MySQL History List
MySQL History List
是 InnoDB 中所有回滚段(RSEG)的 TRX_RSEG_HISTORY 链表中的 Undo slot 总数
也称为purge lag
已提交但其 undo 记录尚未被 purge 的事务的加权计数,其中普通表操作计为 1,临时表操作额外计为 1
实验:
mysql> shutdown;
mysql> set global autocommit=0;
mysql> show engine innodb status\G
------------
TRANSACTIONS
------------
Trx id counter 52232
Purge done for trx's n:o < 0 undo n:o < 0 state: running but idle
History list length 0
#显示HLL的长度为0
------------事务需要两个update undo slot的时候-------------------
mysql> start transaction; #开启事务
Query OK, 0 rows affected (0.00 sec)
mysql> update test.large_data set age=20 where id=35555; #操作普通表
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> update temp_user set name='Alice11' where id=2; #操作临时表
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> commit;
Query OK, 0 rows affected
mysql> show engine innodb status\G
------------
TRANSACTIONS
------------
Trx id counter 52234
Purge done for trx's n:o < 52234 undo n:o < 0 state: running but idle
History list length 2
#显示HLL的长度为2
------------------事务只需要一个update undo slot的时候----------------
#此时的HLL为‘History list length 4’
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> UPDATE temp_user SET name = 'Bob3' WHERE id = 3;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
mysql> show engine innodb status\G
------------
TRANSACTIONS
------------
Trx id counter 52238
Purge done for trx's n:o < 52238 undo n:o < 0 state: running but idle
History list length 5
#HLL为5,符合预期。
监控原因
在写入繁重的数据库中,具有较大的历史列表长度可能需要将大量行的版本恢复为非常旧的版本。这将减慢事务本身的速度。对于长事务,读取成本就越高。拥有较大的 HLL 意味着撤消日志也会增加。
原因&解决
1、清除无法跟随大量写入
控制 InnoDB Purge 线程的清理速度,
避免因事务提交过快导致 History List Length(未清理的 undo logs)堆积过高,从而影响系统性能。
innodb_max_purge_lag(MySQL 5.7 和 8.0 均支持)
当 History List Length(HLL)超过 innodb_max_purge_lag 设定的阈值时,InnoDB 会主动延迟 DML 操作(INSERT/UPDATE/DELETE),以减缓新事务的提交速度,让 Purge 线程有机会追上。
- 默认值:0(不启用延迟)。
- 建议值:1000~10000(视业务负载调整)。
- 控制的是 purge 操作一次处理的 undo log page 数量,而不是 undo log records 数量
计算方式
InnoDB 会根据 HLL 和 innodb_max_purge_lag 计算出一个 延迟时间(毫秒):
delay= (HLL / innodb_max_purge_lag) ×10
如果:HLL = 5000,innodb_max_purge_lag = 1000:delay=(50001000)×10=50msdelay=(10005000)×10=50ms
此时,INSERT/UPDATE/DELETE 操作会额外增加 50ms 的延迟。
适用场景
- 高并发写入:防止事务提交过快导致 HLL 堆积。
- 长事务问题:如果某些事务长时间不提交,导致 HLL 增长,此参数可缓解问题。
innodb_max_purge_lag_delay(MySQL 8.0 新增)
作用
- 限制 innodb_max_purge_lag 计算出的最大延迟时间(避免极端情况下延迟过高)。
- 默认值:0(无限制)。
- 建议值:100~10000(单位:毫秒)。
示例
- 如果 innodb_max_purge_lag_delay = 100:
- 计算出的 delay = 200ms → 实际延迟 100ms(受上限约束)。
- 计算出的 delay = 50ms → 实际延迟 50ms(未超上限)。
适用场景
- 防止极端延迟:避免因 HLL 突然暴涨导致 DML 操作完全卡死。
- 更精细的控制:结合 innodb_max_purge_lag 使用,避免业务不可预测的延迟。
2、长时间运行查询
长时间运行的事务,即使是休眠/停滞的事务,都会阻塞清除,无论写入工作量如何,即使它非常低,HLL 将在该事务的整个生命周期内继续增长。解决此问题的唯一方法是停止那些长事务(提交、回滚、终止)。

浙公网安备 33010602011771号