可通过information_schema.processlist查长时间运行会话,需super或connection_admin权限;常用过滤条件为time>60且command!='sleep';注意info截断、state含义及kill与kill query区别;云数据库常屏蔽该视图,应使用控制台功能。

怎么查出哪些 MySQL 会话在长时间运行
直接看 information_schema.PROCESSLIST 或用 SHOW PROCESSLIST,但默认只显示当前用户会话;想看全部,得有 SUPER 或 CONNECTION_ADMIN 权限。实际中更常用的是带过滤的查询,比如找运行超 60 秒的:
SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO FROM information_schema.PROCESSLIST WHERE TIME > 60 AND COMMAND != 'Sleep';
注意 TIME 字段单位是秒,且从命令开始执行起算——对 Query 类型有效,但对 Sleep 是空闲时间,别误杀。
-
INFO可能被截断(默认 1024 字符),关键 SQL 看不全,可临时设max_allowed_packet加大,但不推荐长期调 - 某些云数据库(如阿里云 RDS、腾讯云 CDB)屏蔽了
PROCESSLIST全量视图,只能通过控制台“慢日志”或“实时会话”页查看,权限受限时别硬查 -
STATE为Locked或Sending data不一定代表异常,得结合INFO和业务逻辑判断
kill 命令到底该用 kill 还是 kill QUERY
KILL 默认终止整个连接(包括后续可能的新查询),KILL QUERY 只中断当前正在执行的语句,连接保持打开。选哪个,取决于你是否想保留应用层的连接复用。
- 应用用了连接池(如 HikariCP、Druid),突然
KILL会导致连接失效,池子可能报Communications link failure,下次取连接还得重连 - 执行 DDL(如
ALTER TABLE)时,KILL QUERY通常无效,MySQL 会忽略,必须用KILL - MySQL 5.7+ 支持
KILL CONNECTION(等价于KILL)和KILL QUERY,语法更明确,建议优先用这两个写法
示例:
KILL QUERY 12345;
KILL CONNECTION 12345;
kill 后为什么进程还在列表里没消失
常见原因不是命令没生效,而是 MySQL 正在清理资源:比如事务回滚、释放锁、刷脏页。尤其大事务回滚可能卡住几十秒甚至几分钟,STATE 会变成 Killed 或 Rolling back。
- 查
INFORMATION_SCHEMA.INNODB_TRX确认是否真在回滚:TRX_STATE = 'ROLLING BACK'且TRX_STARTED时间很早,说明回滚中 - 强行重启 mysqld 能立刻清掉,但可能导致数据不一致,生产环境严禁这么做
- 如果
STATE长期卡在Locked或Waiting for table metadata lock,大概率是其他会话持有 MDL 锁没释放,得一起查锁源
自动化 kill 的安全边界在哪
脚本或监控自动 kill 很危险,必须加至少两层防护:时间阈值 + SQL 类型白名单 + 手动确认开关。
- 别只按
TIME > 300就杀,有些报表查询本来就要跑 10 分钟,应结合COMMAND(如只杀Query,放过Daemon)、USER(避开运维账号)、DB(避开核心库)过滤 - 云数据库的只读实例上,
KILL可能被同步到主库触发意外中断,先确认实例角色 - MySQL 8.0.16+ 支持
SET SESSION max_execution_time = 30000控制单条语句超时,比事后 kill 更可控,但仅对 SELECT 生效
真正难的不是怎么 kill,是怎么区分「该杀的慢查询」和「不该动的核心任务」——这得靠业务语义,不是 SQL 能自动识别的。











