三类日志各司其职:binlog用于主从复制和逻辑恢复,redo log保障崩溃后数据不丢,undo log支持事务回滚和MVCC读一致性;二者协同依赖两阶段提交确保一致性。

三类日志各司其职,不能互相替代:binlog 用于主从复制和逻辑恢复,redo log 保障崩溃后数据不丢,undo log 支持事务回滚和 MVCC 读一致性。
binlog 是 Server 层的逻辑日志,只在事务提交后写入
binlog 记录的是 SQL 语句的原始逻辑(比如 UPDATE t SET v=2 WHERE id=1),不是物理页变更。它由 MySQL Server 层统一生成,跟存储引擎无关——哪怕你用 MyISAM,只要开启了 binlog 就会记录。
- 默认不开启,需手动配置
log_bin=ON并指定binlog_format(推荐ROW) - 刷盘策略由
sync_binlog控制:0表示只写 OS cache;1表示每次 commit 都fsync到磁盘(最安全,但有性能损耗);N表示每 N 次提交刷一次 - 主从复制依赖它:slave 通过拉取并重放 master 的 binlog 实现数据同步
- 无法单独用于 crash recovery —— 它没有 redo log 那种“前滚”能力,也不记录未提交事务
redo log 是 InnoDB 的物理日志,事务过程中持续写入
redo log 记录的是“某个表空间、某页、某偏移量上写了什么字节”,是物理层面的增量变更。它只属于 InnoDB,MyISAM 完全不感知。
- 文件名固定为
ib_logfile0、ib_logfile1,位于 MySQL 数据目录下 - 大小固定、循环写入:写满后从头覆盖,靠
checkpoint位置控制可覆写范围 - 刷盘时机由
innodb_flush_log_at_trx_commit决定:1(默认)表示 commit 时强制fsync;0或2会丢失最近最多 1 秒的事务 - 它是 crash-safe 的核心:MySQL 异常重启时,InnoDB 会重放 checkpoint 之后的 redo log,把 Buffer Pool 中未刷盘的脏页补回来
undo log 不是独立日志文件,而是存于共享表空间或独立 undo 表空间
undo log 存储的是“反向操作”,比如 insert 的 undo 是 delete,update 的 undo 是旧值。它不用于恢复崩溃,而是支撑事务原子性和 MVCC。
- 事务回滚时,InnoDB 用 undo log 把已修改但未提交的数据“倒回去”
- MVCC 读取快照时,会根据事务 ID 和 undo log 链找到对应版本的数据行
- 默认写入
ibdata1(系统表空间),可通过innodb_undo_directory指向独立路径,或启用innodb_undo_tablespaces拆分多个文件 - 长期不提交的大事务会让 undo log 持续保留,可能撑爆表空间或拖慢 purge 线程
真正容易被忽略的点在于:binlog 和 redo log 必须协同工作才能保证主从一致性和崩溃安全,这就是两阶段提交(2PC)的底层逻辑——只有两者都落盘成功,事务才算真正提交。漏掉任一环节,就可能出现主从数据不一致或重启后状态错乱。


















