WAL
WAL 是数据库先写日志、后写数据页的关键机制,在 PostgreSQL 中同时支撑崩溃恢复、复制与事务持久性。
#type / concept
#status / growing
#tech / dev / backend
#resource / database
#resource / postgresql
[!info] related notes
WAL
一句话定义
WAL 是数据库在真正改写数据页之前,先把恢复所需的变更信息写入日志的机制;在 PostgreSQL 语境里,它也是恢复与复制的核心基础。
它要解决什么问题
数据库如果每次提交都等所有数据页完整刷盘,性能会很差;但如果先只改内存页,又会带来风险:
- 提交刚成功就宕机,磁盘上的数据页还没来得及更新
- 数据库重启后,如何判断哪些修改应当存在
WAL 提供的答案是:
- 不要求提交时所有数据页都写完
- 但要求恢复所需的日志先可靠落盘
这样数据库就能兼顾性能和持久性。
核心机制 / 工作原理
1. WAL 的核心原则是“先写日志,再写数据页”
它背后的关键顺序是:
- 先记录足以恢复修改的日志
- 再由后台或后续流程把数据页刷回磁盘
这就是 write-ahead logging 的含义。
2. 事务提交成功的关键,是 WAL 已经可靠保存
更准确地说:
COMMIT成功,不意味着表文件已经全部更新完- 而意味着数据库已经拥有足够信息,在崩溃后把这次提交恢复出来
因此 WAL 直接支撑的是事务的持久性语义。
3. 在 PostgreSQL 里,WAL 不只是恢复基础
除了崩溃恢复,WAL 还常参与:
- 复制
- 备份与恢复链路
- 某些逻辑同步场景
所以 PostgreSQL 里讨论 WAL,往往不是只在讨论“宕机后怎么重启”,而是在讨论更广的变更传播基础设施。
最小例子 / 最小场景
事务提交后,如果脏页还没真正写回表文件,但对应 WAL 已经安全落盘,那么数据库宕机重启后,仍可以依靠 WAL 把这次已提交变更重做出来。
这说明 WAL 保护的是“已提交结果可恢复”,而不是“提交瞬间表文件已经完全更新”。
从原理上最该抓住什么
1. WAL 首先是一条恢复原则
它最核心的思想不是某一个文件名,而是:
- 恢复依据必须先于最终数据页落盘
2. WAL 和 Redo Log 思想接近,但产品术语不同
从角色上看:
都在帮助数据库重做已提交但尚未完整落盘的修改。
但两边的日志体系拆分方式不同,不能机械地把术语一一对齐。
3. WAL 经常是复制链路的起点
这也是它和很多“只在本机恢复阶段使用的内部日志”相比更容易被外部系统关注的原因。
边界与易混淆点
- WAL 是一种“先写日志再写数据”的机制名,不等于所有数据库都把自己的日志直接叫 WAL。
- PostgreSQL 的 WAL 和 MySQL InnoDB 的 Redo Log 目标相近,但产品术语和实现细节不同。
- WAL 不是普通查询日志,它解决的是可靠性、恢复和复制基础问题。
- 把 WAL 理解成“数据页副本”也不准确,它保存的是恢复和传播变更所需的信息,不是简单整页镜像的口语化替代品。