应直接查 information_schema.innodb_trx 而非 show processlist,因后者无法反映事务真实状态,易漏掉持锁的 sleep 连接;innodb_trx 提供 trx_started、trx_state 和 trx_mysql_thread_id 等关键字段,可精准定位阻塞源与事务生命周期。

直接查 INFORMATION_SCHEMA.INNODB_TRX,别只看 SHOW PROCESSLIST——后者根本看不到事务真实状态,容易漏掉真正卡住的 Sleep 连接。
为什么 SHOW PROCESSLIST 会漏掉阻塞源
很多“挂起”的长事务在 PROCESSLIST 里显示为 Command = 'Sleep'、State = NULL、Time 值很大(比如 1200 秒),但 Info 为空。这类连接往往已执行 BEGIN 却没 COMMIT 或 ROLLBACK,事务锁从那一刻就持有了,而 PROCESSLIST 不反映事务级状态。
更关键的是:INFORMATION_SCHEMA.INNODB_TRX 才记录事务实际开始时间(TRX_STARTED)、状态(TRX_STATE)和对应线程 ID(TRX_MYSQL_THREAD_ID)。一个连接可能复用多次,PROCESSLIST.ID 和 INNODB_TRX.TRX_MYSQL_THREAD_ID 并不总一致;必须靠后者定位事务归属。
- 云数据库(如阿里云 RDS)常屏蔽
PROCESSLIST全量视图,但INNODB_TRX一般仍可查(需SUPER或CONNECTION_ADMIN权限) -
TRX_STATE = 'RUNNING'但TRX_OPERATION_STATE停留在'starting index read',哪怕才 3 秒也值得怀疑 -
TRX_ROWS_LOCKED > 1000或TRX_WAITING_TRX_ID IS NOT NULL是强阻塞信号
怎么算“长时间”:别硬套固定秒数
运行时长不是看 PROCESSLIST.Time 字段,而是用 TIMESTAMPDIFF(SECOND, TRX_STARTED, NOW()) 算真实持续时间。阈值要按场景调:
- OLTP 系统建议预警线设为 5 秒,干预线设为 60 秒
- 若事务刚启动但
TRX_STATE = 'LOCK WAIT',说明它已在等锁,不管秒数多短都得优先处理 - 配合
TRX_WAIT_STARTED(来自INNODB_TRX)比单纯看TRX_STARTED更准,因后者是事务开始时间,前者才是锁等待起点
如何精准定位阻塞源头 SQL
单靠 INNODB_TRX.TRX_QUERY 常为空(尤其 Sleep 连接),得关联 PERFORMANCE_SCHEMA 找最近执行语句:
- 先查出可疑
TRX_MYSQL_THREAD_ID,再查performance_schema.threads得到THREAD_ID - 用该
THREAD_ID去performance_schema.events_statements_history拉最近 10 条语句,ORDER BY EVENT_ID DESC - 重点看
SQL_TEXT中是否含SELECT ... FOR UPDATE、UPDATE、DELETE等加锁操作,以及是否缺少COMMIT上下文 - 注意:如果应用用了连接池(如 HikariCP),同一线程 ID 可能复用多次,
events_statements_history的EVENT_NAME为statement/sql/commit或rollback才算真正结束
杀之前必须确认阻塞链关系
别一上来就 KILL,先确认它是不是真在阻塞别人:
- 用
INNODB_LOCK_WAITS关联INNODB_TRX查完整阻塞链:waiting_trx_id→blocking_trx_id→ 对应TRX_MYSQL_THREAD_ID - 执行
KILL QUERY <code>thread_id:对 Sleep 连接虽无实际效果,但能试探该连接是否真空闲;若它其实正在执行慢查询,这一步就能中断语句、提前释放 MDL 锁 - 等 10–20 秒,再查
INNODB_TRX是否还存在该事务;若仍在,再执行KILL CONNECTION <code>thread_id - 特别注意:
KILL CONNECTION会触发连接池重连,若并发高且未限流,可能引发雪崩
最麻烦的其实是那种事务已异常退出但 MySQL 还没清理干净的状态——TRX_STATE 显示 'ACTIVE',TRX_STARTED 是几小时前,TRX_QUERY 为空,TRX_WAITING_TRX_ID 也为空。这种只能靠 KILL CONNECTION 强制收口,但得确保应用层有重试兜底。











