2012-09-04 12 views
6

上書きしたい領域がファイル(可能な場合)にあります。 私はfseek、fwrite、fsyncを呼び出すと仮定します。このような領域書き換え操作の原子性を保証する方法はありますか?私は確信が必要です。失敗した場合は、古い(修正前の)データか、新しい(変更された)データのみが含まれますが、これは混在しません。アトミックファイルの変更

ハイライトしたいことが2つあります。

まず:アトミック任意のサイズの領域に書き込みをする方法がない場合、それは大丈夫です - 私たちは、ファイルにデータを追加fsync'ing、その後、書き換えファイルの「ポインタ」エリア、再びfsyncingことによってそれを処理することができます。しかし、 'ポインタ'の書き込みがアトミックでない場合でも、不正なポインタでファイルが破損する可能性があります。

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

私はロングのための原子書記を持っているなら、これはもっと簡単だろうが、本当にそれを持っていますか?

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

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

この質問は、LinuxやWindowsオペレーティングシステムに適用され、任意の特定の回答(たとえば、ubuntuバージョンa.b.c ....など)も必要です。

+0

は[FSYNC](http://linux.die.net/man/3/fsync)かなり実装/ファイルシステムに依存すると思われます。 http://blogs.gnome.org/alexl/2009/03/16/ext4-vs-fsync-my-take/ – zapl

+0

あなたが話していることは、「コミットメント制御」または「コミット/ロールバック」と呼ばれています。または "トランザクション"。 –

+0

(ボックスにいくつかのトランザクション処理機能がなければ、欲しいことを行うための唯一の(ほとんど)完全に信頼できる方法です。古いファイルの交換を行います。古いファイルを新しいファイルにコピーし、新しいファイルを置き換え、古いファイルを新しいファイルに置き換えます。 –

答えて

1

通常、512バイトチャンクの書き込みは、HDDによる1回の書き込みで行われると仮定するのが安全です。 しかし、私はそれを仮定しません。代わりに、私はあなたの書き込みにチェックサムを追加し、ファイル内のポインタを変更する前にそれを確認しながら、2番目のソリューションと一緒に行くだろう。

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

"同期"保証については、それを仮定することができます。 syncはFSとディスクに依存しますが、私たちは '合理的な'実装について話しています。

  • 第一sync後のデータがディスクにフラッシュされることが保証(ディスクは、それはそれで はまだキャッシュだかもしれない)、データはあなたがあなたが書いたものは何でも得ることが期待されている場合です。
  • 両方の同期のデータがディスクキャッシュにある場合は、説明した状況が発生する可能性がありますが、IMHOその可能性は非常に低くなります。

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

いくつかの詳細情報:Ensure fsync did its job

+0

お返事ありがとうございます。 「同期」保証について、私はあなたにこの仮定の「証明」を提供できますか?または、それはいくつか(何?)ソースコードの追跡/専門家から来ていますか? – andll

+0

いくつかの情報で答えを補強しました。 – Drakosha

関連する問題