Skip to content

P27 binlog 和 redo log 缺一不可? ​

面试题:MySQL 里已经有了 redo log,为什么还需要 binlog?两者缺一不可吗?

答案:缺一不可,二者职责不同 ​

对比项redo logbinlog
所在层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 负责主从复制与恢复归档(逻辑、追加写),二者通过两阶段提交保证一致,缺一不可。

基于 VitePress 重建