2025/08/24 15:40 SQLite (with WAL) doesn't do `fsync` on each commit under default settings

やあ、ロボ子。今日はSQLiteのWALモードについて話すのじゃ。

WALモード、ですか。確かWrite-Ahead Loggingの略でしたよね。どのような話題でしょうか?

そうじゃ、その通り!WALモードでは、デフォルト設定だと各コミット時に`fsync`が実行されないらしいのじゃ。

`fsync`ですか。ファイルシステムを物理的に同期させるためのシステムコールですね。それが実行されないと、どうなるのでしょう?

`synchronous` PRAGMAという設定項目で`fsync`の呼び出し方を設定できるのじゃ。デフォルトは`NORMAL`になっているのじゃ。

`synchronous` PRAGMAですか。`NORMAL`だと、具体的にどういう動作になるんですか?

`synchronous=NORMAL`の場合、WALモードでは、電源喪失やシステムクラッシュ時にコミットされたトランザクションがロールバックする可能性があるのじゃ。

それは困りますね。データが失われてしまう可能性があるということですか。

そういうことじゃ。WALファイルは各チェックポイントの前に同期され、データベースファイルは完了したチェックポイントの後に同期されるのじゃ。

なるほど。チェックポイントのタイミングで同期されるんですね。でも、耐久性がそれほど重要でない場合は、`synchronous=NORMAL`でも十分とのことですが。

そうじゃな。例えば、一時的なキャッシュデータとか、失われても再構築できるようなデータなら問題ないのじゃ。

各コミット時に`fsync`を呼び出すには、どうすれば良いのでしょうか?

`synchronous=FULL`を使うのじゃ!

`synchronous=FULL`ですか。WALモードでは、具体的にどのような動作になるんですか?

`synchronous=FULL`のWALモードでは、各トランザクションコミット後に追加のWALファイルの同期が行われ、電源喪失時にもトランザクションの耐久性が確保されるのじゃ。

それは安心ですね。でも、パフォーマンスには影響がありそうですね。

その通り!`FULL`にすると、書き込み速度は遅くなるのじゃ。だから、データの重要度とパフォーマンスのバランスを考えて設定する必要があるのじゃ。

なるほど。状況に応じて使い分けるのが大切ですね。勉強になりました!

ところでロボ子、WALモードって、まるで忍者の隠れ身の術みたいじゃな。データが消えても、なかったことに…って、違うか!
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。