MySQL 日志与事务机制 · 交互式讲解

Redo Log · Undo Log · 两阶段提交 — 点击按钮逐步观察原理

Redo Log — 重做日志

保证事务的持久性(Durability),核心思想:WAL(Write-Ahead Logging,先写日志再写磁盘)

📌 核心概念

Redo Log 记录的是数据页的物理修改,用于崩溃后将已提交但未刷盘的数据恢复到一致状态。

🔄 交互演示:UPDATE 语句的写入路径

点击「下一步」观察 SQL 执行时,数据在内存与磁盘之间的完整流转。

①客户端发送SQL
②修改Buffer Pool
③写Redo Log Buffer
④fsync到磁盘
⑤返回客户端
⑥后台刷脏页
点击「▶ 下一步」开始
客户端 MySQL Server Buffer Pool Redo Log 数据文件

🚨 交互演示:崩溃恢复(Crash Recovery)

模拟 MySQL 崩溃重启后,如何利用 redo log 恢复已提交但未刷盘的数据。

点击「▶ 下一步」开始

Undo Log — 回滚日志

保证事务的原子性(Atomicity),实现回滚和 MVCC 快照读

📌 核心概念

Undo Log 记录的是数据被修改前的版本,用于事务回滚和 MVCC 的快照读。

🔗 交互演示:Undo Log 版本链

观察同一行记录被多次修改后,如何通过 undo log 形成版本链。

点击「▶ 下一步」开始

🔍 交互演示:MVCC 快照读

模拟两个事务并发执行,观察快照读如何通过 ReadView + undo log 链找到正确的数据版本。

点击「▶ 下一步」开始

两阶段提交(Two-Phase Commit)

保证 Redo Log 与 Binlog 的数据一致性,是 MySQL 主从复制安全性的基石

📌 为什么需要两阶段提交?

MySQL 有两套独立的日志

若先写 redo 再写 binlog(或反过来),崩溃时两套日志可能不一致——主库用 redo 恢复的数据,从库通过 binlog 复制后得到不同结果。

两阶段提交通过 Prepare → Commit 两个步骤保证两者完全一致。

🔄 交互演示:两阶段提交流程

观察事务提交时,redo log 和 binlog 如何协同工作。

①PREPARE
②写Binlog
③COMMIT
④返回客户端
点击「▶ 下一步」开始

🚨 崩溃恢复判断逻辑

重启后,InnoDB 扫描处于 Prepare 状态的 redo log 事务,对照 binlog 决定如何处理:

Redo Log 状态Binlog 状态恢复操作
PREPARE✅ 完整写入✅ 提交事务(补写 COMMIT 标记到 redo)
PREPARE❌ 不完整❌ 回滚事务(利用 undo log)
COMMIT任意✅ 已提交,无需处理

对比总结

Redo Log、Undo Log、Binlog 的核心差异

维度Redo LogUndo LogBinlog
所属层InnoDB 引擎层InnoDB 引擎层MySQL Server 层
日志类型物理日志(数据页修改)逻辑日志(反操作)逻辑日志(SQL/行变更)
主要作用持久性(Durability)原子性 + MVCC主从复制 + 点恢复
刷盘时机事务提交时(取决于配置)修改记录前(先写 undo)事务提交时
写入方式循环写(固定大小)追加写(undo tablespace)追加写
崩溃恢复重放已提交事务回滚未提交事务用于主从同步

💡 面试高频问题