mysql undo log核心作用是事务回滚和mvcc支持:记录旧值实现回滚,通过版本链提供快照读;物理上存于独立undo tablespace,分insert/update-delete两类,由purge线程异步清理;与redo log相比,前者保原子性/一致性、记逻辑前镜像、无需强制刷盘,后者保持久性、记物理页变更、提交时须刷盘。

MySQL undo log 是事务回滚和多版本并发控制(MVCC)的核心机制,面试中常围绕其作用、存储结构、生命周期、与 Redo Log 的区别、以及故障恢复中的角色展开。
undo log 的核心作用
主要解决两个关键问题:
- 事务回滚:当事务执行过程中发生错误或主动执行 ROLLBACK 时,undo log 记录了修改前的旧值,可用于将数据恢复到事务开始前的状态。
- MVCC 支持:在 READ COMMITTED 和 REPEATABLE READ 隔离级别下,InnoDB 利用 undo log 中的历史版本链(rollptr 指向旧版本),让不同事务看到各自“快照”下的数据,避免读写冲突。
undo log 的物理存储与组织方式
从 MySQL 5.6 开始,undo log 默认存于独立的 undo tablespace(如 undo_001、undo_002),而非系统表空间 ibdata1 中,便于管理与截断。
- 每个 undo log segment 属于一个 rollback segment,而每个 rollback segment 可支持 1024 个事务并发写入(由 TRX_RSEG_N_SLOTS 定义)。
- undo log 分为两类:INSERT undo log(仅用于回滚,事务提交后可立即清除)和 UPDATE/DELETE undo log(含历史版本,需保留至所有依赖它的事务结束才能清理)。
- 每条记录的聚集索引页中包含 DB_ROLL_PTR,指向该行最新 undo log 记录,形成版本链。
undo log 的生命周期与清理机制
不及时清理会导致 undo 表空间膨胀,甚至阻塞 purge 线程,影响性能。
- Purge 线程负责异步回收已无事务需要的历史 undo 日志。它依据 history list length(全局未清理 undo log 数量)和最老活跃事务(min_trx_id)判断哪些日志可删。
- 若长事务(如未提交的事务、大查询持有 read view)长期运行,会拖慢 purge 进度,导致 history list 堆积、undo 表空间持续增长。
- 可通过
SHOW ENGINE INNODB STATUS查看 HISTORY LIST LENGTH 和 TRANSACTIONS 部分,定位长事务。
undo log vs redo log:关键区别必须说清
这是高频对比题,核心差异在目的、内容、写入时机和持久化要求:
- 目的不同:undo log 保证事务原子性(回滚)和一致性(MVCC);redo log 保证事务持久性(崩溃恢复)。
- 内容不同:undo log 记录“逻辑前镜像”(如 SET c = 100 → SET c = 80);redo log 记录“物理页变更”(如 “page 5 offset 128 写入 0xABC…”)。
- 写入顺序:事务提交前,undo log 先写入(确保能回滚),再写 redo log(确保能重做),最后提交标记落盘(两阶段提交逻辑)。
- 是否需要刷盘:undo log 写入 buffer 即可(不强制刷盘),而 redo log 在事务提交时必须 fsync 到磁盘(受 innodb_flush_log_at_trx_commit 控制)。










