現在、高速のNVMeデバイスを使用して、Debianでかなり大きな回転ディスクベースのソフトウェアRAID(mdadm)アレイへの書き込み速度を向上させるさまざまな方法を実験しています。
I found そのようなデバイスのペア(raid1、ミラーリング)を使用してファイルシステムのジャーナルを保存すると、興味深いパフォーマンス上の利点が得られます。これを実現するために使用しているマウントオプションはnoatime,journal_aync_commit,data=journal
です。
私のテストでは、barrier=0
オプションを追加すると、書き込みパフォーマンスの点で大きなメリットがあることも発見しました。ただし、このオプションが特定のファイルシステム構成で安全に使用できるかどうかはわかりません。これがカーネル ドキュメント がext4書き込みバリアについて述べていることです:
書き込みバリアは、ディスク上のジャーナルコミットの適切な順序を強制し、揮発性のディスク書き込みキャッシュを安全に使用できるようにしますが、パフォーマンスが低下します。ディスクが何らかの方法でバッテリバックアップされている場合、バリアを無効にするとパフォーマンスが安全に向上する可能性があります。
私が使用している特定のNVMeデバイスは Intel DC P37 で、停電保護機能が組み込まれています。これは、予期しないシャットダウンが発生した場合に、一時バッファにまだ存在するデータは、予備のエネルギーストレージのおかげで安全にNANDストレージにコミットされます。
だから私の質問は、ジャーナルがバッテリーバックアップ式のキャッシュを備えたデバイスに保存されていて、残りのファイルシステム自体がこの機能を持たないディスク上にある場合、ext4書き込みバリアを安全に無効にできるでしょうか?
さらに分析した結果、 以前の回答 が正しいとは思わないため、新しい回答を書いています。
write_dirty_buffers
関数を見ると、REQ_SYNC
フラグを使用して書き込み要求が発行されますが、キャッシュのフラッシュやバリアは発行されません。これは、blkdev_issue_flush
call によって実現されます。これは、JDB2_BARRIER
フラグの検証によって適切にゲートされます。フラグ自体は ファイルシステムがバリアが有効 。
したがって、checkpoint.c
を振り返ると、トランザクションがジャーナルから削除されたときにのみ、バリアが重要になります。コード内の comments は、ここでは参考情報であり、この書き込みバリアが必要になる可能性はほとんどないが、いずれにしても安全策として存在することを示しています。ここでの仮定は、トランザクションがジャーナルから削除されるまでに、データ自体がドライブのキャッシュに残っている可能性は低く、永続的なストレージにまだコミットされていないことです。しかし、これは単なる仮定であるため、書き込みバリアはとにかく発行されます。
では、なぜメインファイルシステムにデータを書き込むときにバリアが使用されないのでしょうか。ここで重要なのは、ジャーナルが首尾一貫している限り、ファイルシステムから欠落しているメタデータ(たとえば、停電イベントで失われたため)は通常 ジャーナルの再生中に回復 、したがって、ファイルシステムの破損を回避できます。さらに、data=journal
を使用すると、実際のファイルシステムデータの整合性も保証されます。これは、私が理解しているように、リカバリプロセスは、再生メカニズムの一部としてジャーナルにコミットされたデータブロックも書き出すためです。
したがって、ext4は実際にはチェックポイントの最後にディスクキャッシュをフラッシュしませんが、停電の場合に回復性を最大化するためにいくつかの手順を実行する必要があります。
ファイルシステムはdata=journal
ではなくdata=writeback
でマウントする必要があります(外部ジャーナルを使用している場合はdata=ordered
は使用できません)。これは明白なはずです。停電イベントで失われる可能性があるので、ジャーナル内のすべての着信データブロックのコピーが必要です。 NVMeデバイスは非常に高速であるため、これはパフォーマンスの点で高価ではありません。
ジャーナルの再生で回復可能なデータの量を最大化するには、最大ジャーナルサイズ102400ブロック(4Kファイルシステムブロックを使用する場合は400MB)を使用する必要があります。すべてのNVMeデバイスのサイズは常に少なくとも数ギガバイトであるため、これは問題になりません。
書き込み集中型の操作中に予期しないシャットダウンが発生した場合でも、問題が発生する可能性があります。データドライブが自分でキャッシュをフラッシュできるよりも速くトランザクションがジャーナルデバイスから削除されると、回復不可能なデータの損失やファイルシステムの破損が発生する可能性があります。
つまり、私の見解では、この設定を少し安全にするためにいくつかの予防策(#1と#2)を実装することはできますが、私の考えでは、最終的には書き込みバリアを無効にするのは100%安全ではありません。
あなたの質問を置く別の方法はこれです:チェックポイントを実行するとき、つまり、ジャーナルのデータを実際のファイルシステムに書き込むとき、トランザクションを完了とマークする前に、ext4が(回転ディスクの)キャッシュをフラッシュします。それに応じてジャーナルを更新しますか?
checkpoint.c でjbd2(ジャーナリングの処理を担当する)のソースコードを見ると、 end でjbd2_log_do_checkpoint()
が呼び出されていることがわかります。 :
__flush_batch(journal, &batch_count);
どの calls :
write_dirty_buffer(journal->j_chkpt_bhs[i], REQ_SYNC);
だから、それは安全なはずです。
関連: 過去 ジャーナルチェックポイントでWRITE_SYNCを使用するパッチも提案されました:理由は、バッファの書き込みの優先度が低すぎて、書き込みが完了するのを待つ間にジャーナルがいっぱいになったためです
書き込みバリアを無効にするとパフォーマンスが大幅に向上する場合は、書き込みバリアを無効にしてはならず、データが危険にさらされていることを意味します。 XFSのこの部分を参照FAQ