redo log是innodb引擎特有的物理日志,用于崩溃恢复;binlog是mysql server层的逻辑日志,用于主从复制和时间点恢复。两者归属层级、记录内容、写入方式及用途均不同。

redo log 是 InnoDB 自己的日志,binlog 是 MySQL Server 层的日志
这是最根本的归属差异。如果你用的是 MyISAM 引擎,redo log 根本不存在;但只要启用了 log_bin,无论什么引擎,binlog 都会记录(哪怕只是空转)。InnoDB 在事务提交时必须依赖 redo log 保证崩溃可恢复,而 binlog 对它来说是“外部日志”,只在两阶段提交中被协调写入。
redo log 记页修改,binlog 记语句或行变更
redo log 是物理日志:比如“在 0x123456 地址的数据页上,把偏移 0x80 处的 4 字节从 5 改成 10”。它不关心 SQL 逻辑,只管磁盘页怎么变。binlog 是逻辑日志(取决于格式):STATEMENT 格式记 UPDATE t SET a=10 WHERE id=5;ROW 格式记“id=5 这行旧值是什么、新值是什么”。这意味着:binlog 可用于跨引擎回放或审计,redo log 只能被 InnoDB 自己解析。
redo log 循环覆盖,binlog 持续追加
redo log 文件组大小固定(默认 4×48MB 或 4×1GB),写满就从头覆盖,靠 checkpoint 推进擦除位置;binlog 默认无限追加,文件名按序号递增(mysql-bin.000001、mysql-bin.000002…),旧文件需手动 PURGE BINARY LOGS 或配置 expire_logs_days 才会清理。这个差异直接决定它们的用途:redo log 只支撑 crash recovery,binlog 支撑主从复制和 PITR(时间点恢复)。
两阶段提交里,innodb_flush_log_at_trx_commit 和 sync_binlog 必须配对调
事务提交时,InnoDB 先写 redo log 到 prepare 状态,Server 层再写 binlog,最后 InnoDB 把 redo log 改为 commit 状态——这就是两阶段提交(2PC)。如果只调高 innodb_flush_log_at_trx_commit=1 却把 sync_binlog=0,MySQL 崩溃后可能已提交事务在 binlog 里丢失,导致主从不一致或恢复失败。常见生产配置是两者都设为 1,牺牲一点性能换强一致性;若选 innodb_flush_log_at_trx_commit=2,至少得配 sync_binlog=1,否则风险更大。
真正容易被忽略的不是“它们有什么区别”,而是:当你要做主从切换、时间点恢复或迁移数据时,redo log 完全没用——它只存在于本地 InnoDB 实例里,不传输、不归档;所有跨实例操作都只认 binlog。反过来,单纯看崩溃恢复能力,binlog 再全也没用,它不参与 crash-safe 流程。











