1 事务执行流程
MySQL在事务的执行过程中,会记录相应SQL语句的Undo Log和Redo Log,然后在内存中更新数据并形成数据脏页。接下来Redo Log会根据一定的规则触发刷盘操作,Undo Log和数据脏页则通过检查点机制刷盘。事务提价时,会将当前事务相关的所有Redo Log刷盘,只有当前事务相关的所有Redo Log刷盘成功,事务才算提交成功
2 事务恢复流程
在事务提交之前,MySQL崩溃或者宕机,此时会先使用Redo Log恢复数据,然后使用Undo Log回滚数据。如果在事务提交之后,MySQL崩溃或者宕机,此时会使用Redo Log恢复数据
3 MySQL两阶段提交中binlog和redo log的作用
3.1 两阶段提交与日志协同的底层逻辑
MySQL 的两阶段提交(2PC)通过协调redo log和binlog的写入顺序,解决了事务在 "存储引擎层" 与 "服务层" 的一致性问题。其核心流程如下:
- 准备阶段(Prepare) :InnoDB 将事务写入 redo log 并标记为
PREPARE,此时事务未真正提交。 - 提交阶段(Commit) :先将事务写入 binlog,再将 redo log 标记为
COMMIT,完成提交。
3.2 redo log 的核心作用:保障事务原子性与持久性
3.2.1 事务原子性的实现
- 记录修改轨迹:redo log 记录数据页修改前的旧值(通过 undo 日志)和新值,确保事务可回滚或重做。
- 崩溃恢复基础:若数据库崩溃,重启时 InnoDB 通过 redo log 检查
PREPARE状态的事务:- 若 binlog 存在对应记录,则提交事务;
- 否则回滚事务(通过 undo 日志恢复数据)。
3.2.2 数据持久性的保障
- 当
innodb_flush_log_at_trx_commit=1(默认配置)时,redo log 在事务准备阶段会持久化到磁盘,确保事务不丢失。
3.3 binlog 的核心作用:保障集群一致性与可恢复性
3.3.1 主从复制的核心依赖
- binlog 记录所有数据库修改操作(如 SQL 语句、数据变更),主库将 binlog 发送给从库,从库重放 binlog 以保持数据同步。
- 在两阶段提交中,binlog 的写入是事务提交的最终确认,确保主从库的事务顺序一致。
3.3.2 时间点恢复(PITR)的关键
- 通过 binlog 可将数据库恢复到任意历史时间点(如误删表后通过 binlog 重做后续操作),前提是 binlog 完整记录了事务顺序。
3.3.3 跨引擎一致性的桥梁
- binlog 是 MySQL Server 层的日志,不依赖存储引擎(如 InnoDB、MyISAM),而 redo log 是 InnoDB 专属日志。两阶段提交通过 binlog 的写入状态,决定 InnoDB 事务的最终提交结果。
3.4 两阶段提交解决的核心问题:双日志一致性
若缺少两阶段提交机制,可能出现以下问题:
- 先写 binlog 后写 redo log:
- 若写完 binlog 后数据库崩溃,redo log 未记录事务,重启后事务丢失,但 binlog 存在该事务,导致主从复制时从库多执行无效事务。
- 先写 redo log 后写 binlog:
- 若写完 redo log 后崩溃,binlog 未记录事务,主库重启后事务存在,但从库无该事务,导致主从数据不一致。
3.4.1 两阶段提交的解决方案
- 通过
PREPARE状态将 redo log 与 binlog 的写入绑定,确保两者要么都完成,要么都回滚。
3.5 日志配置对两阶段提交的影响
| 配置项 | 作用 | 风险与性能平衡 |
|---|---|---|
innodb_flush_log_at_trx_commit | 控制 redo log 刷盘时机: 1= 每次提交刷盘(默认,最安全) 0= 每秒刷盘(可能丢失 1 秒内事务) | 性能开销:1 > 2 > 0,安全性反之 |
sync_binlog | 控制 binlog 刷盘时机: 1= 每次提交刷盘(默认,主从一致性最高) 0= 由 OS 控制(可能丢失 binlog) | 1会降低写入性能,但保障数据不丢失 |
3.6 典型场景:崩溃恢复中的日志协同
- 场景:事务在准备阶段后崩溃
- 状态:redo log 为
PREPARE,binlog 未写入。 - 恢复:InnoDB 检查 binlog 无对应记录,回滚事务。
- 状态:redo log 为
- 场景:事务在 binlog 写入后崩溃
- 状态:redo log 为
PREPARE,binlog 已写入。 - 恢复:InnoDB 确认 binlog 存在记录,将 redo log 标记为
COMMIT,提交事务。
- 状态:redo log 为
3.7 总结:redo log 与 binlog 的协同价值
- redo log:是 InnoDB 的 "本地账本",确保单个节点内事务的原子性和持久性。
- binlog:是 MySQL 的 "全局账本",确保集群环境下的主从一致性和可恢复性。
- 两阶段提交:通过协调两者的写入顺序,解决了分布式系统中 "跨日志一致性" 问题,是 MySQL 实现 ACID 特性的底层基石。