P27 binlog 和 redo log 缺一不可?
面试题:MySQL 里已经有了 redo log,为什么还需要 binlog?两者缺一不可吗?
答案:缺一不可,二者职责不同
| 对比项 | redo log | binlog |
|---|---|---|
| 所在层 | InnoDB 引擎层 | Server 层 |
| 日志类型 | 物理日志(页、偏移、修改值) | 逻辑日志(SQL/行变更) |
| 记录内容 | 数据页的物理修改 | 所有引擎共用的逻辑变更 |
| 写入时机 | 事务执行中边写边记 | 事务提交时写入 |
| 循环/追加 | 固定大小循环写(可覆盖) | 追加写,全量保留 |
| 主要用途 | 崩溃恢复(宕机不丢数据) | 主从复制、时间点恢复、审计 |
为什么缺一不可
只有 redo log 不行
- redo log 是循环覆盖的,只保证"最近"的崩溃恢复,存不下完整历史;
- redo log 是 InnoDB 私有的物理格式,无法用于主从复制(从库是另一套引擎/节点,需要逻辑变更);
- 无法做误删恢复、时间点回放。
只有 binlog 不行
- binlog 是逻辑日志,恢复时要重新执行,性能差、不够底层;
- 崩溃时内存脏页 + binlog 无法精确重建数据页状态,做不到高效的宕机恢复;
- 数据库重启时 InnoDB 恢复靠的是 redo log,而不是 binlog。
两者的配合:两阶段提交
事务提交时二者必须保持一致(要么都写了,要么都没写),否则崩溃后主从可能不一致:
text
① 写 redo log(prepare)
② 写 binlog
③ 写 redo log(commit)- 崩溃在 ② 前:事务回滚,两边都没有;
- 崩溃在 ② 后、③ 前:用 binlog 重做,保证主从一致。
加分点
- 追问"为什么当初不合并成一种日志":redo 归引擎管(物理、循环),binlog 归 Server 管(逻辑、归档),MySQL 是可插拔引擎架构,Server 层日志必须与引擎无关;
- 8.0 引入了 redo log 归档等增强,但两者分工的本质没变。
一句话总结
redo log 负责引擎级崩溃恢复(物理、循环写),binlog 负责主从复制与恢复归档(逻辑、追加写),二者通过两阶段提交保证一致,缺一不可。