purge 是 InnoDB 延迟物理删除的必要环节,通过 coordinator 与 worker 线程协作,依据 history list 和最老 ReadView 判断并清理不再需要的旧版本数据。
你执行了 DELETE 或 UPDATE,数据“不见了”,但磁盘没缩、history list length 却在涨——这不是异常,而是 InnoDB 的 purge 机制正在按规则工作。它不立即删,而是在确保安全后才物理清理旧版本数据。
InnoDB 为支持 MVCC 和事务回滚,不会在事务提交时立刻擦除旧数据:
delete-marked 标记,行仍留在 B+ 树页中;关键依据是事务可见性规则:
SHOW ENGINE INNODB STATUS 中的 History list length 查看;m_low_limit_no)
;trx_id 的 undo 记录,才确认不再被任何现存事务读取,可进入清理队列。
MySQL 5.7.8+ 默认启用多线程 purge 架构:
srv_purge_coordinator_thread):负责扫描 history list、构建 purge 队列、按表分组、分发任务;innodb_purge_threads - 1 个 worker threads(srv_worker_thread):实际执行索引项清理、undo page 回收、B+ 树节点合并等操作;以下参数直接影响清理是否及时、空间能否复用:
innodb_purge_threads:默认 4,适合多表并发 DML;若业务集中在少数大表,可适当调低(如设为 2),减少锁竞争;innodb_purge_batch_size:默认 300,控制每次清理的 undo page 数量;增大可加快空间回收,但可能加剧 IO/CPU 波动,一般无需调整;History list length 持续 > 10000 或单日增长超 5000,通常是 purge 跟不上或存在长事务(包括只读事务),需检查 information_schema.INNODB_TRX;innodb_max_purge_lag 不建议启用(默认 0),人工限流易引发 DML 延迟雪崩,应优先优化事务生命周期。