查看MySQL活跃连接与执行语句:SHOW PROCESSLIST命令详解
排查数据库问题时,一个高频场景是:“数据库当前正在执行什么?” 面对性能抖动或连接数飙升,快速定位活跃连接与执行中的语句,是DBA和开发者的必备技能。本文将系统梳理MySQL中查看连接状态的几种方法及其关键细节。 最直接、门槛最低的方法是使用SHOW PROCESSLIST命令。它无需特殊权限即可查
排查数据库问题时,一个高频场景是:“数据库当前正在执行什么?” 面对性能抖动或连接数飙升,快速定位活跃连接与执行中的语句,是DBA和开发者的必备技能。本文将系统梳理MySQL中查看连接状态的几种方法及其关键细节。

最直接、门槛最低的方法是使用SHOW PROCESSLIST命令。它无需特殊权限即可查看自身发起的连接和语句。但关键点在于:若需查看“全量”信息,特别是其他用户的操作,则必须拥有PROCESS或SUPER权限。权限不足将导致列表显示不完整。
SHOW PROCESSLIST 默认只显示100行且SQL被截断的原因
许多用户初次使用SHOW PROCESSLIST时会发现:输出仅限100行,且长SQL语句被截断。这其实是MySQL的“保护机制”。默认限制输出行数并对Info字段进行长度截断(通常约100字符),主要是为了防止命令行界面输出过多导致卡顿,或避免日志文件瞬间膨胀。
解决此问题的方法如下:
- 使用
SHOW FULL PROCESSLIST命令。添加FULL关键字后,Info字段将显示完整的SQL语句。 - 直接查询系统表。执行
SELECT * FROM information_schema.PROCESSLIST,此视图本身不会对内容进行截断(前提是字段值未超出MySQL行长度限制)。 - 若使用
FULL后仍无法看到完整内容,或Info字段显示为NULL,很可能因当前连接权限不足,无法查看其他用户的语句详情。此时可能需要结合INNODB_TRX.trx_query或应用层日志进行推断。
区分“正在执行SQL”与“仅挂起的空闲连接”
仅查看连接列表不够,关键需分辨哪些连接正在“工作”。需重点关注Command和State字段,必须结合分析,单独看任一字段易导致误判:
- 当
Command = 'Query'且State显示为'Sending data'、'Sorting result'、'Copying to tmp table'时,通常表示活跃查询正在执行。若Time字段大于60秒,基本可判定为慢查询。 - 同样是
Command = 'Query',但若State为'Locked'或'Waiting for table metadata lock',则说明SQL已发出但被“卡”在锁等待上。这并非执行慢,而是发生了阻塞。 Command = 'Sleep'表示连接处于空闲状态,等待新请求。但若其Time值非常大(如超过300秒),则需警惕,可能是应用程序未正确调用close()方法,或连接池发生泄漏。Command = 'Connect'通常表示连接刚建立,尚未发送任何语句,一般无需特别处理。
需注意一个细节:Time字段单位为秒,但它表示线程处于当前Command状态的时间,并非整条SQL的总耗时。例如,若一个事务中先后执行3条语句,Time仅从最后一条语句开始计时。
使用 information_schema.PROCESSLIST 进行过滤与统计更可靠
对于快速交互式排查,命令行查看较为方便。但若需编写监控脚本或规律性排查问题,直接查询information_schema.PROCESSLIST表更为可靠。其结构化输出支持精准的过滤、排序和聚合,例如:
- 查找所有正在执行且耗时超过60秒的非空闲连接:
SELECT ID, USER, HOST, DB, TIME, STATE, INFO FROM information_schema.PROCESSLIST WHERE COMMAND = 'Query' AND TIME > 60 - 统计当前活跃连接数(排除Sleep状态):
SELECT COUNT(*) FROM information_schema.PROCESSLIST WHERE COMMAND != 'Sleep' - 定位长时间Sleep连接的来源:
SELECT USER, HOST, COUNT(*) FROM information_schema.PROCESSLIST WHERE COMMAND = 'Sleep' AND TIME > 600 GROUP BY USER, HOST
需注意,此表本身无索引。在高并发环境下,频繁查询(如每秒轮询)可能对performance_schema造成轻微压力。但对于日常分钟级轮询或人工诊断,其性能开销完全可接受,足够稳定。不建议将其作为实时告警主通道,但用作定时快照或人工分析则非常合适。
KILL CONNECTION 与 KILL QUERY 的易混淆点
定位问题连接后,下一步可能是终止它。但KILL命令有两个选项,使用错误可能导致不同后果:
KILL CONNECTION [ID]:直接终止整个TCP连接。若连接中存在未提交的事务,将触发回滚操作,并在日志中记录Aborted connection。KILL QUERY [ID]:仅中断当前正在执行的那条语句,连接本身仍保持。若之前已开启事务(BEGIN)但尚未提交(COMMIT),则事务状态保持不变,后续可继续执行其他语句。
此处有几个常见“坑”:
- 误杀一个
Command = 'Sleep'的连接基本无效,因其本未执行任何操作。 - 误杀一个
State = 'Committing'的连接,则可能导致事务中断,甚至造成数据丢失。
因此,执行KILL操作前,良好的习惯是先使用SELECT * FROM information_schema.INNODB_TRX WHERE trx_mysql_thread_id = [ID]查看该连接的事务状态,避免在关键的数据提交阶段进行打断。
归根结底,查看连接状态的技术本身并不复杂。真正的难点在于,面对一长串列表和SQL片段时,如何做出准确判断:哪条该立即终止?哪条可再观察?哪条需联系业务方确认?毕竟,INFO字段中的SQL语句脱离业务上下文,无法直接判断其是否属于重试逻辑、补偿任务或重要数据导出脚本。这需要的不仅是命令,更是经验与对系统的整体理解。
