Undo、Redo、Binlog的相爱相杀
什么是 undo log?为什么需要 undo log?
一句话定义
Undo Log(撤销日志)是 InnoDB 存储引擎层的逻辑日志,记录**“数据修改前的旧值”,用于事务回滚和MVCC 多版本并发控制**。
为什么需要 Undo Log?
场景 | 没有 Undo Log 的后果 | Undo Log 的作用 |
---|---|---|
事务回滚 | 无法撤销已执行一半的 SQL → 数据不一致 | 保存旧值,ROLLBACK 时把数据还原 |
MVCC 一致性读 | 其他事务只能看到最新值,不可重复读/幻读 | 通过旧版本链提供 历史快照,实现 RR 隔离级别 |
崩溃恢复 | 崩溃时未提交事务残留脏数据 | Redo 重放后,用 Undo 回滚未提交事务 |
面试金句
“Undo Log 保存旧值,负责 事务回滚 和 MVCC 历史版本,与 Redo Log 的 新值 互补,共同保证 ACID 里的原子性和隔离性。”
什么是 redo log?为什么需要 redo log?
一句话定义
Redo Log(重做日志)是 InnoDB 引擎的物理日志,记录**“对哪个数据页、哪个偏移量做了什么修改”,用来在崩溃时重做已提交事务**,确保持久性(Durability)。
为什么需要 Redo Log?
场景 | 没有 Redo Log 的后果 | Redo Log 的作用 |
---|---|---|
系统崩溃 | 已提交的数据可能只写 Buffer Pool,未落盘 → 数据丢失 | 崩溃后按 Redo Log 把页修改重新刷盘,保证已提交事务不丢 |
随机写优化 | 每次事务刷盘需随机写数据页,I/O 放大 | 顺序追加写 Redo Log(WAL),延迟批量刷脏页,性能提升 10 倍+ |
原子性 | 写到一半断电,页半新半旧 → 页损坏 | Redo 保证页级幂等,可重放完整修改 |
面试金句
“Redo Log 让 InnoDB 先写日志再写磁盘(WAL),崩溃后重放日志即可恢复已提交事务,既保数据不丢,又减少随机写。”
什么是 binlog?它有几种模式?用来做什么?
一句话定义
Binlog(Binary Log)是 MySQL Server 层的二进制日志,记录所有数据变更事件(SQL 或行级修改),用于 主从复制 和 基于时间点的数据恢复。
三大用途
- 主从复制:从库重放 binlog 同步数据。
- 增量备份与恢复:按时间点恢复误删、误改数据。
- 审计 & 数据变更追踪。
三种模式(binlog_format)
模式 | 记录内容 | 特点 | 场景 |
---|---|---|---|
STATEMENT | 原始 SQL 语句 | 日志小,可能主从不一致 | 无函数/触发器的简单 OLTP |
ROW | 每行变更前后镜像 | 日志大,一致性最强 | 金融、高一致性需求 |
MIXED(默认 5.7+) | 智能切换:STATEMENT 为主,危险操作自动切 ROW | 兼顾大小与一致性 | 线上最常用 |
面试金句
“Binlog 是 MySQL 的 逻辑复制日志,三大用途:主从同步、时点恢复、审计追踪;三种模式 STATEMENT / ROW / MIXED,线上默认 MIXED,强一致性需求切 ROW。”
三者关系和配合
一张图 + 三个阶段,把 Undo、Redo、Binlog 在事务生命周期里的配合关系彻底串起来。
🎯 三者职能一句话
日志 | 记录内容 | 核心目的 |
---|---|---|
Undo | “旧值” | 回滚未提交事务、提供 MVCC 历史版本 |
Redo | “新值” | 崩溃后 重做已提交事务(持久性) |
Binlog | “逻辑事件” | 主从复制、时点恢复 |
🔄 事务三阶段协作流程(背这张图)
🛡️ 崩溃恢复时再跑一次
- Redo 重放所有已提交事务 → 数据页最新。
- Undo 回滚未提交事务 → 去掉脏数据。
- Binlog 不参与崩溃恢复,仅用于 主从 或 人工回放。
🎓 面试一句话
“事务提交时 先写 Undo 旧值、再写 Redo prepare、再写 Binlog、最后 Redo commit;崩溃后用 Redo 重做 + Undo 回滚 保证原子性与持久性,Binlog 负责复制。”