MySQL Undo Log 深度解析:表空间、MVCC、回滚机制与版本演进全解

引言

作为 InnoDB 存储引擎的核心组件之一,Undo Log(撤销日志) 是事务执行、回滚、多版本并发控制(MVCC)的基石。它与 Redo Log、Binlog 一起构成 MySQL 事务的三大日志体系,分别负责不同方向的保障:Undo 回滚、Redo 崩溃恢复、Binlog 主从复制与归档

本篇文章从存储结构到工作原理,从事务执行到版本演进,为你彻底讲清 Undo Log 完整机制。

一、InnoDB 表空间:Undo Log 的家在哪里

什么是表空间(Tablespace)

InnoDB 把所有数据、索引、Undo Log 等都放在"表空间"里。表空间本质是一个逻辑存储结构,用于将物理文件组织成可管理的存储单元。

InnoDB 中常用的表空间类型:

类型 说明
System Tablespace(共享表空间) 默认在 ibdata1 中,早期版本 Undo Log 全在这里
File-Per-Table Tablespace(独立表空间) 每个表一个 .ibd 文件
Undo Tablespace(独立 Undo 表空间) 5.6+,将 Undo Log 从共享空间中分离出来
Temporary Tablespace 存储临时数据

共享表空间(System Tablespace)

结构特点:

  • 默认文件:ibdata1

  • 存储内容:

  • Undo Log(旧版)

  • Data Dictionary

  • Doublewrite Buffer

  • Change Buffer

  • 部分索引数据

优点

  • 统一管理,结构简单
  • Undo Log 可以复用,节省管理成本

缺点

  • 文件永不缩小(历史性痛点)
  • 所有表数据混在一个大文件里,迁移不便
  • Undo Log 导致空间膨胀难清理

独立表空间(File-Per-Table)

每个表一个 .ibd 文件,结构更清晰。

优点

  • 删除表时空间可回收
  • 表迁移、备份更灵活
  • 更利于 SSD 的顺序写和扩展

缺点

  • Undo Log 仍可能在共享表空间中(5.6 之前)
  • 文件数量多,维护成本提升

独立 Undo 表空间(Undo Tablespace) ------ 事务写入的全新归宿

MySQL 5.6 后,Undo Log 移到独立的 undo_001undo_002 等文件中。

优势:

  • Undo 页可以独立回收
  • 降低共享表空间膨胀
  • Undo 存储更高效

二、Undo Log 的作用:回滚与 MVCC 的基础

Undo Log 是一类 逻辑日志,记录的是数据修改之前的"旧值"。

Undo Log 两大核心能力:

① 事务回滚

示例:

sql 复制代码
UPDATE account SET balance = balance - 100 WHERE id = 1;

假设原 balance = 500。

Undo Log 会记录:

sql 复制代码
(undo record)
table: account
id=1
balance = 500

如果事务回滚,用该记录恢复数据即可。

② MVCC(多版本并发控制)实现的关键

MVCC 依赖 Undo Log 与隐藏列:

隐藏列 含义
trx_id 本行被哪个事务修改
roll_pointer 指向 Undo Log 的指针

查询时根据版本链判断行的可见性。

假设对一个行进行了三次修改:

sql 复制代码
最新版本(data3)
    ↑ roll_pointer
data2
    ↑ roll_pointer
data1(最旧)

每个版本存储在 Undo Log 中,每个查询根据事务级别读取不同版本。

三、Undo Log vs Redo Log vs Binlog:三者区别一文看懂

Undo Log 与 Redo Log 区别

对比项 Undo Log Redo Log
作用 回滚行记录、MVCC 数据页崩溃恢复
记录内容 数据修改前的旧值 数据修改后的物理变化
格式 逻辑日志 物理日志
写入时机 数据修改时生成 Buffer Pool 脏页产生时生成

一句话总结:

Undo 负责撤销,Redo 负责重做。

Redo+Binlog 能否替代 Undo Log?

不能。

原因如下:

① Binlog 只用于主从复制与归档

  • Binlog 是逻辑日志
  • 不记录行版本
  • 无法支持 MVCC
  • 无法撤销未提交事务

② Redo Log 不记录旧值

  • Redo 记录页物理变化
  • 不能回滚数据
  • 只能确保数据不丢(崩溃恢复)

因此 Undo Log 是不可替代的。

