fdatasync() と fsync() の違い

fdatasync() と fsync() について全く知識が無いので、調べ中。

両方とも、データをハードディスクに *物理的に* 格納するためのファンクションのようだ。

fdatasync() は (システム・コールから戻る前に) ファイルの全てのデータ・バッファーを ディスクにフラッシュ (flush) する。これは fsync() に似ているが、アクセス時刻のようなメタデータを更新しない。


データベースにアクセスしたり、ログ・ファイルに書き込むような アプリケーションはしばしば小さなデータの断片 (例えばログ・ファイルの一行) を書き込み、それがハードディスクに物理的に格納されることを保証する ために、すぐに fsync() を呼び出す。不幸なことに、 fsync() は常に二回の書き込み操作を行なう: 一つは新しく書き込まれたデータを、 もう一つは inode の修正時刻を更新するために。修正時刻がトラザンクション に関係なければ、 fdatasync() を使用することで不必要なディスクへの inode の書き込み処理を 避けることができる。

http://www.pinkdragon.net/DocumentsLibrary/contents/ja/Linux_man/fdatasync.2.html

fsync() は、ファイル記述子 fd で参照されるファイルの内部で持っているデータ (つまりバッファキャッシュページ) のうち修正されたデータを、 そのファイルが属するディスクデバイス (またはその他の永続ストレージデバイス) に転送 (「フラッシュ」) する。 この呼び出しは転送が終わったとデバイスが報告するまでブロックする。 またファイルに結びついたメタデータ情報 (stat(2) 参照) もフラッシュする。


fsync() の呼び出しは、ファイルが存在しているディレクトリのエントリがディスクへ 書き込まれたことを保証するわけではない。 保証するためには明示的にそのディレクトリのファイル記述子に対しても fsync() する必要がある。


fdatasync() は fsync() と同様であるが、メタデータの扱いが異なる。 fdatasync() は、それ以降のデータ読み込みを正しく扱うためにそのメタデータが必要に ならない限り、変更されたメタデータをフラッシュしない。 例えば、 st_atime や st_mtime (それぞれ最終アクセス時刻、最終修正時刻; stat(2) 参照) の変更はフラッシュを必要としない。 なぜならこれらはそれ以降のデータ読み込みを正しく扱うために 必要ではないからである。 一方、ファイルサイズ (ftruncate(2) では st_size) の変更はメタデータのフラッシュが必要である。 fdatasync() の狙いは、全てのメタデータをディスクと同期する必要のない アプリケーションに対して、ディスクアクセスを減らすことである。

http://www.linux.or.jp/JM/html/LDP_man-pages/man2/fsync.2.html


なるほど、ファイルの更新するんだけど、メタデータは無視して、データだけ書き込みするから、fdatasync って名前なのね。Linux 2.2 以前では、 fdatasync() は fsync() と等価だったらしい。