日志系统
hardMySQLredo logundo logbinlog两阶段提交
MySQL 三大日志
| 日志 | 层面 | 类型 | 作用 |
|---|---|---|---|
| redo log | InnoDB 引擎 | 物理日志 | 崩溃恢复(保证持久性) |
| undo log | InnoDB 引擎 | 逻辑日志 | 事务回滚 + MVCC |
| binlog | Server 层 | 逻辑日志 | 主从复制 + 数据恢复 |
redo log vs binlog
| 对比 | redo log | binlog |
|---|---|---|
| 归属 | InnoDB 独有 | Server 层(所有引擎) |
| 内容 | 物理修改(哪个页、哪个偏移改了什么) | 逻辑操作(SQL 语句或行变更) |
| 写入方式 | 循环写(固定大小,写满擦除) | 追加写(文件满了开新文件) |
| 用途 | 崩溃恢复 | 主从复制、数据恢复 |
redo log 的循环写
┌────────┬────────┬────────┬────────┐
│ file 0 │ file 1 │ file 2 │ file 3 │
└────────┴────────┴────────┴────────┘
↑ checkpoint ↑ write pos
│ (已刷盘位置) │ (当前写入位置)
│ │
└── 可擦除区域 ────────────┘ ← 可写入区域
write pos 追上 checkpoint → 需要暂停写入,先刷脏页推进 checkpoint
两阶段提交
为保证 redo log 和 binlog 的一致性,InnoDB 使用两阶段提交(2PC):
1. prepare 阶段: 写 redo log(状态为 prepare)
2. 写 binlog
3. commit 阶段: 将 redo log 状态改为 commit
崩溃恢复:
- redo log prepare + binlog 完整 → 提交事务
- redo log prepare + binlog 不完整 → 回滚事务
- redo log commit → 已提交
如果没有两阶段提交,redo log 和 binlog 可能不一致,导致主从数据不一致。
生产高频题
MySQL 为什么需要两阶段提交?
redo log 和 binlog 是两个独立的日志系统。如果不用 2PC,先写 redo 再写 binlog 时崩溃,主库通过 redo log 恢复了数据,但从库没有对应的 binlog → 主从不一致。两阶段提交保证了两个日志的一致性。