7

write(2)Linux / Unixで、またはで区切られたfdatasync(2)一連のシーケンシャルを発行する場合、fsync(2)またはsync(2)2番目のwrite()の前に最初のwrite()がディスクにコミットされることが保証されていますか?次のSOの投稿では、複数のキャッシングレイヤーが関係しているため、このような保証は提供できないと述べているようです。一貫性を保証するデータベースシステムの場合、これは重要と思われます。WAL(ログ先行書き込み)リカバリでは、実際にデータを変更する前にログをディスクに保持する必要があるため、アプリケーション/システムに障害が発生した場合最後の既知の一貫した状態に戻すことができます。これは実際のデータベースシステムでどのように保証/実装されていますか?

4

2 に答える 2

1

sync()システムコールは実質的に何の助けにもなりません。ディスクへの書き込み操作をスケジュールすることを約束しますが、それだけです。

open()使用される通常の手法は、ディスク ファイルのファイル記述子を使用するときに正しいオプションを設定することです: O_DSYNCO_RSYNCO_SYNC. ただし、fsync()fdatasync()は同じ効果にかなり近づきます。O_DIRECTIOPOSIX ではまったく標準化されていませんが、どれがよくサポートされているかを確認することもできます。

最終的に、DBMS は O/S に依存して、1 つのディスクに書き込まれ同期されたデータが安全であることを保証します。デバイスが常に DBMS が最後に書き込んだものを返す限り、キャッシュのためにまだ実際のディスク上にない場合でも (不揮発性キャッシュなどにバックアップされているため)、重要ではありません。 . 一方、NAS (ネットワーク接続ストレージ) を使用している場合、最後に書き込んだ (そしてディスク上で安全であると伝えられた) 内容が読み取られたときに返されることが保証されていない場合、DBMS がそうしなければならない場合に問題が発生する可能性があります。回復。そのため、DBMS を格納する場所は慎重に選択し、ストレージが適切に機能するようにします。ストレージが仮想ディスクのように十分に機能しない場合、データが失われる可能性があります。

于 2012-05-24T04:35:58.840 に答える
0

はい、fsync最新バージョンのカーネルでは、メモリ (バッファー キャッシュ) をディスクにフラッシュし、ディスク ハードウェア バッファーをプラッターにフラッシュします。マニュアルページによると、古いカーネルは最初のことだけを行っていました。

fsync() は、ファイル記述子 fd によって参照されるファイルのすべての変更されたコア内データ (つまり、変更されたバッファ キャッシュ ページ) をディスク デバイス (または他の永続的なストレージ デバイス) に転送 (「フラッシュ」) します。システムがクラッシュしたり再起動した後でも、変更されたすべての情報を取得できるようにします。 これには、存在する場合、ディスク キャッシュの書き込みまたはフラッシュが含まれます。 デバイスが転送の完了を報告するまで、通話はブロックされます。また、ファイルに関連付けられたメタデータ情報もフラッシュします (stat(2) を参照)。

古いカーネルや使用頻度の低いファイルシステムでの fsync () の実装は、ディスクキャッシュをフラッシュする方法を知りません。 このような場合、安全な操作を保証するために、hdparm(8) または sdparm(8) を使用してディスクキャッシュを無効にする必要があります。

これは、アプリケーションが要求できるものを指します。Fsync は、ファイルシステムがアプリケーションに提供するインターフェイスであり、ファイルシステム自体はその下にある別のものを使用します。ファイルシステムはバリア、または明示的なフラッシュと FUA リクエストを使用してジャーナルをコミットします。LWN の投稿を見てください。

于 2015-10-27T03:56:53.587 に答える