一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

如何定位MySQL中由于Undo Log页被锁定导致的CheckPoint延迟?

时间:2026-07-07 12:28:52 编辑:袖梨 来源:一聚教程网

Undo Log页被锁定本身不直接导致CheckPoint延迟,而是长事务阻塞purge线程,使undo记录无法清理,进而拖慢CheckPoint推进;确认依据是History list length > 10000且持续增长、PURGE PROCESSED停滞、Trx id counter与Purged up to差值扩大。

Undo Log页被锁定时CheckPoint为何延迟?

CheckPoint延迟本身不是直接由“Undo Log页被锁定”引起,而是因为InnoDB在推进CheckPoint时需刷脏页、回收undo log空间,而undo页若正被活跃事务(尤其是长事务)长期持有,会导致purge线程无法清理旧undo记录,进而阻塞CheckPoint推进——本质是undo log purge卡住,而非undo页“被锁”这一动作本身造成延迟。

如何确认是purge阻塞导致CheckPoint滞后?

关键看innodb_purge_laginnodb_purge_lag_history是否持续偏高,再结合SHOW ENGINE INNODB STATUSPURGE部分的输出:

  • History list length > 10000(尤其持续增长):说明undo log堆积严重,purge跟不上
  • PURGE PROCESSED数值长时间不更新或增速极低:purge线程停滞
  • Trx id counterPurged up to差值持续扩大:事务ID推进快但purge慢,undo空间无法复用

此时即使innodb_max_purge_lag设为0,CheckPoint也会因buffer pool中大量“逻辑上可刷但物理上不能丢”的undo相关脏页而变慢。

哪些操作会实质性锁定undo页并拖慢purge?

不是所有事务都影响purge,真正卡住的是那些让undo record无法被安全回收的事务:

  • 未提交的长事务(TRX_STATE = RUNNINGTRX_STARTED时间远早于当前)
  • 设置了极低innodb_lock_wait_timeout但应用层未正确处理回滚,导致事务悬停
  • 使用SELECT ... FOR UPDATEUPDATE后长时间不COMMITROLLBACK
  • 开启READ COMMITTED但未关闭autocommit,执行DML后忘记提交

注意:innodb_undo_log_truncate = ON在MySQL 8.0+默认启用,但仅当history list length足够小时才触发truncate;若purge卡死,truncate永远不会发生。

定位具体阻塞源的实操步骤

不要只查INNODB_TRX,要联动分析三张表:

  • 查最老活跃事务:SELECT * FROM information_schema.INNODB_TRX ORDER BY TRX_STARTED ASC LIMIT 1;
  • 查它持有的undo段:SELECT * FROM information_schema.INNODB_UNDO_LOGS WHERE TRX_ID = ?;(需从TRX_ID反查)
  • 查purge线程状态:SELECT * FROM performance_schema.threads WHERE NAME LIKE '%purge%';,确认PROCESSLIST_STATE是否为sleepingwaiting for undo log

若发现某个事务TRX_MYSQL_THREAD_ID对应的应用连接已断开但事务仍RUNNING,大概率是客户端异常退出未清理事务——这是线上最常见的purge阻塞根源。

真正难处理的不是“怎么查”,而是“查到后不敢KILL”:强行KILL一个正在写入大量undo的事务,会触发同步回滚,可能比让它自己跑完更慢。优先应联系业务确认该事务是否可中断,再决定是否KILL或等待其自然结束。

热门栏目