MySQL 8.0Notes

第 19 章:Redo 与 WAL

zjc 于 2026-01-19 发布

这是《MySQL 8.0 源码与内核实战》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 Redo log 记录物理页修改,用于崩溃恢复时重做到已提交状态。InnoDB 采用 WAL 思路:先记录日志,再择机刷脏页。

19.1 WAL

modify page
  -> write redo log buffer
     -> write log file
        -> fsync as needed
           -> later flush dirty page

崩溃后:

load page
  -> if page LSN older
     -> apply redo from checkpoint

19.2 MTR

mini transaction 是物理一致性单位:

  1. 修改多个页;
  2. 写一组 redo;
  3. 保证页级操作原子性;
  4. 持有相关 latch;
  5. 提交时写 log buffer。

示例:

insert row
  -> modify leaf page
  -> maybe update page directory
  -> mtr commit writes redo records

19.3 LSN

LSN 表示日志序列号:

位置 含义
log buffer 末尾 已写入内存
flushed LSN 已写盘
checkpoint LSN 前缀可以不再重做
page LSN 页面最新修改

checkpoint 推进依赖脏页刷盘和旧版本清理。

19.4 刷盘策略

SHOW VARIABLES LIKE 'innodb_flush_log_at_trx_commit';
行为
1 每次提交 fsync
0 延迟写和刷
2 提交写 OS cache,不强制 fsync

值为 1 最利于持久性;0/2 在故障时可能丢事务,需业务接受。

19.5 Redo 容量

SHOW VARIABLES LIKE 'innodb_redo_log_capacity';
SHOW GLOBAL STATUS LIKE 'Innodb_redo_log%';

容量小的影响:

  1. checkpoint 频繁;
  2. 脏页刷盘压力放大;
  3. 写入抖动;
  4. 用户线程被迫 flush。

容量大也不是无限收益,要结合恢复时间和磁盘能力评估。

19.6 组提交

多个事务提交时可以合并 log flush:

trx1 fsync
trx2 fsync
trx3 fsync
  -> group fsync

收益依赖并发、设备延迟和 binlog sync 策略。

相关:

SHOW VARIABLES LIKE 'sync_binlog';

sync_binlog=1 与 redo 双 1 组合提供更强的持久性保障。

19.7 恢复

start
  -> read checkpoint
     -> scan redo
        -> build page hash
           -> apply redo
              -> rollback uncommitted trx

undo 恢复负责回滚未提交事务,redo 负责重做已提交修改。

19.8 常见问题

现象 方向
commit 延迟高 redo fsync、binlog sync
checkpoint age 高 redo 容量、脏页、IO
刷脏抖动 io_capacity、redo 压力
恢复时间长 redo 量、脏页、大事务回滚
写入尖刺 checkpoint、merge、统计任务

19.9 源码入口

文件 职责
log0log.cc redo 核心
mtr0mtr.cc mini transaction
buf0flu.cc checkpoint 相关刷脏
log0recv.cc 恢复

断点:

b mtr_t::commit
b log_write_flush_to_disk
b log_checkpoint

本章小结

Redo 通过 WAL 保证页修改可恢复。MTR 组织物理修改,LSN 串联日志与页面状态,checkpoint 依赖脏页刷盘推进。刷盘策略、redo 容量和 IO 能力共同决定写入延迟。

思考题

  1. 为什么修改页前先写 redo?
  2. MTR 和事务有什么区别?
  3. checkpoint 为什么依赖脏页刷盘?
  4. innodb_flush_log_at_trx_commit=2 在断电时可能发生什么?
  5. redo 容量过大有什么代价?