web-dev-qa-db-ja.com

Linuxでのファイル編集はディスクに直接保存されますか?

以前は、ファイルの変更は直接ディスクに保存されると思っていました。つまり、ファイルを閉じて[保存]をクリックまたは選択するとすぐです。しかし、最近の会話で、私の友人が私に通常は真実ではないと言っています。 OS(具体的にはLinuxシステムについて話していました)はメモリの変更を保持し、メモリからディスクにコンテンツを実際に書き込むデーモンがあります。

彼は外部フラッシュドライブの例も示しました。これらはシステムにマウントされ(メモリにコピーされます)、デーモンがまだコンテンツをフラッシュメモリに保存していないためにデータが失われることがあります。そのため、フラッシュドライブをアンマウントします。

私はオペレーティングシステムが機能していることを知らないので、これが本当であるかどうか、どのような状況であるかはまったくわかりません。私の主な質問は、これはLinux/Unixシステム(および他のOS)で説明されているように発生しますか?たとえば、ファイルを編集して保存した後、コンピュータの電源をオフにすると即時になると、変更が失われる可能性が高いということですか?多分それはディスクタイプに依存します-従来のハードドライブとソリッドステートディスクのどちらですか?

質問は、明確化や比較が十分に受け入れられていても、情報を格納するためのディスクを備えたファイルシステムに特に言及しています。

58
JuanRocamonde

ファイルを編集して保存した直後にコンピューターの電源を切ると、変更内容が失われる可能性が最も高くなります。

彼らはそうかもしれません。 「可能性が高い」とは言いませんが、可能性は多くの事柄に依存します。


ファイル書き込みのパフォーマンスを向上させる簡単な方法は、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環境で実行してください。)

70
ilkkachu

extremely を証明する簡単な方法がありますできない trueであることは、ファイルの編集が常にディスクに直接保存されること、つまり、そもそもディスクによってバックアップされていないファイルシステムです。ファイルシステムが最初に /ディスクを持たない場合、ディスクに変更を書き込むことはできません[////] / ever

次に例を示します。

  • tmpfs、RAM(より正確には、バッファキャッシュ)にのみ存在するファイルシステム)
  • ramfs、RAMにのみ存在するファイルシステム
  • any network file system(NFS、CIFS/SMB、AFS、AFP、…)
  • any virtual filesystem(sysfsprocfsdevfsshmfs、…)

しかし、ディスクバックアップファイルシステムの場合でも、これは通常は当てはまりません。ページ SQLiteデータベースを破損する方法には、 Failure to sync という章があり、さまざまな方法でどの書き込み(この場合はSQLiteデータベースへのコミット)がディスクに到着しない可能性があります。 SQLiteには、保証するためにジャンプする必要がある多くのフープを説明するホワイトペーパーもあります Atomic Commit In SQLite 。 ( Atomic Write Write よりも問題よりもはるかに難しいことに注意してください。ただし、ディスクへの書き込みは、Atomic書き込みの副問題です。この問題についても、このペーパーから多くのことを学ぶことができます。)このペーパーには、 Things That Go To Go Wrong に関するセクションがあり、 Incomplete Disk Flushes に関するサブセクションでは、書き込みがディスクに到達するのを妨げる可能性のある微妙な複雑さの例をいくつか示します(HDDコントローラーが書き込みを報告したなど)実際にはそうではない場合にディスクに書き込む–はい、これを行うHDDメーカーが存在します。ATAの仕様によれば、この点について曖昧な表現があるため、合法である可能性もあります)。

14
Jörg W Mittag

Unix、Linux、Windowsを含むほとんどのオペレーティングシステムが書き込みキャッシュを使用して操作を高速化していることは事実です。つまり、コンピュータをシャットダウンせずに電源を切るのは悪い考えであり、データの損失につながる可能性があります。取り外す準備ができる前にUSBストレージを取り外す場合も同様です。

ほとんどのシステムには、書き込みを同期させるオプションもあります。つまり、アプリケーションが成功の確認を受け取る前にデータがディスク上に存在することになりますが、速度は低下します。

つまり、コンピュータを適切にシャットダウンし、USBストレージを取り外す準備を適切に行う必要があるのには理由があります。

