NiceOffer

八股文解析

MySQL InnoDB 的 redo log 和 undo log 有什么区别?

MySQLInnoDB八股文数据库

redo log vs undo log

一句话结论

  • redo log:崩溃恢复用,保证已提交事务的持久性(WAL 机制)
  • undo log:回滚与 MVCC 用,保证事务原子性一致性读

面试标准答法

redo log

InnoDB 采用 WAL(Write-Ahead Logging):页修改先写 redo,刷盘后再异步刷数据页。崩溃重启时通过 redo 重放未落盘修改。

关键点:

  • 循环写、固定大小(ib_logfile0 / ib_logfile1
  • innodb_flush_log_at_trx_commit 控制刷盘策略:
  • 0:每秒刷盘,性能最好,崩溃可能丢 1 秒数据
  • 1:每次提交刷盘,最安全,默认推荐
  • 2:每次提交写 OS cache,依赖 OS 刷盘

undo log

记录数据修改前的旧版本,用于:

  1. 事务回滚ROLLBACK 时通过 undo 链恢复旧值
  2. MVCC 一致性读Read View + undo 链构造历史快照

崩溃恢复流程(redo 角度)

  1. 事务提交:写 redo log buffer → 刷盘
  2. 数据页异步刷盘
  3. 崩溃重启:扫描 redo,重放未落盘修改
  4. 通过 undo 回滚未提交事务

常见追问

追问要点
redo 和 binlog 区别?redo 是 InnoDB 层崩溃恢复;binlog 是 Server 层主从复制/归档
为什么需要两阶段提交?prepare → binlog → commit,保证 redo 与 binlog 逻辑一致
undo log 会无限增长吗?不会,purge 线程会清理不再被任何 Read View 引用的 undo
MVCC 是怎么用 undo 的?每行隐藏列 DB_TRX_ID + DB_ROLL_PTR 指向 undo 链,Read View 判断可见性

面试回答模板(30 秒版)

延伸准备

  • 能画出 update 语句执行时 redo / undo / binlog 的写入顺序
  • 能解释 innodb_flush_log_at_trx_commit=1sync_binlog=1 的「双 1 配置」
  • 能结合 RR 隔离级别说明 undo 链如何支撑一致性读