应查innodb_trx表而非仅依赖show processlist,因sleep状态连接可能持锁未释放;执行select trx_id, trx_mysql_thread_id, trx_query, trx_state, trx_started, trx_rows_locked from information_schema.innodb_trx where trx_state in ('running','lock wait') and trx_started
查 INNODB_TRX 确认谁真正在持锁
别只看
SHOW PROCESSLIST里状态是Sleep就跳过——很多“僵死”连接就卡在这儿:事务没提交也没回滚,TRX_STATE却是RUNNING或LOCK WAIT,锁还牢牢占着。执行这个查询定位真正危险的事务:
SELECT trx_id, trx_mysql_thread_id, trx_query, trx_state, trx_started, trx_rows_locked FROM INFORMATION_SCHEMA.INNODB_TRX WHERE trx_state IN ('RUNNING','LOCK WAIT') AND trx_started- 重点盯
trx_query是否为空(空 = 卡在中间)、trx_rows_locked是否异常高(比如上万行)、trx_started时间是否远超业务预期(比如已运行 12 分钟)KILL CONNECTION 而不是 KILL QUERY
KILL QUERY <code>thread_id只停当前语句,连接不断,事务不回滚,锁照常持有——对阻塞问题完全无效,甚至会让等待链更难排查。KILL CONNECTION <code>thread_id(MySQL 5.7+ 推荐写法,等价于旧版KILL <code>thread_id)才会强制断连、触发事务回滚、释放所有锁。
- 执行后立刻查
SHOW PROCESSLIST,确认该 ID 消失;若状态变成Killed却卡住,说明正在回滚大事务,只能等- 严禁对
User = 'system user'(如复制线程)或你自己的当前连接执行KILL- 权限要求:需
PROCESS+SUPER(5.7+ 还要CONNECTION_ADMIN)别把 MDL 锁当行锁处理
有些“卡住”根本不是事务锁,而是元数据锁(
Waiting for table metadata lock),常见于 DDL 操作被未提交事务阻塞。这类锁不会出现在INNODB_TRX,得查:
SELECT blocking_pid, object_schema, object_name, operation FROM performance_schema.metadata_locks WHERE owner_thread_id IN ( SELECT thread_id FROM performance_schema.threads WHERE processlist_command ='Sleep' ) AND lock_status ='PENDING';- 如果
blocking_pid对应一个长时间Sleep的连接,它大概率就是源头——但不能直接KILL,先查它的INFO字段确认是否为业务事务,否则可能中断备份或监控自动清理机制不可靠,必须人工干预
wait_timeout和interactive_timeout只对Command = Sleep且无活跃事务的连接生效,对已启动事务但卡住的连接完全无效。默认 28800 秒(8 小时)在生产环境基本形同虚设。
- 真正的释放时机取决于事务回滚完成——小事务通常 100ms 内完成;大事务回滚时间 ≈ 正向操作耗时,期间锁持续存在
- 回滚不是瞬间动作,
KILL CONNECTION后看到Killed状态,不等于锁已释放,得等INNODB_TRX里对应记录消失才算真正干净












