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,或在能保证一致性的条件下同时处理相关文件。

文中术语

相关文章

AI / Programming Languages

如果编程已经被解决,接下来呢?衡量代码的“草率度”

LLM 能生成近乎正确的代码,却仍会制造重复、冗余和逐步累积的糟糕决策。本文比较 AI 评审、人工评审、代码行数、冗余度与侵蚀度等衡量方法,并结合 SlopCodeBench 解释为什么人的直觉与品味依然不可替代。

6 分钟