SQLite のドキュメントには、別のスレッドでチェックポイントを実行することで、WAL モードでのチェックポイントの一時停止を回避できると書かれています(こちら)。これを試してみましたが、うまくいかないようです: ' -wal
' ファイルは際限なく大きくなり、何かが実際にメイン データベース ファイルにコピーされているかどうかが不明であり、(最も重要なことに)-wal
ファイルが十分に大きくなった後 (メインスレッドはチェックポインターを待たなければならなくなります。
私のアプリケーションでは、メイン スレッドはこれと本質的に同等の処理を継続的に実行しgenerate_data
ます。
db = sqlite3.connect("database.db")
cursor = db.cursor()
cursor.execute("PRAGMA wal_autocheckpoint = 0")
for datum in generate_data():
# It is a damned shame that there is no way to do this in one operation.
cursor.execute("SELECT id FROM strings WHERE str = ?", (datum.text,))
row = cursor.fetchone()
if row is not None:
id = row[0]
else:
cur.execute("INSERT INTO strings VALUES(NULL, ?)", (datum.text,))
id = cur.lastrowid
cursor.execute("INSERT INTO data VALUES (?, ?, ?)",
(id, datum.foo, datum.bar))
batch_size += 1
if batch_size > batch_limit:
db.commit()
batch_size = 0
チェックポイントスレッドはこれを行います:
db = sqlite3.connect("database.db")
cursor = db.cursor()
cursor.execute("PRAGMA wal_autocheckpoint = 0")
while True:
time.sleep(10)
cursor.execute("PRAGMA wal_checkpoint(PASSIVE)")
(pysqlite は複数のスレッド間での接続の共有をサポートしていないため、別々のスレッド上にあるため、データベースへの別々の接続が必要です。) FULL または RESTART チェックポイントに変更しても役に立ちません。チェックポイントは失敗するだけです。
これを実際に機能させるにはどうすればよいですか?1) メイン スレッドが待機する必要がない、2) ジャーナル ファイルが際限なく大きくならない。