【发布时间】:2015-03-17 15:40:19
【问题描述】:
我在 Debian 7 上使用 SQLite 3.7.13 时遇到了一个有趣的问题。
我正在使用带有“PRAGMA journal_mode = wal”和“PRAGMA synchronous = normal”的 SQLite 来尝试避免 Python 程序的主事件循环中的 fsync。正如文档所建议的,我已禁用自动检查点,并定期在 不同线程 中运行“PRAGMA wal_checkpoint”以将最新数据同步到磁盘。
这是可行的,但是我发现 主程序线程 中的检查点之后的 first 插入操作会导致 WAL 文件本身的一次性 fsync 调用.任何进一步的插入操作都不会导致 fsync。我已经使用 strace 验证了这一点。
查看它说的 SQLite 文档:
WAL 文件在检查点后开始被重用时同步 WAL 文件头
我正在寻找一种方法来防止在主线程中发生任何 fsync,但这仍然允许我从另一个线程执行定期检查点。在检查点线程中是否可以做更多的事情来避免主线程中的 fsync?
我查看了“同步 = 关闭”,但这也阻止了检查点的 fsync。
注意:我为两个线程中的每一个线程都有一个单独的数据库连接(如果相关的话)
进一步说明:文档似乎在其他地方说不应该有 fsync,但观察到的行为明显不同:
请注意,当 PRAGMA 同步设置为 NORMAL 时,检查点是发出 I/O 屏障或同步操作的唯一操作(unix 上的 fsync() 或 windows 上的 FlushFileBuffers())。因此,如果应用程序在单独的线程或进程中运行检查点,则执行数据库查询和更新的主线程或进程将永远不会阻塞同步操作。
谢谢
【问题讨论】: