2

ジャーナリング/ログ先行書き込みストレージシステムを構築しているとしましょう。(トランザクションごとに)データを追加し(write(2)を使用)、コミットマーカーを追加してから、fsyncすることで、これを簡単に実装できますか?

考慮すべきシナリオは、このログに大量の書き込みを行ってからfsyncを実行し、fsync中に障害が発生した場合です。iノードの直接/間接ブロックポインタは、すべてのデータブロックがフラッシュされた後にのみフラッシュされますか、それともブロックが順番にフラッシュされるという保証はありませんか?後者の場合、リカバリ中にファイルの最後にコミットマーカーが表示されていると、そのファイルと前のコミットマーカーの間のデータに意味があるとは信じられません。したがって、ログファイルのどの範囲が一貫しているかを判断するには、別のメカニズム(少なくとも別のfsyncを含む)に依存する必要があります(たとえば、データの書き込み/ fsync、次にコミットマーカーの書き込み/ fsync)。

それが違いを生むなら、主にコンテキストとしてext3/ext4について疑問に思います。

4

2 に答える 2

4

Linuxとmacosのfsyncとfdatasyncはデフォルトでは正しくないことに注意してください。Windowsはデフォルトで正しいですが、ベンチマークの目的でLinuxをエミュレートできます。

また、fdatasyncは、ファイルのiノードを新しい長さで更新する必要があるため、ファイルの末尾に追加すると、複数のディスク書き込みを発行します。コミットごとに1回の書き込みが必要な場合は、ログスペースを事前に割り当て、ログエントリのCRCをコミットマーカーに格納し、コミット時に1つのfdatasync()を発行するのが最善の策です。そうすれば、OS /ハードウェアがどれだけ後ろから並べ替えても、実際にディスクにヒットしたログのプレフィックスを見つけることができます。

ログを永続的なコミットまたは先行書き込みに使用する場合は、fsyncが実際に機能することを確認する必要があるため、事態はさらに困難になります。Linuxでは、hdparmを使用してディスク書き込みキャッシュを無効にするか、バリアをtrueに設定してパーティションをマウントする必要があります。[編集:私は正しい立場に立っていますが、バリアは正しいセマンティクスを提供していないようです。SATAとSCSIは、書き込みバリアやネイティブコマンドキューなどの多くのプリミティブを導入しており、オペレーティングシステムが先行書き込みロギングを可能にするプリミティブをエクスポートできるようにします。マンページとオンラインからわかることから、Linuxはこれらをファイルシステム開発者にのみ公開し、ユーザースペースには公開しません。]

逆説的ですが、ディスク書き込みキャッシュを無効にすると、ユーザースペースでの書き込みスケジューリングをより細かく制御できるため、パフォーマンスが向上する場合があります。ディスクが一連の同期書き込み要求をキューに入れると、アプリケーションに奇妙な遅延スパイクが発生することになります。書き込みキャッシュを無効にすると、これが発生しなくなります。

最後に、実際のシステムはグループコミットを使用し、同時ワークロードでコミットごとに1未満の同期書き込みを実行します。

于 2010-09-26T23:33:18.010 に答える
1

ブロックがディスクにフラッシュされる順序は保証されません。最近では、ドライブ自体でさえ、プラッターに向かう途中でブロックを並べ替えることができます。

順序付けを強制する場合は、少なくとも順序付けfdatasync()する書き込みの間に行う必要があります。同期が約束するのは、それが戻ったときに、同期の前に書き込まれたすべてのものがストレージにヒットすることです。

于 2010-09-26T23:12:07.177 に答える