pt-kill 默认仅打印不杀戮,需显式指定--kill或--kill-query参数并授予PROCESS+SUPER(MySQL 8.0+为CONNECTION_ADMIN)权限;须配合--ignore-command、--ignore-user等精准过滤,避免误杀复制或监控线程。

为什么 pt-kill 不是“开箱即用”的超时杀器
直接运行 pt-kill 默认不会杀任何查询——它默认只打印匹配的查询(--print 模式),不带 --kill 或 --kill-query 参数,就只是个只读观察者。很多用户配完规则发现慢查询还在跑,就是卡在这一步。
真正生效需要明确告诉它“要动手”,而且得确保它有足够权限去杀线程(PROCESS + SUPER 或 MySQL 8.0+ 的 CONNECTION_ADMIN)。
-
pt-kill --host=localhost --user=admin --password=xxx --busy-time 60 --kill:杀所有运行超 60 秒的连接(含 sleep 状态) -
pt-kill --host=localhost --user=admin --password=xxx --run-time 300 --interval 10 --busy-time 30 --kill-query:每 10 秒检查一次,杀掉已执行超 30 秒的查询(保留连接,只中断当前语句) - MySQL 8.0+ 注意:如果用的是角色权限模型,需确保该用户被授予
CONNECTION_ADMIN,否则KILL QUERY会报错Access denied; you need (at least one of) the CONNECTION_ADMIN privilege(s)
如何精准匹配“慢查询”而非误杀后台连接
默认 --busy-time 对所有非 Sleep 线程生效,但像 Binlog Dump、Replication_IO/SQL、Query Analytics 工具连接也常处于非 Sleep 状态,容易被误杀。必须加过滤条件。
- 排除复制线程:
--ignore-command="Binlog Dump,Change master,Start slave,Stop slave" - 排除特定用户:
--ignore-user="monitor,backup,pt-heartbeat" - 只杀 SELECT/UPDATE/DELETE(避开 SET/COMMIT/SHOW):
--match-command="Query" --match-state="executing|Sending data|Sorting result" - 更安全的做法是结合 SQL 模式过滤:
--match-info="^(SELECT|UPDATE|DELETE|INSERT)\b"(注意转义空格和词界)
守护进程化运行时的关键配置项
用 nohup 或 systemd 跑 pt-kill 时,--run-time 和 --interval 决定它的生命周期和灵敏度,设错会导致漏杀或 CPU 毛刺。
-
--run-time 3600:进程最多运行 1 小时,适合 cron 定期拉起;若想长期驻留,应省略此项 -
--interval 5:每 5 秒轮询一次INFORMATION_SCHEMA.PROCESSLIST,太小(如 1s)会加重主库压力,太大(如 30s)可能让慢查询多跑半分钟 - 务必加
--log /var/log/pt-kill.log,否则 kill 行为无迹可查;日志里会记录被杀线程 ID、SQL 片段、时间戳,排查误杀全靠它 - 避免与
pt-query-digest共用同一账号:后者只需SELECT权限,而pt-kill需高危权限,最小权限原则建议拆分账号
常见错误现象和对应解法
运行后没效果?或者疯狂 kill?先看这几类典型表现:
- 现象:
Cannot connect to P:3306—— 检查--port是否显式指定(尤其 Docker 或非标端口),pt-kill不读取my.cnf中的port - 现象:
Access denied for user ... (using password: YES)—— 密码含特殊字符(如$、!)未被 shell 转义,改用--password='xxx'单引号包裹 - 现象:杀掉了连接但应用报 “Lost connection to MySQL server during query” —— 这是预期行为;若应用无法重连,说明它没处理连接中断,不是
pt-kill的问题 - 现象:日志里大量
Skipping thread N: not matched—— 检查--match-*和--ignore-*规则是否过于严格,临时去掉所有匹配参数,只留--busy-time 10 --print看原始 processlist 输出再调
最易被忽略的是 MySQL 的 wait_timeout 和 interactive_timeout 值——它们控制空闲连接自动断开时间,和 pt-kill 的 --busy-time 无关,别混为一谈。

















