ファイルを編集して保存した直後にコンピュータの電源を切ると、変更内容が失われる可能性が高くなりますか?
そうかもしれません。 「最も可能性が高い」とは言いませんが、可能性は多くのことに依存します。
ファイル書き込みのパフォーマンスを向上させる簡単な方法は、OS がデータをキャッシュし、書き込みが行われたことをアプリケーションに伝え (嘘をつき)、後で実際に書き込みを行うことです。これは、他のディスク アクティビティが同時に進行している場合に特に便利です。OS は読み取りを優先し、後で書き込みを行うことができます。また、一時ファイルが後ですぐに削除される場合など、実際の書き込みの必要性を完全になくすこともできます。
ストレージが遅い場合、キャッシュの問題はより顕著になります。高速な SSD から低速の USB スティックにファイルをコピーすると、USB スティックが追いつかないため、おそらく多くの書き込みキャッシュが必要になります。しかし、あなたの cp
コマンドがより速く返されるため、作業を続行でき、コピーしたばかりのファイルを編集することさえできます。
もちろん、そのようなキャッシュには、実際に保存される前に一部のデータが失われる可能性があることに注意してください。編集者が書き込みは成功したが、ファイルが実際にはディスク上にないと言った場合、ユーザーは不満を抱くでしょう。 fsync()
があるのはそのためです。 このシステム コールは、ファイルが実際にディスクにヒットした後にのみ返されるはずです。編集者はそれを使用して、書き込みが成功したことをユーザーに報告する前に、データに問題がないことを確認できます。
ドライブ自体がOSに同じ嘘をつき、書き込みが完了したと言う可能性があるため、「はずです」と言いましたが、ファイルは実際にはドライブ内の揮発性の書き込みキャッシュにしか存在しません。ドライブによっては、それを回避する方法がない場合があります。
fsync()
に加えて 、 sync()
もあります と syncfs()
システム全体のすべての書き込みまたは特定のファイルシステムへのすべての書き込みがディスクにヒットしたことを確認するようシステムに要求するシステムコール。ユーティリティ sync
それらを呼び出すために使用できます。
それから O_DIRECT
もあります open()
にフラグを立てる 、これは「このファイルとの間の I/O のキャッシュ効果を最小限に抑えようとする」ことになっています。キャッシングを削除するとパフォーマンスが低下するため、独自のキャッシングを行い、それを制御したいアプリケーション (データベース) で主に使用されます。(O_DIRECT
には問題がないわけではありませんが、man ページのそれに関するコメントはやや面白いものです。)
停電時に何が起こるかは、ファイルシステムにも依存します。心配する必要があるのはファイル データだけではなく、ファイル システムのメタデータです。ディスク上にファイル データがあっても、それが見つからない場合はあまり役に立ちません。ファイルをより大きなサイズに拡張するだけで、新しいデータ ブロックを割り当てる必要があり、それらをどこかにマークする必要があります。
ファイルシステムがメタデータの変更を処理する方法と、メタデータとデータの書き込みの順序は大きく異なります。例:ext4
の場合 、マウントフラグ data=journal
を設定した場合 の場合、すべての書き込み (データ書き込みも含む) はジャーナルを通過するため、かなり安全です。これはまた、それらが 2 回書き込まれることを意味するため、パフォーマンスが低下します。デフォルトのオプションでは、メタデータが更新される前にデータがディスク上にあるように、書き込みを順序付けようとします。他のオプションまたは他のファイルシステムは、より良い場合も悪い場合もあります。総合的な研究を試みることさえしません。
実際には、負荷の軽いシステムでは、ファイルは数秒以内にディスクにヒットするはずです。リムーバブル ストレージを扱っている場合は、メディアを取り出す前にファイル システムをアンマウントして、データが実際にドライブに送信され、それ以上のアクティビティがないことを確認してください。 (または、GUI 環境にそれを実行させます。)
非常に できないことを証明する簡単な方法 ファイルの編集内容は常に直接ディスクに保存されます。つまり、そもそもディスクにバックアップされていないファイル システムがあるという事実です。 .ファイルシステムに ない場合 そもそもディスク、それならあり得ない 常に、変更をディスクに書き込みます .
いくつかの例:
tmpfs
、RAM(より正確にはバッファキャッシュ)にのみ存在するファイルシステムramfs
、RAM にのみ存在するファイル システム- すべて ネットワーク ファイル システム (NFS、CIFS/SMB、AFS、AFP など)
- すべて 仮想ファイルシステム (
sysfs
、procfs
、devfs
、shmfs
、…)
しかし、ディスクでバックアップされたファイル システムの場合でも、これは通常正しくありません。ページ SQLite データベースを破損する方法 同期の失敗という章があります これは、書き込み (この場合は SQLite データベースへのコミット) がディスクに到達しない可能性があるさまざまな方法を説明しています。 SQLite には、SQLite でのアトミック コミットを保証するためにジャンプしなければならない多くの手順を説明するホワイト ペーパーもあります。 . (Atomic Write に注意してください 書くよりもはるかに難しい問題です ですが、もちろん、ディスクへの書き込みはアトミック書き込みの下位問題であり、この問題についてもこの論文から多くのことを学ぶことができます)。 これには、不完全なディスク フラッシュに関するサブセクションが含まれています これは、書き込みがディスクに到達するのを妨げる可能性のある微妙な複雑さの例をいくつか示しています (実際にはディスクに書き込まれていないのに、HDD コントローラーがディスクに書き込んだと報告するなど)。はい、これを行う HDD メーカーがあり、この点に関してあいまいな言葉遣いがされているため、ATA 仕様によれば合法でさえあります)。
Unix、Linux、および Windows を含むほとんどのオペレーティング システムが書き込みキャッシュを使用して操作を高速化することは事実です。つまり、コンピュータをシャットダウンせずに電源を切るのはよくない考えであり、データの損失につながる可能性があります。 USB ストレージを取り外す前に取り外した場合も同様です。
ほとんどのシステムには、書き込みを同期させるオプションも用意されています。これは、アプリケーションが成功の確認を受け取る前にデータがディスク上に存在することを意味しますが、遅くなります。
つまり、コンピューターを適切にシャットダウンし、USB ストレージを取り外す準備を適切に行う必要があるのには理由があります。