弄懂事务的四大特性(ACID)
掌握 redo log、undo log、binlog 各自用途与流程
理解两阶段提交协议(2PC)
明白事务是如何保证一致性的
特性 | 含义 |
---|---|
原子性 A | 要么全做、要么全不做(靠 undo 实现) |
一致性 C | 数据始终从一个合法状态变到另一个合法状态 |
隔离性 I | 多个事务互不干扰(靠锁机制或MVCC) |
持久性 D | 提交后数据不会丢(靠 redo log 实现) |
日志类型 | 作用 | 属于谁? |
---|---|---|
undo log | 回滚前镜像(支持回滚/MVCC) | InnoDB 引擎级别 |
redo log | 崩溃重做(保证持久性) | InnoDB 引擎级别 |
binlog | 逻辑操作日志(主从同步) | MySQL Server 层 |
redo 是“重做”,undo 是“撤销”,binlog 是“记账”。
redo log 记录的是 “物理层面页的变化”,属于 InnoDB 私有。
修改数据时,先写 redo log buffer,再写磁盘
定期刷入 redo log 文件
系统崩溃后可用 redo log 重放已提交但未写入的数据页
ib_logfile0 / ib_logfile1(可循环使用)
undo log 用来 撤销未提交的数据,也用作 MVCC 快照来源。
每个事务会维护自己的 undo log
数据发生变更前,先写 undo log,再写数据
回滚事务时按 undo log 反向恢复数据
MVCC 的快照版本读取,也基于 undo log 中旧数据版本实现。
binlog 是 MySQL Server 层日志,记录逻辑 SQL 操作。
记录每条 SQL 的原始执行内容(如:UPDATE t SET age=1 WHERE id=2)
支持 ROW / STATEMENT / MIXED 模式
用于:主从复制、增量备份、审计恢复等
为了确保 binlog 和 redo log 一致,MySQL 使用“两阶段提交”方案。
1. 写 undo log(记录原值)
2. 写 redo log(prepare 状态)
3. 写 binlog
4. redo log 改为 commit 状态 → 事务正式提交
只写了 prepare,没写 binlog → 事务未提交,回滚
写了 binlog,但 redo 没 commit → 回滚
只有 redo commit + binlog 写入 才算提交成功
隔离级别 | 可能问题 | MySQL 默认 | 日志相关 |
---|---|---|---|
READ UNCOMMITTED | 脏读 | ❌ | 不需要 undo |
READ COMMITTED | 不可重复读 | ❌ | 需要 undo/MVCC |
REPEATABLE READ | 幻读 | ✅ | 需 MVCC + gap lock |
SERIALIZABLE | 性能最差 | ❌ | 全部加锁 |
默认 REPEATABLE READ = 快照读 + next-key lock 保证一致性
-- 开启 binlog
SHOW VARIABLES LIKE 'log_bin';
-- 查看 binlog 文件
SHOW BINARY LOGS;
-- 查看内容(需 mysqlbinlog 工具)
mysqlbinlog binlog.000001 | less
redo log 和 binlog 有什么不同?
✅ redo 是物理日志,binlog 是逻辑 SQL
为什么需要两阶段提交?
✅ 为了保证 redo + binlog 一致性
快照读用的日志是哪一个?
✅ undo log(历史版本)
事务回滚靠什么?
✅ undo log
[事务开始]
↓
修改数据 → 记录 undo(撤销)
→ 记录 redo(物理页变更)
→ 写 binlog(逻辑操作)
↓
两阶段提交
1. redo prepare
2. 写 binlog
3. redo commit
↓
[事务提交完成]
下一章我们将进入 第7章:性能诊断与慢SQL分析,包括:
如何用慢查询日志 / performance_schema 定位瓶颈
SQL 执行耗时分布
实战慢SQL改写演练