最快定位卡住sql应使用show full processlist,它轻量即时、无需配置,关键看time(秒)、state(如sending data)、info(完整sql),配合performance_schema可查更精准的实时执行细节。

直接看 SHOW FULL PROCESSLIST 最快定位卡住的SQL
执行时间超过 30 秒的 SQL 就该被怀疑了,SHOW FULL PROCESSLIST 是最轻量、最即时的判断手段。它不依赖配置开启,也不需要重启服务,只要能连上 MySQL 就能用。
关键字段别忽略:Time(已运行秒数)、State(当前状态,比如 Sending data 或 Copying to tmp table)、Info(实际执行的 SQL,注意只显示前 100 字符,所以加 FULL 很重要)。
- 如果
State长期卡在Waiting for table metadata lock,大概率是 DDL 操作被阻塞,得先查谁持有元数据锁 -
Command列为Query才代表真正在执行 SQL;大量Sleep状态说明应用连接没释放,会挤占连接数但不直接导致卡死 - 别只扫一眼就关掉终端——把输出重定向保存:
mysql -e "SHOW FULL PROCESSLIST" > processlist_$(date +%s).txt,方便后续比对
用 performance_schema 查正在跑的完整语句和耗时细节
MySQL 5.6+ 默认启用 performance_schema,它比 INFORMATION_SCHEMA.PROCESSLIST 更准、更全,尤其适合查“正在执行中但还没完成”的语句。注意:它只存内存,重启即丢,不能当历史日志用。
查当前活跃语句最常用的是:
SELECT thread_id, sql_text, timer_wait/1000000000000 AS time_sec FROM performance_schema.events_statements_current WHERE sql_text IS NOT NULL AND sql_text NOT LIKE 'SELECT %events_statements%';
-
timer_wait单位是皮秒,除以1000000000000才是秒,直接看数值容易误判 - 必须过滤掉自己查
performance_schema的语句,否则结果里全是监控语句本身 - 如果想看最近执行过哪些慢语句,查
events_statements_history_long表,但默认只保留 10000 条,高并发下可能被覆盖
别信 INFORMATION_SCHEMA.PROCESSLIST 的 Info 字段长度
INFORMATION_SCHEMA.PROCESSLIST 的 Info 列默认只存前 100 字符,且截断不带省略号。一个 SELECT ... JOIN ... WHERE ... GROUP BY ... HAVING ... ORDER BY ... LIMIT 的长查询,很可能只看到开头几个表名,根本看不出问题在哪。
-
SHOW FULL PROCESSLIST才真正返回完整 SQL,这是唯一不用改配置就能看到全貌的方式 - 想让
INFORMATION_SCHEMA也返回完整内容?不行——这个长度是编译时固定的,无法运行时调整 - 如果必须用 SQL 查询方式获取完整语句,只能走
performance_schema.events_statements_current,它默认存全部
监控不是目的,及时干预才能防卡死
发现一个跑了 120 秒的 UPDATE,光记录日志没用。你得立刻决定:是 KILL 它,还是让它继续?这取决于两点:事务是否可中断、数据一致性是否允许回滚。
-
KILL命令后,MySQL 不会立即终止,而是等语句执行到安全点(如完成一行更新)才退出,所以Time可能还会涨几秒 - MySQL 8.0.19+ 有个坑:
KILL QUERY对某些大事务可能无效,后台线程仍在运行,得用KILL CONNECTION强制断连 - 真正危险的是那些
State = 'Locked'或'Waiting for table flush'的语句——它们不光自己卡,还可能阻塞其他所有操作,优先处理
最易被忽略的一点:SHOW PROCESSLIST 和 performance_schema 都看不到“已经提交但尚未刷盘”的事务影响。这类长事务虽不显现在进程列表里,却持续占用 undo log 和锁资源,得靠 information_schema.INNODB_TRX 补充排查。











