私はかなり重要なデータを処理するためにいくつかのソフトウェアを書いています、そして耐久性を達成するために私が何をする必要があるかを正確に知る必要があります。
どこを見ても矛盾する情報があるので、洞察をいただければ幸いです。
ディスクに書き込む方法は3つあります。
O_DIRECTの使用| O_DSYNC、および512バイトをプリアドしてからpwriteする-16MBブロック。
O_DIRECTを使用して、512バイトブロックをプリアドしてからpwriteし、必要に応じて定期的にfdatasyncを呼び出します。
必要に応じて定期的にmsync(...、MS_SYNC | MS_INVALIDATE)と呼ぶメモリマップトファイルを使用します。
そして、これはすべてデフォルトフラグ付きのext4にあります。
これらすべてについて、停電、パニック、クラッシュなどによってデータが失われたり(書き込みまたは同期が戻った後)、破損したりする可能性はありますか?
サーバーがpwriteの途中で、またはpwriteの開始とfdatasyncの終了の間に、またはマップされたメモリが変更されてmsyncの間に停止した場合、古いデータと新しいデータが混在する可能性がありますか、それとも1つになりますか?または他?個々のpwrite呼び出しをアトミックで順序付けてほしい。これは本当ですか?そして、それらが複数のファイルにまたがっている場合はそうですか?したがって、O_DIRECTで書き込む場合| O_DSYNCをAに、次にO_DIRECT | O_DSYNCからBへ、何が起こっても、データがBにある場合、それはAにもあることが保証されますか?
fsyncは、データが書き込まれることを保証しますか?そうではありませんが、それ以来状況が変わったかどうかはわかりません。
ext4のジャーナル化は、このSOの回答が存在すると言っている破損したブロックの問題を完全に解決しますか?
私は現在、posix_fallocateを呼び出してからftruncateを呼び出してファイルを増やしています。これらは両方とも必要ですか、それで十分ですか?これらの問題を回避するために、ftruncateが実際に割り当てられたブロックを初期化すると考えました。
ミックスに混乱を加えるために、私はこれをEC2で実行していますが、それが何かに影響するかどうかはわかりません。どれだけ積極的にシャットダウンするかを制御できないため、テストは非常に困難ですが。