innodb_undo_log_truncate=on仅是许可开关,真正自动截断需同时满足四个硬性条件:innodb_undo_tablespaces≥2、innodb_max_undo_log_size>0、至少一个undo表空间处于inactive/empty状态、purge线程持续推进使truncate_status变为truncate_ready。

innodb_undo_log_truncate 开启后会自动截断,但前提是满足四个硬性条件;报错如 ERROR 3655 (HY000) 或 xb_load_tablespaces() failed with error code 57 不是配置没开,而是状态卡在依赖未解除。
为什么Undo表空间会“自动”截断?
它不是真自动,而是由 innodb_purge_threads 推进逻辑清理 + 后台线程按频率触发物理动作。关键点在于:innodb_undo_log_truncate = ON 只是开关,真正启动截断需同时满足:
-
innodb_undo_tablespaces ≥ 2:必须有至少两个独立 undo 表空间(undo_001、undo_002),否则轮换机制无法成立 -
innodb_max_undo_log_size > 0:默认 1024MB,设为 0 或负值会直接禁用截断逻辑 - 至少一个 undo 表空间处于
inactive或empty状态:活跃事务未退出前,InnoDB 不敢动它 -
purge_trx_count持续下降:说明 purge 线程在推进,history list length 在收缩;否则TRUNCATE_STATUS永远卡在not_truncate_ready
ERROR 3655 (HY000):Cannot set undo tablespace inactive
这是最常被误读的报错——不是权限或语法问题,而是系统拒绝破坏最小可用性保障。MySQL 要求始终保留 ≥ 2 个 active undo 表空间,所以当你只有 undo_001 和 undo_002 时,执行 ALTER UNDO TABLESPACE undo_001 SET INACTIVE 就会失败。
- 先新增第三个:
CREATE UNDO TABLESPACE undo_003 ADD DATAFILE 'undo_003.ibu' - 再设旧的为 inactive:
ALTER UNDO TABLESPACE undo_001 SET INACTIVE - 查状态:
SELECT NAME, STATE FROM INFORMATION_SCHEMA.INNODB_TABLESPACES WHERE NAME LIKE 'undo%';,确认undo_001变成inactive - 等
STATE变为empty后,才能安全DROP UNDO TABLESPACE undo_001
xb_load_tablespaces() failed with error code 57
这个错误出现在 xtrabackup 备份时,本质是 MySQL 实例异常退出时,某个 undo 表空间正处于截断中途(文件已删但元数据未清),导致备份工具在只读恢复阶段无法重建表空间上下文。
- 不要尝试手动恢复
.ibu文件——InnoDB 已标记该 space ID 作废,强行还原会引发崩溃 - 正确做法:停机后 clean shutdown(确保
innodb_fast_shutdown = 1或= 0),再启动;若仍报错,需加innodb_force_recovery = 1启动,导出数据后重建实例 - 预防重点:避免在业务高峰期执行
ALTER UNDO TABLESPACE ... SET INACTIVE;8.0.21+ 版本可大幅降低此类风险,因截断不再强制刷 buffer pool
TRUNCATE_STATUS 是 ready,但磁盘空间不释放
状态就绪 ≠ 立即执行,也不等于立刻释放空间。物理截断受 innodb_undo_truncate_frequency 控制,默认每完成 128 次 purge 才尝试一次判定。如果 purge 进度慢,或者 innodb_purge_threads = 1 且负载高,可能数小时都看不到文件变小。
- 查 purge 进度:
SELECT * FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME IN ('purge_trx_count', 'purge_undo_log_bytes'); - 临时加速:
SET GLOBAL innodb_purge_threads = 4;(勿超过 CPU 核心数) - 调低频率:
SET GLOBAL innodb_undo_truncate_frequency = 32;,但注意太小会导致 I/O 毛刺 - 文件大小变化滞后是正常现象,观察
INFORMATION_SCHEMA.INNODB_TABLESPACES中FILE_SIZE字段比看磁盘更准
真正卡住截断的,从来不是开关有没有开,而是 XA PREPARED 事务残留、长空闲事务没 commit、或者 purge 线程被堵死——这些不会报错,但会让整个流程静默挂起。











