★ redo log、undo log、binlog 分别管什么?两阶段提交解决什么问题?

结论先行:undo log 记录如何撤销(回滚与 MVCC),redo log 记录如何重做(InnoDB 崩溃恢复),binlog 是 MySQL Server 层的逻辑日志(主从复制与时间点恢复)。redo 与 binlog 分属不同组件,为让两者一致,InnoDB 采用“redo prepare → 写 binlog → redo commit”的两阶段提交。

一、三类日志对比

对比项redo logundo logbinlog
所在层InnoDB 存储引擎InnoDB 存储引擎MySQL Server 层
记录内容物理页的修改行的旧版本(逆操作)逻辑 SQL/行变更
核心作用崩溃恢复、持久性回滚事务、MVCC 版本链主从复制、恢复、审计
记录时机每次修改先写事务内修改前写事务提交时写
文件示例ib_logfile0/1undo 表空间mysql-bin.000001

二、一条 UPDATE 的写入顺序

1. 读数据页到内存,修改前写 undo(留旧版本)
2. 写 redo log,状态 prepare,同时改内存页
3. 写 binlog
4. 把 redo log 状态改为 commit,事务提交

三、两阶段提交解决了什么

  • 崩溃可能发生在任意一步,会出现“redo 有但 binlog 没有”或相反,导致主从数据不一致。
  • 两阶段提交让 redo 与 binlog 以同一事务 id 对账:恢复时两边都落盘才生效,否则回滚丢弃。
  • 对账规则:redo 是 prepare 且 binlog 已落 → 事务补提交;否则回滚,保证崩溃后主从一致。

四、刷盘参数(双 1)

innodb_flush_log_at_trx_commit = 1   -- 每次提交都刷 redo,最安全
sync_binlog = 1                      -- 每次提交都刷 binlog

常见追问与记忆点

  • 追问:为什么不能让 binlog 先写?binlog 没有崩溃恢复能力,必须以 InnoDB 的 redo 为最终裁决者。
  • 追问:group commit 是什么?多个事务的提交刷盘合并为一次 fsync,提升吞吐。
  • 追问:binlog 的 row 格式与两阶段提交的关系?row 格式记录行级变更,配合两阶段对账,是恢复与校验的基础。
  • 记忆点:undo 管回滚、redo 管恢复、binlog 管复制;prepare 与 commit 之间夹着 binlog 就是两阶段提交。
笔记加载中…