SQLite WAL(先行書き込みログ)モードの読み書き並行性とチェックポイント制御
SQLiteのWALモードが読み取りと書き込みの動作をどう変えるか、チェックポイントがWALの内容をデータベースファイルへ反映する仕組みを説明します。WALでも同時に書き込めるのは1つであり、古い読み取りスナップショットやロックがチェックポイントの進行を制限することがあります。
発行・訂正窓口:infostoa · 編集基準
この記事の個別の執筆者・専門査読者の情報は提供されていません。
SQLiteのロールバックジャーナルでは、書き込み時に変更前のページをジャーナルへ記録してからデータベースファイルを更新します。WALは変更を別ログに記録し、読み取りスナップショットの仕組みを変えます。ただしWALでも同時に書き込めるトランザクションは一つで、ロックやチェックポイント、長時間の読み取りによる制約があります。読み書きが常に互いを妨げないとは言えません。
2. WAL(Write-Ahead Log)モードの追記構造と共有メモリ(-shm)の役割
WALモードでは変更ページを別のWALファイルへ追記し、読み取りトランザクションはスナップショットに基づいてデータベースページと必要なWALフレームを読みます。ロールバックジャーナルとは読み書きの相互作用が異なりますが、同時に複数の書き込みを許すわけではありません。SQLite文書はWALでもSQLITE_BUSYが発生する場合を説明しており、常に非ブロッキングで性能が上がるとは言えません。
WALインデックスは共有メモリに置かれます。そのためWALデータベースを使うプロセスは同一ホスト上で動作する必要があります。データベースとWALをネットワークファイルシステムに置き、複数ホストから共有する構成はSQLiteのWAL対応範囲外です。導入前にファイル配置とプロセス境界を確認し、複数サーバーから同時アクセスする必要があればクライアント・サーバー型の構成を検討します。
3. チェックポイントの進行とWALサイズ
チェックポイントは有効なWALフレームをデータベースファイルへ反映します。SQLiteの既定動作では、コミット後にWALが約1,000ページへ達すると自動チェックポイントを開始しますが、これは開始条件であり、サイズ上限やファイル縮小の保証ではありません。各読み取りトランザクションは開始時に、WAL内の最後の有効なコミット位置であるend markを記録します。チェックポイントは、実行中の読者のend markを越えたWALページに達するとそこで停止します。「end markより前のフレームは上書きできない」と逆に説明しないでください。進行位置が記録され、後の実行で続けられます。重なる読み取りにより完了する時間がなければ、WALが増え続けることがあります。
既定の自動チェックポイントはPASSIVEで、他の接続の読み取りや書き込みを待たず、可能な範囲だけ処理することがあります。sqlite3_wal_checkpoint_v2()のモードを分けて確認しましょう。FULLは既存の読者が最新スナップショットを読むまで待ち、新しい書き込みを止めますが、新しい読み取りは続けられます。RESTARTはさらに、次の書き込みがWALを先頭から再利用できるよう、既存の読者がWALを使い終えるまで待ちます。TRUNCATEはRESTARTと同様に進め、成功直前にWALファイルを0バイトに切り詰めます。このAPIの説明では、FULL・RESTARTが読者をブロックするという意味ではありません。一方、WAL概要§6はRESTART/TRUNCATE中に読者がブロックされる可能性を広く記しているため、モード全体へ拡張せず、API・版・呼び出し経路を確認してください。閾値との比較だけでなく、同じ時間帯の読み取りトランザクション時間とログ/チェックポイントのフレーム数を観察します。
4. 複製ツールによってチェックポイントの担当が変わる
Fly.ioが紹介するLitestreamの構成では、複製側が読み取りトランザクションを開いてSQLiteの自動チェックポイントを止め、WALの変更を取得・複製した後、チェックポイントも自ら実行します。これは同ツールの実装例であり、すべての複製ソフトが同じ方式を取るわけではありません。チェックポイントが進まない、またはWALが増え続ける場合は、利用する版の資料と試験で、複製側が読み取りトランザクションとチェックポイントをどう調整するか、遅延や復元がどう動くかを確認します。この例は無損失やリアルタイム複製の保証ではありません。
定期観測では、WALサイズの変化とチェックポイントの進行状況を同じ時間軸で記録すると、読者による停滞を切り分けやすくなります。
同時書き込み・チェックポイントの導入前確認
2026-10-12に確認したSQLite WAL §11は、WALリセット競合によりデータベースが破損し得る非常にまれな不具合を説明しています。条件には、同じWALデータベースを開く複数の接続が別スレッドまたは別プロセスにあり、書き込みとチェックポイントが狭いタイミングで重なることが含まれます。SQLiteの説明では3.51.3以降で修正済みで、一部の旧系列には3.44.6、3.50.7の修正版があります。まず本番バイナリに実際に組み込まれたSQLiteの版を確認し、該当する複数接続・同時書き込み/チェックポイントの使い方かを判断してください。すべてのWAL環境に同じ緊急度や発生確率を示すものではありません。