4

PRAGMA journal_mode=WAL、PRAGMA journal_size_limit=0 の db ファイルに継続的に書き込みを行っています。私の C++ プログラムには、リーダー (15 秒間隔でクエリ) とライター (5 秒間隔で挿入) の 2 つのスレッドがあります。

3 分ごとに挿入を一時停止して、モード パラメータを SQLITE_CHECKPOINT_RESTART としてライター スレッドから sqlite3_wal_checkpoint_v2() を実行しています。この時点でアクティブな読み取り操作が行われていないことを確認するために、チェックポイントが実行されようとしているというフラグを設定し、リーダーが完了する (接続がまだ開いている) のを待ってからチェックポイントを実行します。チェックポイントの完了後、クエリを再開しても問題ないことを再度読者に示します。

sqlite3_wal_checkpoint_v2() は SQLITE_OK を返し、pnLog と Ckpt は等しい (約 4000) として返され、完全な wal ファイルがメインの db ファイルと同期されたことを示します。したがって、ドキュメントに従って、次の書き込みは最初から開始する必要があります。ただし、後続の書き込みによって WAL ファイルが無限に大きくなり、最終的には数 GB になるため、これは発生していないようです。

いくつかの検索を行ったところ、開いているトランザクションが原因でリーダーがチェックポイントの失敗を引き起こす可能性があることがわかりました。ただし、私が使用している唯一のリーダーは、チェックポイントが開始する前にトランザクションを終了することです。WAL ファイルが大きくならないのを妨げているものは他にあるでしょうか?

4

1 に答える 1

2

これは答えとしては遅すぎますが、他の人には役立つかもしれません。

SQLite のドキュメントによると、あなたの期待は正しいはずですが、このSO 投稿を読むと、ファイナライズされていないステートメントの場合にも問題が発生します。したがって、ステートメントだけの場合、データベースがビジーsqlite3_reset()状態に見えるか、チェックポイントのためにロックされているように見える可能性があります。これは、 のレベルが高い場合にも発生する可能性があることに注意してください。SQLITE_CHECKPOINT_values

また、この値は、チェックアウトが正常に行われた場合、ファイルの長さを 0SQLITE_CHECKPOINT_TRUNCATEに切り捨てます。-walこれは、すべてのページがデータベースに挿入されたことを確認するのに役立ちます。

-walファイナライズされていないステートメントが原因でファイルがますます大きくなる別の議論は、これです

于 2016-06-16T16:57:46.827 に答える