Database / Programming Languages

SQLite WAL:读写并行背后的那本账

理解预写式日志如何改变 SQLite 的提交路径、检查点与故障恢复。

DatabaseProgramming Languages#SQLite#WAL#Transactions

SQLiteSQLiteSQLite Database Engine嵌入应用进程、以单个文件保存主要数据的事务型关系数据库引擎。查看详细解释 → 把数据库引擎嵌入应用进程。默认回滚日志模式会先保存旧页面;而 WALWALWrite-Ahead Logging先把变更可靠记录到日志,再更新主要数据结构的持久化技术。查看详细解释 →(预写式日志)把新的页面版本顺序追加到单独文件中,提交时不必立刻覆盖主数据库。

提交路径发生了什么

事务修改的页面先进入 WAL。提交记录被可靠写入后,事务就可以对新读者可见。旧读者仍从自己开始读取时对应的快照继续工作。

PRAGMA journal_mode = WAL;
PRAGMA synchronous = NORMAL;
PRAGMA wal_checkpoint(PASSIVE);

这使“一个写者、多个读者”在常见负载下更顺畅,但并没有创造多个并行写者。写事务持续太久,其他写者仍会等待。

操作 主要读取位置 是否阻塞普通读者
读取旧快照 主库 + WAL 中已提交帧 通常不会
写入事务 WAL 尾部 同时只能有一个写者
检查点 WAL → 主数据库 受活跃读者边界约束

检查点与恢复

检查点把已提交页面复制回主数据库。崩溃后,SQLite 会读取 WAL 中有效的提交边界来恢复一致状态。应用仍然需要正确处理 SQLITE_BUSY、磁盘空间和备份策略。

WAL 是持久化协议的一部分,不是可以随意删除的缓存。复制数据库时,也必须使用 SQLite 的备份 API,或在能保证一致性的条件下同时处理相关文件。

文中术语

相关文章

Hardware / Programming Languages

缓存如何工作:一个非常具体的解释

从局部性原理出发,具体讲解 CPU 缓存的索引、标签匹配、组相联结构、写入策略,以及面向缓存的代码重构方法。

11 分钟