web-dev-qa-db-ja.com

既存のファイルをrename()で置き換えるときにクラッシュセーフのためにfsync()が必要なファイルシステムはどれですか?

広範な苦情を受けて、ext4はデフォルトで有効になっているauto_da_allocと呼ばれるクラッシュ安全性の保証を得ました。他のファイルシステムはどうですか?最もよく知られたファイルシステムのうち、どれがこれと同じ保証を提供しますか(どれが提供しないか)?

個人的に私はについての情報を聞くことに興味があります

  • XFS-Red Hat Enterprise Linuxのデフォルトのファイルシステム。
  • btrfs-SuSE Enterpriseのデフォルトのファイルシステム。
  • bcachefs -bcacheから派生したツリー外のLinuxファイルシステム。 「データを消費しないLinux用のCOWファイルシステム。」

以下の履歴のように、この問題は主にLinuxに関係しています。 ZFSがどのように動作するかを知ることは興味深いことですが、これはこれを実装しないと思いがちです。

auto_da_allocとは何ですか?

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

しかし、最も人気のあるLinuxファイルシステムであるext3でfsync()を呼び出すと、システム全体が実質的に数十秒間ハングしたままになるという問題がありました。アプリケーションはこれについて何も実行できないため、fsync()を使用せずに楽観的にrename()を使用するのが一般的でした。システムが電源を失っても、そのパターンはこのファイルシステムでうまく機能するように見えました。

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

ファイルシステムの次のバージョンであるext4は、一般にfsync()のハングを回避しました。同時に、fsync()の正しい使用にさらに依存するようになりました。

これはすべてかなり悪いです。この歴史を理解することは、矛盾するカーネル開発者の多くが使用する否定的なフレーズによっておそらく助けられないでしょう。

これはext4で解決され、 クラッシュセーフのためにfsync()を必要とせずにrename()パターンをサポート 古いext3ファイルシステムと同様に、クラッシュ時の動作を提供します。オプションnoauto_da_allocでマウントすると、この動作を再び無効にできます。

4
sourcejedi

この質問には間違いがあります。質問は、このシナリオがauto_da_allocによって完全にクラッシュしても安全であることを示唆しています。これはext4には当てはまりません。古いext3でもそうではなかったと思います。ただし、isは、btrfsおよびbcachefsの場合はtrueです。

最近のext4には、rename時に新しいデータブロックを強制的に出力することにより、replace-via- renameが長さゼロのファイルを生成する可能性を減らす特別な回避策があります。ただし、名前の変更は、このフラッシュが完了するまで待機しないため、原子性の保証はありません。クラッシュ後、新しいコンテンツの一部のみが残る可能性があります。テストしたファイルシステムのうち、btrfsは、replace-via-renameのアトミック性を保証する唯一のファイルシステムです。

https://homes.cs.washington.edu/~lijl/papers/ferrite-asplos16.pdf


btrfsの-​​ documentation は、rename()を使用してファイルを置き換えると完全なアトミック性が提供されることを示し、クラッシュからデータを保護するために明示的なfsync()を必要としません。これは追加されたと思います ext4とほぼ同時期auto_da_alloc 。また、btrfsの実装は、rename()呼び出しを待機させないため、パフォーマンスの低下を回避するという主張も見ています。ただし、最近のカーネルでは、少なくともfsync()を使用した場合、次のrename()は親ディレクトリを fsync()して、「ログツリー」全体が書き込まれるのを待ちます です。

bcachefsは現在、完全なレベルの保護を提供しているようですが、ドキュメントは見つかりませんでした。コードを確認してください。 "filemap_write_and_wait_range"関数の呼び出しが表示されます

XFSには rejected rename()のクラッシュセーフ回避策が追加されています。別のケースでのデータ損失のリスクを軽減する(ただし削除しない)コードを獲得したようです。

UBIFS(たとえば、多くのOpenwrtデバイスで使用されます)には、rename()のクラッシュセーフな回避策は含まれていません。受け入れられますが、多くの作業が必要になります。 http://www.linux-mtd.infradead.org/doc/ubifs.html#L_sync_exceptions

5
sourcejedi