长事务与 history list length(purge 滞后)
MySQL性能命令
-- Undo records waiting for purge (millions = trouble)
SELECT NAME, COUNT AS history_list_length
FROM information_schema.INNODB_METRICS WHERE NAME = 'trx_rseg_history_len';
-- Oldest transactions, their owner and last SQL
SELECT trx.trx_id, trx.trx_mysql_thread_id AS conn_id, trx.trx_state,
TIMESTAMPDIFF(SECOND, trx.trx_started, NOW()) AS age_sec,
trx.trx_rows_modified, trx.trx_rows_locked, trx.trx_isolation_level,
p.USER, p.HOST, p.COMMAND, p.TIME AS state_sec,
LEFT(COALESCE(trx.trx_query, esc.SQL_TEXT), 80) AS current_or_last_sql
FROM information_schema.INNODB_TRX trx
JOIN performance_schema.processlist p ON p.ID = trx.trx_mysql_thread_id
LEFT JOIN performance_schema.threads th ON th.PROCESSLIST_ID = trx.trx_mysql_thread_id
LEFT JOIN performance_schema.events_statements_current esc ON esc.THREAD_ID = th.THREAD_ID
ORDER BY trx.trx_started
LIMIT 10;作用
显示 purge 落后多少(history list length)以及拖住它的最老事务:所有者、持续时间、修改行数和最后执行的 SQL。
适用场景
undo 表空间增长、相同查询随时间变慢(扫描旧行版本)或出现磁盘空间告警时。
注意
最常见的原因是持有打开事务的 Sleep 会话,或在 REPEATABLE READ 下被遗忘的一致性快照(如被丢弃的 mysqldump/报表)。KILL 之后,回滚耗时与该事务修改的行数相当;终止 trx_rows_modified 很高的事务意味着漫长且 IO 密集的回滚,重启也无法缩短。purge 追上后 undo 会自动截断(innodb_undo_log_truncate=ON)。