大家好,我是程序员二叉。
简介
MySQL InnoDB 引擎依靠 redo log、undo log 实现事务特性与宕机恢复,binlog 负责数据备份与主从复制。三者各司其职、协同工作,是 MySQL 事务、高可用架构的核心。
本文依次讲解三大日志作用、WAL 机制、binlog 三种格式、两大日志区别、两阶段提交原理。
一、三大日志基本作用
1. redo log(重做日志)
InnoDB 存储引擎层独有,物理日志
- 核心作用:实现崩溃恢复,保证事务持久性
- 记录内容:数据页物理修改信息(页偏移、修改内容)
- 写入时机:事务执行过程中持续写入
2. undo log(回滚日志)
InnoDB 存储引擎层独有,逻辑日志
- 核心作用:
- 事务回滚:执行 ROLLBACK 时恢复数据到修改前状态
- 支撑 MVCC 多版本并发控制,实现读写不阻塞
- 记录内容:数据修改前的旧版本数据
3. binlog(二进制日志)
MySQL 服务层日志,所有存储引擎通用,逻辑日志
- 核心作用:
- 主从复制:主库向从库同步数据
- 数据备份 + 时间点恢复
- 记录内容:执行的 SQL 语句 或 行数据变更记录
二、redo log、WAL 机制 与 崩溃恢复原理
1. WAL 预写日志机制
WAL(Write-Ahead Logging)核心规则:先写日志,后刷数据
作用:规避随机磁盘 IO,大幅提升数据库写入性能。
2. redo log 如何保证事务崩溃恢复
- 扫描 redo log 日志文件
- 日志存在 prepare + commit 标记:重放日志,将数据落盘
- 日志仅有 prepare、无 commit:丢弃日志,回滚事务
结论:已提交的事务绝对不会丢失,严格保证事务持久性。
三、binlog 三种格式区别
binlog 是逻辑日志,提供三种记录格式,适用于不同业务场景:
- 记录内容:原始执行的 SQL 语句
- 优点:日志体积小,磁盘 IO 压力低
- 缺点:存在主从数据不一致风险
- 风险场景:now()、rand()、自定义函数、limit 等非确定性 SQL
- 记录内容:每行数据修改前后的完整字段内容
- 优点:主从数据绝对一致,无不确定性问题
- 缺点:日志文件体积大,磁盘 IO 开销高
- 运行逻辑:MySQL 自动判断切换格式
- 普通确定性 SQL:使用 STATEMENT
- 非确定性 SQL:自动切换为 ROW
- 定位:折中方案,兼顾日志体积与数据一致性
四、redo log 与 binlog 核心区别
| 所属层级 | InnoDB 存储引擎层 | MySQL 服务层 |
| 日志类型 | 物理日志(数据页修改) | 逻辑日志(SQL / 行变更) |
| 核心用途 | 崩溃恢复、事务持久化 | 主从复制、数据备份恢复 |
| 写入时机 | 事务执行中持续写入 | 事务提交时一次性写入 |
| 写入方式 | 循环覆盖(固定文件大小) | 追加写入(不断新建文件) |
| 引擎支持 | 仅 InnoDB 引擎 | 所有存储引擎通用 |
五、事务提交:redo log + binlog 两阶段提交(2PC)
1. 存在问题
如果两份日志写入顺序错乱,宕机会导致日志与数据不一致:
解决方案:两阶段提交,保证两份日志原子性(同时成功、同时回滚)
2. 完整执行流程
阶段一:Prepare 准备阶段
步骤:写入 binlog
阶段二:Commit 提交阶段
3. 宕机恢复规则(高频考点)
redo log 只有 prepare,无完整 binlog → 事务回滚
宕机在 binlog 写完、redo commit 之前
binlog 完整存在,redo log 有 prepare 标记 → 数据库自动补 commit,提交事务
最终效果:redo log 与 binlog 状态完全统一。
总结
1.三大日志分工
- undo log:事务回滚 + 实现 MVCC;
- redo log:基于 WAL 机制实现崩溃恢复,保障事务持久;
- binlog:服务层通用日志,用于数据备份与主从复制。
2.binlog格式选型
STATEMENT 省空间但有数据不一致风险;ROW 安全性最高、日志量大;MIXED 为折中方案。
3.日志差异
redo log 是引擎层物理日志、循环覆盖写入;binlog 是服务层逻辑日志、追加写入。
4.两阶段提交
通过 Prepare + Commit 两阶段,保证 redo log 与 binlog 原子一致性,是 MySQL 事务与高可用的核心保障。




