Redo Log · Undo Log · 两阶段提交 — 点击按钮逐步观察原理
保证事务的持久性(Durability),核心思想:WAL(Write-Ahead Logging,先写日志再写磁盘)
Redo Log 记录的是数据页的物理修改,用于崩溃后将已提交但未刷盘的数据恢复到一致状态。
ib_logfile0、ib_logfile1innodb_flush_log_at_trx_commit:0=不保证;1=每次提交 fsync(默认,最安全);2=写 OS buffer 每秒 fsync点击「下一步」观察 SQL 执行时,数据在内存与磁盘之间的完整流转。
模拟 MySQL 崩溃重启后,如何利用 redo log 恢复已提交但未刷盘的数据。
保证事务的原子性(Atomicity),实现回滚和 MVCC 快照读
Undo Log 记录的是数据被修改前的版本,用于事务回滚和 MVCC 的快照读。
观察同一行记录被多次修改后,如何通过 undo log 形成版本链。
模拟两个事务并发执行,观察快照读如何通过 ReadView + undo log 链找到正确的数据版本。
保证 Redo Log 与 Binlog 的数据一致性,是 MySQL 主从复制安全性的基石
MySQL 有两套独立的日志:
若先写 redo 再写 binlog(或反过来),崩溃时两套日志可能不一致——主库用 redo 恢复的数据,从库通过 binlog 复制后得到不同结果。
两阶段提交通过 Prepare → Commit 两个步骤保证两者完全一致。
观察事务提交时,redo log 和 binlog 如何协同工作。
重启后,InnoDB 扫描处于 Prepare 状态的 redo log 事务,对照 binlog 决定如何处理:
| Redo Log 状态 | Binlog 状态 | 恢复操作 |
|---|---|---|
| PREPARE | ✅ 完整写入 | ✅ 提交事务(补写 COMMIT 标记到 redo) |
| PREPARE | ❌ 不完整 | ❌ 回滚事务(利用 undo log) |
| COMMIT | 任意 | ✅ 已提交,无需处理 |
Redo Log、Undo Log、Binlog 的核心差异
| 维度 | Redo Log | Undo Log | Binlog |
|---|---|---|---|
| 所属层 | InnoDB 引擎层 | InnoDB 引擎层 | MySQL Server 层 |
| 日志类型 | 物理日志(数据页修改) | 逻辑日志(反操作) | 逻辑日志(SQL/行变更) |
| 主要作用 | 持久性(Durability) | 原子性 + MVCC | 主从复制 + 点恢复 |
| 刷盘时机 | 事务提交时(取决于配置) | 修改记录前(先写 undo) | 事务提交时 |
| 写入方式 | 循环写(固定大小) | 追加写(undo tablespace) | 追加写 |
| 崩溃恢复 | 重放已提交事务 | 回滚未提交事务 | 用于主从同步 |