正在执行sql需同时满足command为query、state非sleep/init且info非null;info常因截断、权限不足、状态切换或预编译而缺失或不全;监控应优先用information_schema.processlist表查询,kill前须核对state并优先用kill query。

能直接看到,但默认只显示前 100 行、SQL 截断、且普通用户看不到别人在跑什么——别急着执行,先确认你看到的是真正在执行的 Query,不是 Sleep 或 Command 为其他值的线程。
SHOW PROCESSLIST 输出里哪些行才算“正在执行 SQL”
不是所有 SHOW PROCESSLIST 返回的行都代表 SQL 正在跑。关键要同时满足:
-
Command列必须是Query(排除Sleep、Binlog Dump、Daemon等) -
State列不能是Sleep或Init(Sending data、Copying to tmp table、Locked才算活跃执行中) -
Info字段有内容,且不为NULL(但注意:即使Info为空,也不代表没在执行,可能是权限或预编译导致)
为什么 INFO 经常不完整或显示 NULL
常见原因和应对方式:
- 默认截断:MySQL 对
Info字段长度限制约 100 字符,长 SQL 直接被砍掉 —— 改用SHOW FULL PROCESSLIST - 权限不足:普通用户没
PROCESS权限时,只能看到自己连接,其他线程的Info强制设为NULL—— 联系 DBA 授予GRANT PROCESS ON *.* TO 'user' - 状态已切换:SQL 执行完但连接没断开,
Command可能已变回Sleep,Info清空 —— 这时Time值仍可能很大,但不代表当前有 SQL 在跑 - 用了
PREPARE/EXECUTE:部分 MySQL 版本中,预编译语句不会回填实际 SQL 到Info—— 这种情况得查performance_schema.events_statements_current
用 INFORMATION_SCHEMA.PROCESSLIST 写监控脚本更靠谱
命令行适合临时看一眼,但写告警或轮询脚本必须用表查询,因为支持过滤、排序、字段可控:
- 查运行超 60 秒的真正在执行的 SQL:
SELECT ID, USER, HOST, DB, TIME, STATE, INFO FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND = 'Query' AND TIME > 60 AND INFO IS NOT NULL ORDER BY TIME DESC LIMIT 10 -
INFO IS NOT NULL不能换成INFO != '',空字符串和NULL是两回事 - 该表不包含被
KILL后还没退出的残留线程,也不记录已断开的连接 - 注意
TIME单位是秒,但它表示线程处于当前Command状态的时间,不是整条 SQL 的总耗时
KILL 前必须核对的三件事
误杀一个 ID 可能中断事务、丢数据、引发应用重连失败:
- 先查
State:如果是Committing或Locked,KILL会导致回滚;如果是Waiting for table metadata lock,得先找到持有 MDL 的线程再杀 - 优先用
KILL QUERY <code>ID,它只中断当前语句,保留连接,适合 Web 应用这类不想重建连接的场景 -
ID不是持久标识:MySQL 重启后重置,别存成配置项长期引用;每次操作前务必SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = <code>ID再确认一遍
真正卡住的 SQL 往往不在 PROCESSLIST 里露头——要么太快被快照错过,要么根本没进 Query 状态(比如卡在锁等待、网络传输、磁盘 I/O)。这时候得切到 performance_schema 查等待事件,或者打开慢日志抓原始记录。别只盯着 Info 字段看内容,State 和 Time 的组合才是判断依据。











