Skip to content

05.2 - Undo Log 详解

定位:Undo Log 是 InnoDB 原子性和 MVCC 的基础——记录数据的旧版本,支持回滚和历史版本读取 面试高频度:⭐⭐⭐⭐ 考查方式:Undo Log 与 MVCC 的关系、回滚过程、Purge 机制、8.0 中 Undo Log 的独立表空间


一、这是什么?为什么需要它?

是什么

Undo Log(回滚日志)记录的是数据修改前的旧版本。当事务回滚时,用 Undo Log 把数据恢复原状。当 MVCC 需要旧版本数据时,通过 Undo Log 版本链找到可见版本。

为什么需要 Undo Log?

两个核心用途:

  1. 事务回滚 —— 原子性保证:任何 DML 执行前,先记录旧值到 Undo Log。回滚时,从 Undo Log 中取出旧值恢复
  2. MVCC 快照读 —— 一致性非锁定读:通过 Undo Log 版本链找到事务应该看到的版本

核心 insight:Undo Log 解决的不是"写"的性能问题,而是"读的隔离性"和"写的原子性"问题。它本质上是一个"时光机"——让你可以读到数据的历史状态。


二、原理拆解

2.1 Undo Log 的类型

Undo Log
  ├── INSERT Undo Log
  │   记录插入行的主键
  │   回滚时: 根据主键 DELETE
  │   MVCC 不需要: INSERT 前的状态是"不存在",其他事务看不到
  │   因此: INSERT Undo Log 在事务提交后可以立即回收

  └── UPDATE Undo Log
      记录修改行的旧版本(所有被修改的列 + 主键)
      回滚时: 根据旧值恢复
      MVCC 需要: 其他事务可能需要读旧版本
      因此: UPDATE Undo Log 只在所有快照都不需要时回收

2.2 Undo Log 与 MVCC 版本链

详细参见 **MVCC 实现原理**。

当前行:     DB_TRX_ID=150, name='Tom', age=30

              │ DB_ROLL_PTR

Undo Log:   trx_id=120, name='Tom', age=25  ← UPDATE 产生的旧版本

              │ DB_ROLL_PTR

Undo Log:   trx_id=100, name='Tom', age=20  ← INSERT 产生的初始版本

2.3 Purge 机制

为什么需要 Purge? Undo Log 不能一直保留——会产生大量垃圾数据。

Purge 规则:

  • 事务提交后,其 Undo Log 可以清理
  • 但如果有其他事务的 Read View 还需要某个版本→保留
  • Purge 线程在后台持续运行,回收不再需要的 Undo Log
sql
-- 监控 Purge
SHOW ENGINE INNODB STATUS\G
-- 查看 HISTORY LIST LENGTH
-- 值越大 → 需要 Purge 的 Undo Log 越多
-- 如果持续增长 → Purge 跟不上事务提交速度 → 需要调优

2.4 8.0 中的 Undo Log 变化

版本Undo Log 存储特点
5.6 之前系统表空间 (ibdata1)无法收缩,ibdata1 无限膨胀
5.6 - 5.7可独立表空间 (undo_001, undo_002)可配置数量,但不可自动 truncate
8.0独立表空间,自动 truncateinnodb_undo_tablespaces,可自动收缩

三、面试视角

追问答案要点
Undo Log 的两个作用?事务回滚(原子性)+ MVCC 快照读(隔离性)
UPDATE Undo Log 和 INSERT Undo Log 的区别?INSERT 回滚时删除行即可,MVCC 不需要 INSERT 的旧版本;UPDATE 需要保留旧版本供 MVCC 读取
Undo Log 什么时候清理?Purge 线程回收,条件是所有活跃事务的 Read View 都不再需要该版本
Purge 跟不上怎么办?查看 HISTORY LIST LENGTH,调整 innodb_purge_threadsinnodb_max_purge_lag
Undo Log 在 8.0 中有什么改进?独立 undo 表空间,自动 truncate 回收空间,不再导致 ibdata1 无限膨胀

📚 相关链接

  • MVCC 详解:**MVCC实现原理**
  • Redo Log:**Redo Log**
  • 两阶段提交:**两阶段提交与崩溃恢复**
  • ← 返回 **日志系统索引**

Knowledge4J — Java 知识库