MySQL 专题(五):日志体系(Redo Log、Undo Log、Binlog)原理与应用
MySQL 专题(五):日志体系(Redo Log、Undo Log、Binlog)原理与应用
在前面的文章中,我们讲解了 事务的 ACID 特性 和 MVCC 机制。但是一个问题随之而来:
👉 如果 MySQL 在执行过程中宕机了,数据如何恢复?
👉 为什么 MySQL 能实现 事务回滚、崩溃恢复、主从复制?
答案就在于 MySQL 的三大日志体系:
- Redo Log(重做日志,InnoDB 专用)
- Undo Log(回滚日志,InnoDB 专用)
- Binlog(归档日志,MySQL Server 层)
这三者一起支撑了 MySQL 的事务能力和高可用架构。
一、Redo Log:保证事务的持久性
1. 为什么需要 Redo Log?
如果每次修改都直接写入数据页(磁盘),会有两个问题:
- 磁盘 I/O 开销太大,性能很差。
- 万一写到一半宕机,可能导致数据页损坏。
👉 解决办法:先写日志,再写数据(WAL,Write-Ahead Logging)。
2. Redo Log 特点
- 物理日志:记录的是 数据页的物理修改,比如“在某个页的某个偏移量写入了 xxx”。
- 先写日志,再异步刷脏页。
- 以循环写的方式存储,大小固定(如 4GB)。
3. Redo Log 工作流程
- 事务更新时,先写入 Buffer Pool(内存)。
- 同时记录修改到 Redo Log Buffer。
- 事务提交时,Redo Log 刷盘(fsync),保证崩溃后能恢复。
- 后台线程 异步刷脏页 到磁盘。
👉 这样即使宕机,也能通过 Redo Log 把 Buffer Pool 里的数据重新“重做”一遍,保证 持久性。
二、Undo Log:保证事务的原子性
1. 为什么需要 Undo Log?
如果事务执行到一半需要回滚,怎么恢复原来的数据?
👉 就需要 Undo Log,它记录了数据修改前的版本。
2. Undo Log 特点
- 逻辑日志:记录的是 如何回滚,比如 “把
name
从'Jerry'
改回'Tom'
”。 - 事务回滚时,用 Undo Log 恢复旧值。
- 也是 MVCC 的核心依赖。
3. Undo Log 工作流程
- 修改数据时,先记录旧值到 Undo Log。
- 如果事务回滚,就用 Undo Log 恢复数据。
- 事务提交后,Undo Log 可能被清理(但 MVCC 可能需要保留历史版本)。
三、Binlog:保证数据一致性与复制
1. 为什么需要 Binlog?
Redo Log 是 InnoDB 专用的,并且是循环写的,不能用于归档。
👉 如果要做 主从复制、数据恢复(恢复到指定时间点),就需要 Binlog。
2. Binlog 特点
- 逻辑日志:记录的是 SQL 语句 或 行级别的修改。
- 只追加写,不会覆盖,大小无限制。
- 存储在 MySQL Server 层,所有存储引擎通用。
3. Binlog 格式
- STATEMENT:记录 SQL 语句(节省空间,但可能产生不一致)。
- ROW:记录每行的变更(更可靠,但日志量大)。
- MIXED:混合模式。
四、三大日志的关系
事务提交时,MySQL 的内部流程大致如下:
- 写入 Undo Log(保证可回滚)。
- 写入 Redo Log Buffer。
- 写入 Binlog。
- 刷盘 Redo Log(两阶段提交)。
👉 两阶段提交(2PC) 是为了保证 Redo Log 与 Binlog 的一致性。
否则可能出现 Redo Log 成功而 Binlog 失败,导致主从数据不一致。
五、三大日志的对比
日志类型 | 层级 | 内容类型 | 作用 |
---|---|---|---|
Redo Log | InnoDB 引擎 | 物理日志(页修改) | 保证事务 持久性,崩溃恢复 |
Undo Log | InnoDB 引擎 | 逻辑日志(旧值) | 保证事务 原子性,支持 MVCC |
Binlog | Server 层 | 逻辑日志(SQL/行) | 主从复制、数据恢复 |
六、实际应用场景
-
崩溃恢复
- Redo Log 重放 → 保证已提交事务不会丢失。
- Undo Log 回滚 → 保证未提交事务被撤销。
-
主从复制
- 主库写入 Binlog,从库通过 Binlog Relay Log 重放。
-
数据恢复
- 结合全量备份 + Binlog,可以恢复到指定时间点。
七、总结
- Redo Log:保证崩溃后数据不丢失。
- Undo Log:保证事务可回滚,支撑 MVCC。
- Binlog:保证数据可复制和恢复。
- 两阶段提交:保证 Redo Log 与 Binlog 的一致性。
👉 一句话总结:
Redo Log 保证事务持久性,Undo Log 保证事务原子性,Binlog 保证数据一致性。三者相辅相成,构成 MySQL 强大的事务与高可用体系。