WAL 预写日志机制
数据库突然断电,重启后数据还在吗?这取决于 WAL(Write-Ahead Logging,预写日志)。
WAL 是存储引擎最朴素的可靠性保证:先把日志写到磁盘,再写数据。就算写数据时崩溃,日志里也有记录。
WAL 原理
WAL 的核心思想:在数据写入磁盘之前,先把操作记录写入日志。
WAL 的三个关键特性
顺序写:WAL 日志只追加,不修改,天然是顺序写。
同步刷盘:日志写入后必须同步刷盘,不能只停留在内存。
幂等操作:日志中记录的是「做什么」,而不是「做了什么」,方便重放。
WAL 与 Redo Log 的关系
很多资料把 WAL 和 Redo Log 混用,但严格来说:
- WAL:通用概念,任何「先写日志再写数据」的机制都是 WAL
- Redo Log:InnoDB 中特定的 WAL,记录「重做」操作
WAL 工作流程
写入流程
崩溃恢复流程
WAL 实现
日志格式
写入实现
Checkpoint 机制
WAL 会不断增长,不能无限保留。Checkpoint 机制定期标记「此前的日志已安全刷盘」,可以清理。
WAL vs Redo Log vs Undo Log
Redo Log:重做未刷盘的数据
Undo Log:回滚未提交的事务
组提交优化
WAL 的瓶颈是刷盘。如果每条日志都单独刷盘,性能很差。组提交(Group Commit)把多个日志合并成一次刷盘。
生产配置建议
配置警示:
innodb_flush_log_at_trx_commit设置为 0 或 2 会显著提升性能,但会牺牲持久性。如果对数据可靠性要求高(如金融场景),必须设置为 1。