syncはUnixオペレーティングシステムの標準システムコールであり、カーネルファイルシステムバッファのすべてのデータ(低レベルI/Oシステムコールによって書き込みがスケジュールされたデータ)を不揮発性ストレージにコミットします。stdioなどの高レベルI/O層は、独自のバッファを保持する場合があります。
C言語の関数として、呼び出しは通常のsync()ように宣言されます。システムコールは、 syncと呼ばれるコマンドラインユーティリティや、 PerlやNode.jsなどの他の言語の同様の名前の関数( fs モジュール内)からも利用できます。 void sync(void)<unistd.h>
関連するシステムコールは、指定されたファイル記述子fsync()に関連するバッファリングされたデータのみをコミットします。[ 1 ]は、ファイル内のデータに加えられた変更のみを書き出すためにも使用できますが、必ずしもファイルの関連メタデータを書き出す必要はありません。[ 2 ]fdatasync()
一部のUnixシステムでは、定期的にsync関数を呼び出す、一種のフラッシュデーモンまたはアップデートデーモンが動作しています。一部のシステムではcronデーモンがこの処理を行い、Linuxではpdflushデーモンが処理していましたが、 pdflushデーモンは新しい実装に置き換えられ、最終的に2012年にLinuxカーネルから削除されました。[ 3 ]ファイルシステムがアンマウントされたり、読み取り専用で再マウントされたりした場合も、バッファはフラッシュされます。 [ 4 ]例えば、システムのシャットダウン前などです。
LibreOfficeなどの一部のアプリケーションでは、同期関数を呼び出して、一定間隔で回復情報を保存します。
データベースの使用
適切な耐久性を提供するために、データベースは、書き込まれた情報が、電源障害時に失われるメモリベースの書き込みキャッシュに格納されるのではなく、不揮発性ストレージに確実に保存されるように、何らかの形式の同期を使用する必要があります。たとえば、 PostgreSQLは、コミットの耐久性を確保するために、や [ 5 ] など、さまざまな同期呼び出しを使用することがあります。[ fsync()6 ]残念ながら、一連のレコードを書き込む単一のクライアントの場合、回転するハードドライブは1回転につき1回しかコミットできず、1秒あたり数百回のコミットしか実行できません。[ 7 ]そのため、fsync要件をオフにするとコミットのパフォーマンスが大幅に向上しますが、クラッシュ後にデータベースが破損する可能性があります。 fdatasync()
データベースでは、最近の変更に関する情報を含むトランザクション ログファイル (通常はメイン データ ファイルよりはるかに小さい) も使用されるため、クラッシュが発生した場合でも変更を確実にやり直すことができ、メイン データ ファイルの同期頻度を減らすことができます。
エラー報告とチェック
データ損失を避けるため、 の戻り値をチェックする必要がある。これは、ライブラリやカーネルによってバッファリングされるI/O操作を実行する際に、データが不揮発性ストレージに書き込まれず、メモリページキャッシュにのみ書き込まれる可能性があるため、システムコールfsync()または 呼び出しの使用時にエラーが報告されない可能性があるためである。代わりに、書き込みエラーは、、または のシステムコール中に報告されることが多い。[ 8 ] 2018年より前は、特定の状況下でのLinuxの動作によりエラー状態が報告されなかった。[ 9 ] [ 10 ]この動作の変更は2018年4月23日に提案された。[ 11 ]write()fflush()fsync()msync()close()fsync()
パフォーマンス論争
ハードディスクは、デフォルトで揮発性書き込みキャッシュを使用して書き込みをバッファリングする場合があります。これによりパフォーマンスは大幅に向上しますが、書き込みが失われる可能性があります。[ 12 ] hdparm -Fなどのツールは、HDDコントローラにドライブ上の書き込みキャッシュバッファをフラッシュするよう指示します。キャッシュをオフにすることによるパフォーマンスへの影響は非常に大きいため、通常は保守的なFreeBSDコミュニティでさえ、FreeBSD 4.3で書き込みキャッシュをデフォルトで無効化することを拒否しました。[ 13 ]
SCSIおよびネイティブ コマンド キューイングを備えたSATA (ただし、TCQ を備えたプレーン ATA ではそうではありません)では、ホストは、データがディスクのプラッタにヒットしたとき、またはディスクのバッファ (オンボード キャッシュ) にヒットしたときに完了通知を受け取るかどうかを指定できます。 ハードウェア実装が正しいと仮定すると、この機能により、 などのシステム コールの正しいセマンティクスを保証しながら、ディスクのオンボード キャッシュを使用できます。[ 14 ]このハードウェア機能はForce Unit Access (FUA) と呼ばれ、ATA (または SATA 非 NCQ) ディスクで行われるようにキャッシュ全体をフラッシュするよりも少ないオーバーヘッドで一貫性を実現します。[ 15 ] Linux は 2007 年頃に NCQ を有効にしましたが、初期のドライブでサポートされていないことを理由に、2012 年まで SATA/NCQ FUA を有効にしませんでした。[ 16 ] [ 17 ]fsync
2008年にリリースされたFirefox 3.0では、fsyncパフォーマンスを低下させることが判明したシステムコールが導入されました。このシステムコールは、組み込みのSQLiteデータベースの整合性を保証するために導入されました。[ 18 ] Linux Foundationの最高技術責任者であるTheodore Ts'oは、「fsyncを恐れる」必要はなく、Firefox 3の速度低下の本当の原因はfsyncの過剰な使用であると主張しています。 [ 19 ]しかし、彼はまた(Mike Shaverの言葉を引用して)次の ように認めていますfsync。
Linuxの一般的な設定、特にext3ファイルシステムを「data=ordered」モードで使用している場合、fsyncを呼び出すと、呼び出されたファイルのデータだけでなく、そのファイルシステムのすべてのバッファリングされたデータがフラッシュされます。[ 20 ]
参照
参考文献
- ^ fsync仕様
- ^ fdatasync仕様
- ^ 「RIP Pdflush [LWN.net]」。
- ^ 「mount - umountは保留中の書き込みを完了するためにsyncを呼び出しますか?」 Unix & Linux Stack Exchange 。2021年5月2日閲覧。
- ^ Vondra, Tomas (2019年2月2日). 「PostgreSQL vs. fsync」 . Osuosl Org . 2019年2月10日時点のオリジナル(mp4)からアーカイブ。 2019年2月10日閲覧。
- ^ PostgreSQLの信頼性と先行書き込みログ
- ^ PostgreSQL WAL同期のチューニング 2009年11月25日アーカイブWayback Machine
- ^ 「データがディスクに確実に到達できるようにする [LWN.net]」。
- ^ 「PostgreSQL の fsync() の驚き [LWN.net]」。
- ^ 「ブロック層のエラー処理の改善 [LWN.net]」。
- ^ 「ライトバックエラーを常に1回報告する - Patchwork」 。 2018年5月4日時点のオリジナルよりアーカイブ。2018年5月3日閲覧。
- ^書き込みキャッシュは有効ですか?
- ^ FreeBSD ハンドブック — ディスクのチューニング
- ^ Marshall Kirk McKusick . 「ファイルシステムの観点から見たディスク - ACM Queue」 . Queue.acm.org . 2014年1月11日閲覧。
- ^グレゴリー・スミス (2010). PostgreSQL 9.0: 高性能. Packt Publishing Ltd. p. 78. ISBN 978-1-84951-031-8。
- ^ 「SATA ドライブの FUA を有効にする (Re: [RFC][PATCH] libata: SATA ディスクの FUA 検出をデフォルトで有効にする) (Linux SCSI)」。
- ^ 「Linux-Kernel アーカイブ: [PATCH RFC] libata: FUA の更新」。
- ^ 「Shaver » fsyncers and curveballs」 2012年12月9日時点のオリジナルよりアーカイブ。2009年10月15日閲覧。
- ^ 「fsync を恐れないでください!」。
- ^ 「遅延割り当てと長さゼロのファイル問題」。