Wal2 モードの有効化/無効化
- SQLite の「Wal2」モードは、「wal(Write-Ahead Logging)」モードと非常によく似ています。
- データベースを wal2 モードに変更するには、
PRAGMA journal_mode = wal2; コマンドを使用します。
- 「wal」モードから直接「wal2」モードに変更することはできず、まずロールバックモードに変更する必要があります。
- wal モードのデータベースを wal2 モードに変更するには、
PRAGMA journal_mode = delete; の後に PRAGMA journal_mode = wal2; コマンドを使用します。
- wal2 モードのデータベースは、そのブランチでコンパイルされた SQLite バージョンでのみアクセス可能です。
- 他のバージョンの SQLite を使用しようとすると、SQLITE_NOTADB エラーが発生します。
- wal2 モードのデータベースをロールバックモードに変更して、すべてのバージョンの SQLite からアクセス可能にするには、
PRAGMA journal_mode = delete; コマンドを使用します。
Wal2 モードの利点
- 従来の wal モードでは、ライターがデータベースにデータを書き込む際、データベースファイルを直接変更せず、「-wal」ファイルに新しいデータを追加します。
- 読み取り処理は、元のデータベースファイルと「-wal」ファイルの両方からデータを読み取ります。
- ある時点で、「-wal」ファイルからデータベースファイルへデータがコピーされ、これを「チェックポイント」と呼びます。
- チェックポイントは、
PRAGMA wal_checkpoint または sqlite3_wal_checkpoint_v2() によって明示的に実行されるか、PRAGMA wal_autocheckpoint を設定して自動的に実行されます(デフォルト設定)。
- チェックポインタはライターをブロックせず、ライターもチェックポインタをブロックしません。
- しかし、チェックポイント中にライターがデータベースへ書き込むと、新しいデータが wal ファイルの末尾に追加されるため、wal ファイルが継続的に大きくなる可能性があります。
- wal2 モードでは、チェックポインタが妨げられずに完了する機会がなくても、wal ファイルが無制限に肥大化する問題はありません。
- wal2 モードでは、1 つではなく 2 つの wal ファイル(「-wal」および「-wal2」)を使用します。
- データが書き込まれると、ライターは最初の wal ファイルへの新しいデータの追加を開始します。
- 最初の wal ファイルが十分に大きくなると、ライターは 2 番目の wal ファイルにデータを追加し始めます。
- その後、最初の wal ファイルはチェックポイント可能になり、2 番目の wal ファイルが十分に大きくなって最初のファイルのチェックポイントが完了すると、再び最初のファイルへ切り替わります。
アプリケーションプログラミング
- ユーザーの観点から見ると、wal モードと wal2 モードの主な違いはチェックポイントに関係しています。
- wal モードではいつでもチェックポイントを試みることができますが、wal2 モードではライターが「もう一方の」wal ファイルへ切り替えた後でなければチェックポイントできません。
- wal モードでは、トランザクションがコミットされた後、wal ファイルの総ページ数を引数として wal-hook(コールバック)が呼び出されます。
- wal2 モードでは、wal-hook は 2 つの wal ファイルにある未チェックポイントページの合計数を引数として、または「もう一方の」wal ファイルが空かすでにチェックポイント済みであれば 0 を引数として呼び出されます。
- クライアントには、wal2 モードのデータベースに対しても wal モードと同じチェックポイント戦略を使用することが推奨されます。
- wal-hook はトランザクションがディスクにコミットされ、データベースロックが解放された後に呼び出されますが、
sqlite3_step() 呼び出しの内部で発生します。
- BEGIN CONCURRENT システムでは、wal-hook 内でチェックポイントを実行する代わりに、アプリケーションミューテックスが解放された後でこの処理を遅延させるスレッドを使用できます。
GN⁺の意見
- SQLite の wal2 モードは、データベースの並行性と効率を向上させる新しいジャーナリング方式を提供します。
- wal ファイルの無制限な肥大化の問題を解決し、システムの安定性と性能を改善することが重要です。
- 開発者は wal2 モードの導入に伴い、データベースのチェックポイント戦略を見直し、より良い並行性のために適切なチェックポイントロジックを実装する必要があります。
1件のコメント
Hacker Newsのコメント
Bedrock
WAL2モードに似た技術であるleft-right primitiveへのリンクあり。
wal2に切り替わったのだからwalファイルは残り物だと思って、walファイルを削除してしまう人がどれだけいるのか気になる。Microsoft SQL Serverは似たアーキテクチャを使っているが、別個のログファイルではなく、物理的な(ディスク上の)ログファイル内にVirtual Log Files(VLF)を割り当てる。VLFはリングバッファから割り当てられ、数千個に達することもある。
この機能がまだリリースされていないことはわかる。
WALはデータ整合性を保ち、クラッシュからの復旧を助けるために存在するのだとずっと思っていた。しかしファイル自体はバッチで書き込まれ(ディスクへ信頼できる形でコミットされ)、それもデータベースの変更ごとではなく、性能を得るためにそうしている。これはその目的を損なわないのだろうか? データベース一般の話として、これに対する答えを見つけられなかった。
これがLitestreamのような新しい分散SQLiteシステムにどんな影響を与えるのか気になる。
つまり基本的には、データベースのためのダブルバッファリングということか? 納得できる。
WAL2モードはHC-treeバックエンド研究のベンチマークに含まれていた。