SQLite3 のオンラインバックアップ

どのような点で優れているか?

SQLite ロック機構に則ってデータベースの複製が行われるので、オンラインのデータベースに対して安全に処理を実行できる。 例えば、単にバックアップを取るだけならファイルコピーでも可能だが、もしデータベースが書き込み中であった場合、バックアップは壊れている恐れがある。 ちなみに、オンラインバックアップの対象はデータベース単位である。 特定のテーブルのみ取り出したいといった場合は、ユースケースに合わないので愚直に ATTACH と INSERT クエリでコピーすべし。

実施手順

オンラインバックアップの実施は非常に簡単で、sqlite3 コマンドで .backup というメタコマンドを実行する。

以下に実行例を示す。 ここでは、sample.db という SQLite データベースのバックアップを sample.db.backup として取っている。 ちなみに、sample.db.backup というファイルが既に存在する場合、上書きされてしまうので注意。

$ sqlite3 sample.db "SELECT * FROM members;"
1|Smith
2|Alisa
$ sqlite3 sample.db ".backup sample.db.backup"
$ sqlite3 sample.db.backup "SELECT * FROM members;"
1|Smith
2|Alisa

また、バックアップ元およびバックアップ先としてカレントディレクトリ以外を指定したい場合には、 絶対パスもしくは相対パスを用いて指定すればよい。

$ sqlite3 sample.db ".backup /var/tmp/sample.db.backup"
$ sqlite3 sample.db.backup "SELECT * FROM members;"
1|Smith
2|Alisa

ちなみに、アタッチしているデータベースのバックアップを取りたい場合は、 コマンドの第1引数に、バックアップを取りたいデータベース名を指定する。

$ sqlite3
sqlite> ATTACH DATABASE "sample.db" as sample;
sqlite> .backup sample sample.db.backup
sqlite> .quit

$ sqlite3 sample.db.backup "SELECT * FROM members;"
1|Smith
2|Alisa

インメモリデータベースの書き出し

オンラインバックアック機能を使えば、インメモリデータベースの書き出すことが可能である。

$ sqlite3
SQLite version 3.7.17 2013-05-20 00:56:22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> CREATE TABLE members (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT);
sqlite> INSERT INTO members (name) VALUES ('Smith');
sqlite> INSERT INTO members (name) VALUES ('Alisa');
sqlite> SELECT * FROM members;
1|Smith
2|Alisa
sqlite> .backup sample.db
sqlite> .quit

$ sqlite3 sample.db 
SQLite version 3.7.17 2013-05-20 00:56:22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> SELECT * FROM members;
1|Smith
2|Alisa

インメモリデータベースへの読み込み

.backup コマンドと逆の操作を実施する .restore コマンドがある。 これを利用すれば、ファイルに書き出したデータベースをインメモリデータベースとして読み込むことが可能である。 ちなみに、この操作を実施した時点で既にインメモリ上にデータベースが開かれていた場合、 そのデータベースは上書きされて消えてしまうので非常に注意。

$ sqlite3
SQLite version 3.7.17 2013-05-20 00:56:22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .restore sample.db
sqlite> SELECT * FROM members;
1|Smith
2|Alisa

ライブラリによるサポート

オンラインバックアップは、C ライブラリから利用することも可能である。 詳細は割愛するが、C ライブラリではより細かくバックアップ挙動を指定することが可能である。 ちなみに、Python の sqlite3 モジュールは未対応。

参考