主要观点:数据库实现持久性不一定需要预写日志(WAL),但通常设计中 WAL 对持久性很关键。文中通过无 WAL 的持久化数据库设计来理解 WAL,介绍了不同层次的持久性实现方式,如将数据库写入文件、使用 fsync 等,还提到优化持久化写入的方法(将用户消息写入追加日志,定期写入整个 B 树)、文件系统和磁盘错误的解决办法(校验和)以及其他需要 WAL 的原因(实现 ACID 事务的某些方面、逻辑复制)。
关键信息:
- 无 WAL 的内存数据库无持久性,将数据库写入文件可实现基本持久性但不安全,需 fsync 强制操作系统将数据刷新到磁盘且不能忽略 fsync 失败。
- 可通过组提交来分摊 fsync 成本,关键是在返回成功前确保数据已 fsync 到磁盘。
- 优化持久化写入可将用户消息写入追加日志,定期写入整个 B 树,启动时需从磁盘读取 B 树并重播日志。
- 一些数据库默认不进行数据校验和,磁盘和节点可能完全故障,需通过冗余提高持久性。
重要细节: - 文中以 SQLite、RocksDB、Postgres、MongoDB 等数据库为例说明不同的持久性实现和相关特性。
- 介绍了各种数据库在安全性和性能之间的权衡,如 Postgres 和 MongoDB 提供不默认 fsync 的不安全模式。
- 详细说明了 write-ahead log 的作用和在不同场景下的应用,如在实现 ACID 事务和逻辑复制中的作用。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。