SHOW FULL PROCESSLIST 是快速定位现行慢查询的首选方法,需关注Time>5、Command='Query'、State状态,配合information_schema.processlist查完整SQL;KILL前须确认权限与影响;pt-kill需显式加--kill或--kill-query,并配置过滤与日志;终止后必须分析EXPLAIN、索引及慢日志根源。

直接用 SHOW FULL PROCESSLIST 抓现行慢线程
系统突然卡顿、CPU飙升时,SHOW FULL PROCESSLIST 是最快定位“正在吃资源”的慢查询的方式——它不依赖日志配置,执行即见结果,但要求账号有 PROCESS 权限。
重点关注三列:Time(当前状态持续秒数)、Command(值为 Query 才是真正在跑 SQL)、State(如 sending data、Sorting result、Updating 表示确实在干活)。若 Time > 5 且 Command = 'Query',基本可判定为需干预的慢线程。
别只看 Info 字段全貌:长 SQL 可能被截断,建议用 LEFT(info, 500) 配合 information_schema.processlist 查询更可靠:
SELECT id, user, host, db, time, state, LEFT(info, 500) AS sql_text FROM information_schema.processlist WHERE command = 'Query' AND time > 5 AND info IS NOT NULL ORDER BY time DESC;
杀线程前必须确认权限和影响范围
执行 KILL [id] 不是所有账号都能干成的事。MySQL 8.0+ 要求账号同时具备 PROCESS 和 CONNECTION_ADMIN 权限;5.7 及以前则需 PROCESS + SUPER。用 root 临时操作可以绕过,但生产环境应建专用账号:
CREATE USER 'killer'@'localhost' IDENTIFIED BY 'xxx';GRANT PROCESS, CONNECTION_ADMIN ON *.* TO 'killer'@'localhost';FLUSH PRIVILEGES;
误杀风险很高:复制线程(Binlog Dump)、心跳检测(pt-heartbeat)、监控连接(monitor 用户)一旦被 KILL,可能引发主从延迟或告警风暴。所以查到线程 ID 后,先人工核对 User、Host、db 和 Info 是否属于业务应用。
用 pt-kill 实现自动、可控的终止策略
pt-kill 不是开箱即用的“一键杀”,默认只打印不执行——这是最常踩的坑。必须显式加 --kill 或 --kill-query 才真正生效:
-
--kill:干掉整个连接,适合无重试逻辑或已确认连接异常的场景 -
--kill-query:仅中断当前 SQL,连接保活,更适合带重试的应用
关键参数不能少:
-
--busy-time 30:只处理已执行超 30 秒的线程(单位秒) -
--ignore-command="Binlog Dump,Change master":排除复制相关线程 -
--ignore-user="monitor,backup,pt-heartbeat":避开运维工具账号 -
--match-command="Query"和--match-state="executing|Sending data":精准锁定真实业务查询 -
--interval 10:每 10 秒轮询一次,太密会加重主库压力 -
--log /var/log/pt-kill.log:所有操作必须落日志,否则故障回溯无依据
避免“杀完又来”:查根源比杀线程更重要
反复出现的慢查询,大概率不是孤立事件。线程被 KILL 后,如果对应 SQL 没优化,下次请求照旧触发。所以每次终止后必须立刻跟进:
- 用
EXPLAIN看执行计划,重点盯type(是否ALL全表扫描)、key(是否命中索引)、rows(扫描行数是否远超预期)、Extra(是否用临时表或文件排序) - 检查该 SQL 的
WHERE、JOIN、ORDER BY字段是否有合适索引,注意函数操作(如WHERE DATE(created_at) = '2026-09-01')会导致索引失效 - 确认
long_query_time设置是否合理(如设为1却忽略小数阈值需求),以及是否启用了log_queries_not_using_indexes辅助发现隐性低效查询
真正棘手的不是“怎么杀”,而是“为什么总要杀”。线程 ID 一变就丢,但 EXPLAIN 输出和慢日志里的 SQL 片段不会骗人——把它们存下来,才是排查闭环里最不能跳过的动作。


















