我正在连续写入一个数据库文件,该文件的PRAGMA journal_mode=WAL,PRAGMA journal_size_limit=0。我的C++程序有两个线程,一个读取器(每隔15秒查询)和一个写入器(每隔5秒插入)。
每隔3分钟我会暂停插入以运行sqlite3_wal_checkpoint_v2()从写入器线程使用模式参数SQLITE_CHECKPOINT_RESTART。要确保此时没有活动的读取操作正在进行,我设置了一个标志,表示检查点操作即将发生,并等待读取器完成(连接仍然打开)。检查点完成后,我再次向读者指示可以继续查询。
sqlite3_wal_checkpoint_v2()返回SQLITE_OK,并且pnLog和Ckpt相等(大约4000),表示完整的wal文件已与主数据库文件同步。因此,根据文档,下一次写入应从头开始。但是,这似乎不会发生,因为后续写入会导致WAL文件无限增长,最终达到一些GB。
我做了一些搜索,发现读取器可能会由于打开的事务而导致检查点失败。然而,我使用的唯一读取器在检查点开始之前就结束了它的事务。还有什么可能阻止WAL文件不增长呢?
1条答案
按热度按时间uxhixvfz1#
这作为一个答案为时已晚,但可能对其他人有用。
根据SQLite documentation,您的期望应该是正确的,但是如果您阅读此SO post,则在未完成语句的情况下也会出现问题。因此,如果您只是
sqlite3_reset()
您的语句,则无论如何都有可能数据库可能看起来为检查点“忙碌”或“锁定”。请注意,对于更高级别的SQLITE_CHECKPOINT_values
,也可能发生这种情况。另外,
SQLITE_CHECKPOINT_TRUNCATE
的值,如果 checkout 成功,会将-wal
文件截短为零长度,这样可以帮助你检查所有的页面都已经插入到数据库中了。-wal
文件由于未完成的语句而变得越来越大的另一个讨论是this。