PostgreSQL WAL 和 checkpoint 是什么?
简化版
WAL 是 Write-Ahead Logging,意思是数据页真正写入磁盘前,先把变更记录写入 WAL 日志。这样数据库崩溃后可以用 WAL 重放恢复数据。checkpoint 是检查点,会把一部分脏数据页刷新到磁盘,并记录恢复起点,减少崩溃恢复需要重放的 WAL 范围。
详细版
WAL 和 checkpoint 的关系可以这样理解:
- WAL 保证持久性和崩溃恢复;
- 修改数据时先写日志,再写数据页;
- 事务提交通常要确保相关 WAL 已持久化;
- checkpoint 把脏页刷盘,推进恢复起点;
- checkpoint 太频繁会增加 I/O 压力,太少会拉长恢复时间。
面试中要能说明:WAL 不是普通业务日志,而是数据库恢复机制的核心;checkpoint 不是清空 WAL,而是让数据库知道崩溃后从哪里开始恢复更合适。
完整版教学
一、为什么需要 WAL
数据库更新数据时,不可能每次都立刻把所有数据页安全写回磁盘。数据页可能先在内存缓冲区里被修改,稍后再刷盘。
如果这时数据库崩溃,就会出现问题:事务已经告诉客户端提交成功,但对应数据页还没来得及写入磁盘。
WAL 的解决思路是:先把“我要做什么修改”写入顺序日志,并保证日志先于数据页落盘。崩溃后,即使数据页没写完,也可以根据 WAL 重放恢复。
二、WAL 的写入顺序
典型流程可以理解为:
- 事务修改数据页,数据页变成脏页;
- PostgreSQL 生成对应 WAL 记录;
- 提交时确保必要 WAL 记录持久化;
- 数据页稍后由后台进程或 checkpoint 刷盘;
- 崩溃恢复时重放 WAL,让数据回到一致状态。
顺序写 WAL 通常比随机写大量数据页更高效,这也是 WAL 设计的重要性能收益。
三、checkpoint 的作用
如果只有 WAL 而没有 checkpoint,数据库崩溃后可能要从非常早的日志开始重放,恢复时间会很长。
checkpoint 会把一批脏页写回磁盘,并记录一个恢复位置。之后数据库崩溃时,不必从更早位置开始重放。
checkpoint 的价值是:
- 缩短崩溃恢复时间;
- 控制 WAL 文件保留和生成压力;
- 推进数据页持久化进度。
四、checkpoint 配置不当会影响性能
checkpoint 太频繁,会导致大量脏页集中刷盘,产生 I/O 抖动。checkpoint 间隔太长,又可能导致 WAL 积累多、崩溃恢复时间变长。
常见相关参数和现象包括:
- checkpoint 过于频繁导致写入延迟抖动;
- WAL 生成速度过快导致磁盘压力;
- 大批量导入、建索引、更新引起 WAL 暴增;
- 复制或归档消费不及时导致 WAL 堆积。
实际优化要结合磁盘能力、写入峰值、恢复时间目标和复制架构综合考虑。
五、WAL 还支撑复制和备份
WAL 不只用于本机崩溃恢复,也支撑 PostgreSQL 的流复制、归档恢复、时间点恢复等能力。
例如主库把 WAL 发送给备库,备库重放 WAL 来追赶主库状态。归档 WAL 后,可以结合基础备份恢复到某个时间点。
所以 WAL 是 PostgreSQL 高可用和备份恢复体系的基础。
六、常见误区与追问
| 概念 | 核心作用 | 调优关注 |
|---|---|---|
| WAL | 崩溃恢复、复制、归档恢复 | 写入量、落盘延迟、堆积 |
| checkpoint | 刷脏页并推进恢复起点 | I/O 抖动、恢复时间 |
| archived WAL | 时间点恢复和灾备 | 归档延迟、磁盘容量 |
记忆钩子:WAL 保证“崩了能重放”,checkpoint 保证“不用从很久以前重放”。二者一个偏恢复依据,一个偏恢复起点。
用数字理解:如果 checkpoint 之间生成 20GB WAL,崩溃恢复时可能要重放更多日志;如果把 checkpoint 设得非常频繁,脏页会更密集刷盘,写入延迟可能抖动。真实配置要在恢复时间目标、磁盘 I/O 能力、写入峰值和复制归档能力之间取平衡。
WAL 和 checkpoint 的恢复链路可以简化成:
事务提交 -> WAL 持久化 -> 数据页稍后刷盘
|
checkpoint 记录恢复起点
|
崩溃后从检查点附近重放 WAL
- 误区:WAL 是普通业务操作日志。 WAL 是数据库崩溃恢复和复制的底层日志,不是给业务审计直接阅读的日志。
- 误区:checkpoint 会清空 WAL。 checkpoint 推进恢复起点,但 WAL 是否删除还受复制、归档、保留策略等影响。
- 误区:checkpoint 越频繁越安全。 过于频繁会带来集中刷脏页和 I/O 抖动,安全性和性能要平衡。
- 追问:为什么要先写 WAL 再写数据页? 这样提交后即使数据页没落盘,崩溃恢复也能通过 WAL 重放到一致状态。
- 追问:WAL 为什么能支撑复制? 主库把 WAL 发送给备库,备库重放 WAL,就能追赶主库的数据变化。
- 追问:WAL 堆积常见原因是什么? 复制延迟、归档失败、复制槽长期不消费、大批量写入或 checkpoint/保留策略不合理。
七、加强记忆
WAL 记住“先写日志再写数据”,checkpoint 记住“把脏页刷盘并推进恢复起点”。WAL 负责崩溃后能恢复,checkpoint 负责恢复不要从太久以前开始;两者共同影响可靠性、写入性能和恢复时间。