7

ファイルに上書きしたい領域(小さい可能性があります)があります。fseek、fwrite、fsync を呼び出すとします。このような領域書き換え操作の原子性を確保する方法はありますか?これを混ぜます。

強調したいことが2つあります。

最初: 任意のサイズの領域をアトミックに書き込む方法がなくても問題ありません。ファイルにデータを追加し、fsync を実行し、ファイル内の「ポインタ」領域を書き換えてから、再度 fsync を実行することで処理できます。ただし、「ポインタ」の書き込みがアトミックでない場合でも、不正なポインタでファイルが破損する可能性があります。

2番目:1バイト領域の書き込みはアトミックであると確信しています。ファイルに入れたことのないバイトはファイルに表示されません。したがって、アドレスに 2 つの領域を割り当て、1 バイトのスイッチを使用するいくつかのトリックを使用できます。したがって、領域の書き換えは、新しいデータを追加し、同期し、2 つの (未使用の) ポインター スロットの 1 つを書き換え、再度同期し、次に 'switch バイトを書き換えます。 ' そして再び同期します。そのため、領域の上書き操作には、少なくとも 3 つの fsync 呼び出しが含まれるようになりました。

長い間アトミックな書き込みがあれば、これはすべてはるかに簡単になりますが、本当にそれを持っていますか?

ポイント2で述べた方法を使用せずにこの状況を処理する方法はありますか?

もう 1 つの質問は、書き込みと同期の間に順序の保証はありますか? たとえば、fseek、fwrite [1]、fseek、fwrite [2]、fsync を呼び出した場合、[2] での書き込みをコミットし、[1] での書き込みをコミットしないようにすることはできますか?

この質問は、Linux および Windows オペレーティング システムに適用されます。特定の回答 (例: ubuntu バージョン abc ....) も必要です。

4

1 に答える 1

1

通常、512バイトのチャンクの書き込みはHDDによる1回の書き込みで行われると想定するのが安全です。しかし、私はそれを想定していません。代わりに、ファイル内のポインターを変更する前に、書き込みにチェックサムを追加して検証しながら、2番目のソリューションを使用します。

一般に、ディスクに書き込まれるすべてのものにチェックサムを追加することをお勧めします。

「同期」保証について答えるために-あなたはそれを仮定することができます。同期はFSとディスクに依存しますが、「合理的な」実装について話しているとしましょう。

  • 1回目以降sync、データはディスクにフラッシュされることが保証され(ディスクにはまだキャッシュにある可能性があります)、データが書き込まれたものを取得することが期待されます。
  • 1秒後syncに両方の同期のデータがディスクキャッシュにある場合、説明した状況が発生する可能性がありますが、私見ではその可能性は非常に低いです。

とにかく、データがディスク上にあることを約束する他のメカニズムはありません。そのため、チェックサムが必要です。

さらに詳しい情報:fsyncがその役割を果たしたことを確認してください

于 2012-09-04T17:52:35.253 に答える