11
RalfFriedl

1.フラッシュベースのストレージ

それは、ディスクの種類(従来のハードドライブとソリッドステートディスクのどちらか)または他の変数に依存しますか? Linuxでのみ発生しますか(発生した場合)、他のOSでも発生しますか?

選択の余地がある場合は、フラッシュベースのストレージが完全にシャットダウンせずに電源を失うことを許可しないでください。

SDカードのような低コストのストレージでは、消去ブロック全体(数回は4KBを超える)が失われ、さまざまなファイルやファイルシステムの基本的な構造に属する可能性のあるデータが失われることが予想されます。

いくつかの高価なSSDは、電源障害に直面してもより良い保証を提供すると主張するかもしれません。ただし、サードパーティのテストでは、高価なSSDの多くが失敗していることが示されています。 「ウェアレベリング」のためにブロックを再マッピングするレイヤーは複雑で独自仕様です。考えられる障害には、ドライブ上のすべてのデータの損失が含まれます。

テストフレームワークを適用して、合計3千回を超える障害注入サイクルを使用して、6つの異なるベンダーからの17のコモディティSSDをテストします。私たちの実験結果は、テストされた17個のSSDデバイスのうち14個が、ビットの破損、shornの書き込み、シリアル化できない書き込み、メタデータの破損、デバイス全体の障害など、電源障害時に驚くべき障害動作を示すことを示しています。

2017: https://dl.acm.org/citation.cfm?id=2992782&preflayout=flat

2013: https://www.usenix.org/system/files/conference/fast13/fast13-final80.pdf?wptouch_preview_theme=enabled

2.ハードディスクドライブの回転

回転HDDにはさまざまな特性があります。安全性とシンプルさのために、フラッシュベースのストレージと同じ実用的な不確実性があると想定することをお勧めします。

特定の証拠がない限り、それは明らかにありません。 HDDの回転に関する比較データはありません。

HDDは不完全な書き込み済みセクターを1つ残し、チェックサムが不良になる可能性があります。これにより、後で素敵な読み取りエラーが発生します。大まかに言って、このHDDの障害モードは完全に予想されます。ネイティブLinuxファイルシステムは、それを考慮して設計されています。この種の停電障害に直面しても、fsync()の契約を維持することを目指しています。 (私たちは本当にこれがSSDで保証されることを望んでいます)。

しかし、Linuxファイルシステムがすべてのケースでこれを実現するかどうか、またはそれが可能かどうかはわかりません。

このタイプの障害後の次の起動では、ファイルシステムの修復が必要になる場合があります。これはLinuxであるため、ファイルシステムの修復で理解できない質問が表示される可能性があります。Yを押すだけで、問題が解決することを期待できます。

2.1 fsync()コントラクトが何かわからない場合

Fsync()コントラクトは、良いニュースと悪いニュースの両方のソースです。最初に良い知らせを理解しなければなりません。

朗報:fsync()は、ファイルデータを書き込む正しい方法として十分に文書化されています。 「保存」を押したとき。そして、それは広く理解されています。テキストエディターは、rename()を使用して既存のファイルをアトミックに置き換える必要があります。これは、常に古いファイルを保持するか、新しいファイル(名前を変更する前にfsync()されたファイル)を取得することを確認するためのものです。新しいファイルの半分書かれたバージョンを残したくはありません。

悪いニュース:長年にわたり、最も人気のあるLinuxファイルシステムでfsync()を呼び出すと、システム全体が数十秒間ハングしたままになる可能性があります。アプリケーションはこれについて何も実行できないため、fsync()を使用せずに楽観的にrename()を使用することは非常に一般的でしたが、このファイルシステムでは比較的信頼性が高いようです。

したがって、fsync()を正しく使用しないアプリケーションが存在します。

このファイルシステムの次のバージョンでは、一般にfsync()のハングを回避しました。同時に、fsync()の正しい使用に依存し始めました。

これはすべてかなり悪いです。この歴史を理解することは、衝突するカーネル開発者の多くが使っていた否定的な口調や言い争いによっておそらく助けられません。

