bigywater.tech
MySQL / InnoDB · 60

Undo Tablespace

数一数本机真实有几个undo tablespace,用DDL动态新建再删除一个,再用500次真实小更新验证它的磁盘占用到底会不会随便涨。

2个→3个→2个
真实动态创建并删除一个undo tablespace
0字节增长
500次真实更新后undo文件大小完全没变

做的事:真实数一数本机现在有几个undo tablespace

代码SELECT SPACE, NAME, STATE, FILE_SIZE FROM information_schema.INNODB_TABLESPACES WHERE NAME LIKE '%undo%';

验证:真实默认的2个undo tablespace,各32MB

实测 · 本机information_schema.INNODB_TABLESPACES真实输出
SPACE         NAME              STATE    FILE_SIZE
4294967279    innodb_undo_001   active   33554432   (32MB)
4294967278    innodb_undo_002   active   33554432   (32MB)
实测 · 磁盘上真实存在的文件
$ ls -la /opt/homebrew/var/mysql/undo_*
-rw-r----- 1 w admin 33554432 undo_001
-rw-r----- 1 w admin 33554432 undo_002

这两个undo tablespace是InnoDB初始化数据目录时真实自动创建的,从MySQL 8.0开始不再需要靠innodb_undo_tablespaces参数手动指定数量——这个变量在真实的MySQL 26.7.0里查询会直接报"Unknown system variable",取而代之的是CREATE UNDO TABLESPACE/DROP UNDO TABLESPACE这套DDL语法,undo tablespace的数量真实变成了可以运行时动态增减的对象。

验证:真实用DDL新建一个,再真实删掉它

实测 · 本机执行输出
CREATE UNDO TABLESPACE undo_003 ADD DATAFILE 'undo_003.ibu';
→ 真实新增一行:SPACE=...277, NAME=undo_003, STATE=active, FILE_SIZE=16777216(16MB)
→ 磁盘上真实多了一个文件:undo_003.ibu,16MB

ALTER UNDO TABLESPACE undo_003 SET INACTIVE;
→ STATE真实变成 empty

DROP UNDO TABLESPACE undo_003;
→ 磁盘上的undo_003.ibu文件真实被删除

新建的这个undo tablespace初始大小是16MB,比默认的两个(32MB)小——这是两种不同的创建路径:默认的两个是数据目录初始化时按老的固定尺寸创建的,运行时用DDL新建的走的是另一套初始化逻辑。要删除一个undo tablespace,真实必须先用SET INACTIVE把它标记成不再接受新事务,等它内部真实的历史数据被purge线程清空之后,才能真实DROP掉——不能对一个还在被使用的undo tablespace直接删除。

验证:真实测500次小更新,undo文件大小纹丝不动

实测 · 本机执行输出
500次真实独立的UPDATE(各自单行、各自提交)之前:
  innodb_undo_001: 33554432   innodb_undo_002: 33554432
500次之后:
  innodb_undo_001: 33554432   innodb_undo_002: 33554432   ← 完全没变
这500次真实的更新完全没让undo文件长大一个字节——因为undo tablespace真实是预分配的,内部空间像一个循环使用的区域,一旦某段undo记录被purge线程真实清理完,这段空间就能被后面新的事务重新使用,不需要每次都向磁盘申请新的空间。只有当"尚未被purge的历史记录"真实持续堆积、超过已经预分配的容量时(本文《长事务如何阻塞Purge》验证过这种堆积真实会发生),undo tablespace才会真实向磁盘申请扩容,直到innodb_max_undo_log_size(本机默认1GB)这个阈值——本文出于对磁盘空间的真实顾虑,没有把测试推到这个规模去触发真实的扩容和之后的truncate回收,这一步如实标注为没有验证。

分步演示:undo tablespace的真实生命周期

每一步都是本文上面用真实DDL和information_schema跑出来的原始结果。

undo tablespace:真实可以动态增减,也真实不会随便长大
这一步新验证的状态

    本文用到的工具

    • 本机 MySQL 26.7.0(InnoDB),information_schema.INNODB_TABLESPACES、真实磁盘文件核对
    • CREATE/ALTER/DROP UNDO TABLESPACE:MySQL 8.0起真实支持的动态DDL
    • 没有验证:真实把undo tablespace推到innodb_max_undo_log_size(1GB)触发扩容和truncate的完整过程,出于对磁盘空间的顾虑没有测试这个规模
    京ICP备2026067502号-1京公网安备11010502063487号