一、初识 SHOW FULL PROCESSLIST;
:它是什么?看什么?
SHOW FULL PROCESSLIST;
是MySQL提供的一个命令,用于显示当前所有活跃的MySQL服务器线程(每个客户端连接通常对应一个服务器线程)。执行此命令需要用户拥有 PROCESS
权限;如果没有此权限,你只能看到自己当前连接的线程。
当你执行 SHOW FULL PROCESSLIST;
后,会看到类似下面这样的表格输出:
+-------+--------+---------------------+--------+---------+------+-----------------------------------+----------------------------------+
| Id | User | Host | db | Command | Time | State | Info |
+-------+--------+---------------------+--------+---------+------+-----------------------------------+----------------------------------+
| 101 | root | localhost | myapp | Query | 0 | starting | SHOW FULL PROCESSLIST |
| 102 | appusr | 192.168.1.10:12345 | myapp | Sleep | 15 | | NULL |
| 103 | appusr | 192.168.1.11:54321 | myapp | Query | 35 | Sending data | SELECT * FROM large_table WHERE... |
| 104 | repl | slave.example.com | NULL | Binlog | 3600 | Master has sent all binlog to slave | NULL |
| 105 | event | localhost | mysql | Daemon | 7200 | Waiting for next activation | NULL |
+-------+--------+---------------------+--------+---------+------+-----------------------------------+----------------------------------+
我们来逐列解析这些信息的含义:
-
Id
(连接ID):- 一个唯一的数字,用于标识这个服务器线程/客户端连接。当你需要
KILL
掉某个有问题的连接时,就会用到这个ID。
- 一个唯一的数字,用于标识这个服务器线程/客户端连接。当你需要
-
User
(用户名):- 发起这个连接的MySQL用户名。通过它可以知道是哪个应用或用户产生的连接。
-
Host
(主机名/IP):- 客户端连接的来源主机名或IP地址及端口。这有助于判断请求的来源。
-
db
(当前数据库):- 该连接当前默认使用的数据库。如果为
NULL
,则表示没有选择默认数据库。
- 该连接当前默认使用的数据库。如果为
-
Command
(命令类型):- 线程当前正在执行的命令类型。常见的有:
Query
: 线程正在执行一个SQL查询。Sleep
: 线程处于空闲状态,等待客户端发送新的命令。Connect
: 客户端正在连接到服务器。Execute
: 线程正在执行一个预处理语句 (Prepared Statement)。Binlog Dump
: 主库线程正在向从库发送二进制日志。Table Dump
: 线程正在发送表内容给从库。Daemon
: 服务器内部的守护线程(如事件调度器线程)。Kill
: 线程正在杀死另一个线程。
- 线程当前正在执行的命令类型。常见的有:
-
Time
(状态持续时间):- 线程处于当前
State
的持续时间,单位是秒。这个值非常关键! 如果一个Query
状态的线程Time
值非常大,那它很可能就是一个慢查询。如果一个Sleep
状态的线程Time
值很大,可能意味着应用没有正确关闭连接或连接池配置不当。
- 线程处于当前
-
State
(线程状态):- 描述线程当前正在做什么。这是排查问题时信息量最大、最需要仔细解读的列之一。常见的状态有很多,这里列举一些重要的:
Locked
: 线程正在等待获取表级锁(通常在MyISAM表或显式LOCK TABLES
时出现)。如果大量线程处于此状态,说明存在严重的锁竞争。Sending data
: 线程正在处理查询结果并将其发送给客户端。如果结果集非常大,或者网络慢,这个状态可能持续较长时间。Copying to tmp table
,Copying to tmp table on disk
: 查询需要创建内部临时表来处理。如果显示on disk
,说明内存中的临时表不够大,数据被转存到磁盘,性能会急剧下降。Creating sort index
,Sorting result
: 查询正在进行排序操作。Executing
: 线程正在积极执行查询。query end
: 查询执行刚刚结束。Waiting for table metadata lock
: 线程正在等待获取元数据锁(通常在DDL操作、表结构变更、或某些特定查询如OPTIMIZE TABLE
时发生,会阻塞对该表的其他操作)。User sleep
: 线程调用了SELECT SLEEP()
函数。- (还有很多InnoDB相关的状态,如等待Buffer Pool的 latch、等待I/O完成等,需要结合
SHOW ENGINE INNODB STATUS;
分析)
- 描述线程当前正在做什么。这是排查问题时信息量最大、最需要仔细解读的列之一。常见的状态有很多,这里列举一些重要的:
-
Info
(执行信息):- 如果线程正在执行查询 (
Command
为Query
或Execute
),这里会显示完整的SQL语句。如果线程处于其他状态,通常为NULL
。 - 注意:
SHOW PROCESSLIST;
(不带FULL
) 只会显示Info
字段的前100个字符,而SHOW FULL PROCESSLIST;
会显示完整的SQL语句,这对于分析长SQL或复杂SQL至关重要。
- 如果线程正在执行查询 (
二、SHOW FULL PROCESSLIST;
实战应用场景
了解了各列含义后,我们来看看在实际工作中如何运用它:
场景一:揪出“龟速慢查询”
- 现象: 应用响应慢,用户投诉。
- 操作: 执行
SHOW FULL PROCESSLIST;
。 - 关注: 寻找
Command
为Query
且Time
值异常大的线程。 - 分析:
Info
列会显示这条慢SQL的具体内容。拿到SQL后,下一步通常是使用EXPLAIN <SQL语句>;
来分析其执行计划,找出性能瓶颈(如未使用索引、全表扫描等)并进行优化。
场景二:诊断“卡死”与锁等待
- 现象: 应用部分功能无响应,或者出现大量请求超时。
- 操作: 执行
SHOW FULL PROCESSLIST;
。 - 关注:
State
列是否大量出现Locked
、Waiting for table metadata lock
、Waiting for table flush
或其他与锁相关的状态。- 这些线程的
Info
列显示它们想执行什么操作,Time
列显示它们等了多久。
- 分析: 这表明可能存在严重的锁竞争或死锁。对于InnoDB表,需要进一步结合
SHOW ENGINE INNODB STATUS;
来查看详细的锁信息和最近的死锁日志。
场景三:监控连接数与连接状态
- 操作: 定期执行
SHOW FULL PROCESSLIST;
(或通过脚本/监控工具)。 - 关注:
- 结果的总行数,即当前的总连接数。是否接近MySQL配置的
max_connections
上限? Command
列的分布。是否有大量的Sleep
状态连接?它们的Time
值是否很大?User
和Host
列,看看连接主要来自哪些应用服务器或用户。是否有未知的或非预期的连接来源?
- 结果的总行数,即当前的总连接数。是否接近MySQL配置的
- 分析: 大量长时间处于
Sleep
状态的连接可能意味着应用没有正确关闭数据库连接,或者连接池配置不当(如idleTimeout
设置过大或未生效)。过多的连接会消耗MySQL服务器资源。
场景四:识别“僵尸”连接或长时间运行的非查询操作
- 除了长时间
Sleep
的连接,Command
列为Binlog Dump
(主从复制)、Connect
(主库等待从库连接)、或某些内部维护操作的线程,如果其Time
值异常大,也可能指示相应的功能(如复制、事件调度)出现了问题。
三、使用 SHOW FULL PROCESSLIST;
的技巧与注意事项
- 权限: 执行此命令需要
PROCESS
权限。否则,你只能看到自己创建的线程。 - 瞬时性: 它显示的是执行命令那一刻的快照。对于执行速度非常快的问题查询或一闪而过的状态,可能难以捕捉。因此,多次执行、间隔采样,或者结合慢查询日志 (Slow Query Log) 进行历史分析通常更有效。
- 输出解读:
State
列的值非常多,含义各异。遇到不常见的状态,务必查阅MySQL官方文档以准确理解。 - 性能影响: 在一个连接数极多、并发极高的MySQL服务器上频繁执行
SHOW FULL PROCESSLIST;
理论上会有一点点开销(因为它需要收集所有线程的信息),但通常这种开销是可以接受的,远小于它带来的诊断价值。 - 替代与补充:
information_schema.PROCESSLIST
表: 可以通过SQL查询此表,获取与SHOW FULL PROCESSLIST;
类似的信息,好处是可以用WHERE
,ORDER BY
等子句进行更灵活的过滤和排序。- Performance Schema: 提供了更细致、更底层的性能监控数据,但配置和使用也更复杂。
- MySQL Workbench 或其他图形化工具: 通常也提供了类似
PROCESSLIST
的可视化界面。
总结
SHOW FULL PROCESSLIST;
无疑是MySQL管理员和开发者诊断线上问题时最先想到的、也是最直接有效的工具之一。它像一面“照妖镜”,能让我们迅速看清MySQL服务器当前的工作状态,找出那些“行为异常”的连接和查询。
当然,它不是万能的。对于历史问题分析,我们需要依赖慢查询日志、错误日志;对于InnoDB的复杂锁问题和死锁,SHOW ENGINE INNODB STATUS;
提供了更深层的信息;对于SQL本身的执行效率,EXPLAIN
才是解剖刀。
但无论如何,熟练掌握 SHOW FULL PROCESSLIST;
的使用和输出解读,是你排查MySQL问题、保障数据库稳定运行的必备技能。下次遇到MySQL“发脾气”,不妨先让它“SHOW”一下,看看它到底在忙些什么!
Comments NOTHING