3

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) ジャーナル ファイルが際限なく大きくならない。

4

1 に答える 1

5

チェックポイントはデータベース全体をロックする必要があるため、他のすべての読み取りと書き込みをブロックする必要があります。(パッシブ チェックポイントは単に中止されます。)

そのため、別のスレッドでチェックポイントを実行しても同時実行性は向上しません。(SQLite のドキュメントがこれを示唆しているのは、メイン スレッドがアイドル状態でチェックポイントを処理するように設計されていない可能性があるためです。)

データベースに連続してアクセスすると、チェックポイントができません。バッチ操作で WAL ファイルが大きくなりすぎる場合は、そのループに明示的なチェックポイントを挿入する (または自動チェックポイントに依存する) 必要があります。

于 2014-03-27T08:03:10.860 に答える