Binlog 三种格式区别

格式 优点 缺点
STATEMENT 体积小 难以重现执行环境
ROW 精确记录每行变化 文件巨大
MIXED 折中模式 实现复杂

Binlog 主要用于:

  • 主从复制
  • PITR 时间点恢复
  • 审计与数据归档

四、Undo Log 的物理结构与写入过程

Undo Log 属于 Undo Space 中的段(Segment),包含两类记录:

类型 说明
Insert Undo Log Insert 事务提交后即可清除
Update Undo Log 删除或更新记录的旧版本,用于 MVCC

Undo Log 写入流程(配合 MVCC)

假设执行:

sql 复制代码
UPDATE user SET age = 20 WHERE id=1;

流程如下:

  • 生成 Undo 记录(旧值)

  • 将 Undo 记录写入 Undo Page

  • Data Page 写入新值(Buffer Pool)

  • Redo Log 记录物理变化

  • 提交事务后

  • Insert Undo 可立即清理

  • Update Undo 在无事务使用后由 Purge Thread 清除

五、事务回滚机制:如何恢复旧值

回滚操作过程如下:

  • 事务遇到 ROLLBACK 或发生异常
  • 获取 Undo Log 版本链
  • 按链表顺序倒序恢复每条记录
  • Redo Log 会记录 Undo 操作(保证 crash-safe)
  • 事务失败结束

Undo 与 Redo 是双向联动保证一致性的。

六、Undo Log 堆积问题:为什么空间越来越大?

Undo Log 堆积主要源于:

① 长事务

某个事务长时间未提交,旧版本无法被清理。

② Purge Thread 太慢

磁盘 IO 高、系统繁忙导致清理不及时。

③ 大量读取历史版本

MVCC 查询导致版本被引用无法删除。

解决方案

  • 关闭长事务
  • 确保自动提交
  • 优化 Purge
  • MySQL 8.0 后 Undo 表空间支持 truncate 回收空间

七、MySQL 各版本 Undo Log 演进

MySQL 5.5 及以前

  • Undo 全部在共享表空间
  • 无法回收空间
  • 容易膨胀

MySQL 5.6

  • 引入独立 Undo 表空间
  • 支持回收 Undo

MySQL 5.7

  • 多 Undo Tablespace
  • Undo 自动 purge 更智能

MySQL 8.0

  • Undo 支持 truncate
  • Undo 重做机制优化
  • 根本改善长事务导致空间膨胀的问题

总结

Undo Log 的关键作用:

作用 说明
回滚能力 让事务具有"撤销"功能
MVCC 实现 快照读必须依赖 Undo
事务隔离级别保证 Repeatable Read 离不开版本链
逻辑日志 记录的是"旧值"

Undo 在整个 MySQL 体系中不可替代。

Redo 负责让数据不丢,

Binlog 负责让数据能复制,
Undo 负责让事务可回滚、多版本可读取

三者共同组成了 MySQL 事务引擎的铁三角。

相关推荐
leoufung1 小时前
LeetCode 433:Minimum Genetic Mutation 题目理解与 BFS 思路详解
数据库·leetcode·宽度优先
张3蜂1 小时前
SQL Server 数据库 的通信加密配置SSL安全连接
数据库·安全·ssl
卿雪1 小时前
Redis 数据过期删除和内存淘汰策略
数据库·redis·缓存
by__csdn1 小时前
第一章 (ASP.NET Core入门)第二节( 认识ASP.NET Core)
数据库·后端·c#·asp.net·.net·.netcore·f#
爬山算法2 小时前
Redis(170)如何使用Redis实现分布式限流?
数据库·redis·分布式
JavaBoy_XJ2 小时前
Redis在 Spring Boot 项目中的完整配置指南
数据库·spring boot·redis·redis配置
KG_LLM图谱增强大模型2 小时前
SciDaSynth:基于大语言模型的科学文献交互式结构化数据提取系统
数据库·人工智能·大模型·知识图谱
凌盛羽2 小时前
用Python非常流行的openpyxl库对Excel(.xlsx格式)文件进行创建、读取、写入、显示等操作
数据库·python·链表·excel
前端小咸鱼一条2 小时前
antdv下拉框树的封装(可懒加载,可级联下级,可单独勾选,可禁用,可搜索)
前端·数据库