現在の解決策は、現在最も人気のあるLinuxファイルシステムです。 デフォルトでは、fsync()を必要とせずにrename()パターンをサポートします 以前のバージョンとの「バグとバグの互換性」を実装します。これは、マウントオプションnoauto_da_allocで無効にできます。

これは完全な保護ではありません。基本的に、保留中のIO at rename()時間をフラッシュしますが、IOが完了する前に名前が変更されるまで待機しません。これは、たとえば60秒の危険ウィンドウですが、回答も参照してください 既存のファイルをrename()で置き換えるときにクラッシュを防ぐためにfsync()が必要なファイルシステムはどれですか?

あまり人気のないファイルシステムの中には、保護を提供しないものがあります。 XFS 拒否 そうする。そして [〜#〜] ubifs [〜#〜] もそれを実装していません、明らかに受け入れられるかもしれませんが、それを可能にするために多くの作業が必要です。同じページは、UBIFSには、電力損失など、データの整合性に関する他のいくつかの「TODO」問題があることを指摘しています。 UBIFSは、フラッシュストレージで直接使用されるファイルシステムです。フラッシュストレージに関してUBIFSが言及する困難のいくつかはSSDのバグに関連していると思います。

9
sourcejedi

負荷の軽いシステムでは、カーネルは、新しく書き込まれたファイルデータを、ページキャッシュにwrite()の後、ディスクにフラッシュする前に、おそらく30秒間保持して、削除された場合や、すぐに再び変更されました。

Linuxの_dirty_expire_centisecs_のデフォルトは3000(30秒)で、新しく書き込まれたデータが「期限切れ」になるまでの時間を制御します。 ( https://lwn.net/Articles/322823/ を参照)。

関連する調整パラメータの詳細については https://www.kernel.org/doc/Documentation/sysctl/vm.txt を、その他の詳細についてはgoogleを参照してください。 (例:google on _dirty_writeback_centisecs_)。

Linuxの_/proc/sys/vm/dirty_writeback_centisecs_のデフォルトは500(5秒)です。PowerTopでは、消費電力を削減するために1500(15秒)に設定することをお勧めしています。


ライトバックの遅延は、ディスクへの書き込みを開始する前に、カーネルがファイルのサイズを確認する時間も与えます。割り当てが遅延しているファイルシステム(XFSなど、最近ではおそらく他のもの)は、iノード自体にスペースを割り当てることとは別に、必要になるまで、新しく書き込まれたファイルのデータを配置するディスク上の場所を選択することすらありません。これにより、たとえば、大きなファイルの先頭を他のファイル間の1 MBのギャップに入れることを回避できるため、断片化が軽減されます。

大量のデータが書き込まれている場合、ダーティ(まだディスクに同期されていない)データがページキャッシュにどれだけ存在できるかについてのしきい値によって、ディスクへの書き戻しがトリガーされます。

ただし、他に多くのことをしていない場合、ハードドライブのアクティビティライトは、小さなファイルで[保存]を押してから5秒間(または15秒間)点灯しません。


エディターがファイルの書き込み後にfsync()を使用した場合、カーネルはそれを遅延なくディスクに書き込みます。 (そして、fsyncは、データが実際にディスクに送信されるまで戻りません)。


ディスク内の書き込みキャッシュも可能ですが、Linuxのページキャッシュアルゴリズムとは異なり、ディスクは通常、書き込みキャッシュを永続ストレージにできるだけ早くコミットしようとします。ディスク書き込みキャッシュは、書き込みの小さなバーストを吸収するためのストアバッファーですが、読み取りを優先して書き込みを遅らせ、ディスクファームウェアにシークパターンを最適化する余地を与えることもできます(たとえば、1つではなく2つの近くの書き込みまたは読み取りを行う) 、それから遠くを探し、それから後ろを探します。)

回転する(磁気)ディスクでは、書き込みの前に保留中の読み取り/書き込みがあった場合、SATA書き込みコマンドからのデータが電源オフから実際に安全になるまでに、それぞれ7〜10 msのシーク遅延がいくつか発生することがあります。 (この質問に関する他のいくつかの回答では、ジャーナル化されたFSが破損を回避するために使用できるディスク書き込みキャッシュと書き込みバリアについて詳しく説明しています。)

5
Peter Cordes