mysql 8.0 的 undo 表空间文件(如 undo_001.ibu)不会因 innodb_undo_log_truncate=on 而缩小物理体积,该参数仅触发逻辑截断(重置 lsn、清空位图),操作系统层面文件大小不变;真正释放磁盘空间必须执行 drop undo tablespace,且前提为先 set inactive 并确保 purge 完成(history list length
MySQL 8.0 的 Undo 回滚段不会自动缩小文件体积,这是设计使然,不是配置错了或服务异常。你看到
undo_001.ibu占用 71GB 且du -h不变,不是 truncate 失败,而是它根本没打算删文件。为什么
innodb_undo_log_truncate=ON不释放磁盘空间这个参数只触发逻辑截断:重置 LSN、清空页分配位图、让新事务从头写入。操作系统层面的文件尺寸(
ls -lh)完全不变。
ALTER UNDO TABLESPACE undo_001 SET INACTIVE后,文件仍躺在原地,只是不再被新事务使用DROP UNDO TABLESPACE undo_001才会真正删除物理文件——但前提是它已处于INACTIVE状态且 purge 已完成- 错误日志里出现
[Note] InnoDB: Truncating tablespace ./undo/undo_001≠ 文件变小,只是内部结构重置如何确认 purge 是否跟上,才能安全
DROP别信变量值,看实时状态:
- 执行
SHOW ENGINE INNODB STATUS\G,搜索HISTORY LIST LENGTH—— 必须降到500以下(越低越稳)- 查表空间状态:
SELECT NAME, STATE FROM information_schema.FILES WHERE SPACE_TYPE = 'Undo',目标必须是INACTIVE- 再跑一次
SELECT trx_id, trx_started, trx_rows_modified FROM information_schema.INNODB_TRX,确保没有运行超 300 秒、修改行数 > 10000 的事务收缩失败最常见的三类操作陷阱
这些动作看似合理,实际无效甚至危险:
- 直接
rm -f /var/lib/mysql/undo_001.ibu:实例重启失败,报错Cannot find undo tablespace- 执行
ALTER TABLESPACE undo_001 ENGINE=InnoDB:语法合法但无任何效果,日志静默,文件大小纹丝不动- 只改
innodb_undo_directory不重启:新段落新路径,旧段仍卡在原目录,且无法迁移真正能回收磁盘空间的唯一路径
必须走“新增 → 切换 → 清理 → 删除”闭环,跳步必卡死:
- 先在
my.cnf加innodb_undo_tablespaces = 3,重启 mysqld(旧 undo 仍在原路径,新undo_003.ibu落到新目录)- 等
HISTORY LIST LENGTH下降后,执行ALTER UNDO TABLESPACE undo_001 INACTIVE- 等状态变
INACTIVE,再执行DROP UNDO TABLESPACE undo_001- 若需彻底释放空间,且业务允许停机:导出数据 → 初始化新实例(配好
innodb_undo_tablespaces = 2)→ 导入最易被忽略的一点:即使所有操作都对,
undo_001.ibu文件也不会自动消失——DROP命令才真正删它。别盯着truncate日志等空间回收,那是徒劳。












