show processlist是 MySQL 排查慢查询、锁阻塞、连接异常的“手术刀”——它能实时展示当前 MySQL 所有连接的运行状态,核心价值是把抽象的“数据库卡顿”具象化为“具体的SQL/连接问题” 。
一、先懂基础:show processlist是什么?能解决什么问题? 1. 核心定位 show processlist是 MySQL 内置命令,用于实时查看当前所有客户端连接的执行状态 ,分为两种形式:
show processlist:显示前100条连接(精简版);show full processlist:显示所有连接,且Info字段展示完整SQL(排查慢查询必用)。2. 解决的核心问题 定位正在执行的慢查询 (比如卡死的SELECT/UPDATE); 排查锁阻塞 (比如某连接持有锁,导致其他连接等待); 识别异常连接 (比如大量 Sleep 连接占用资源、非法IP连接); 分析连接来源 (比如PHP应用的连接是否过多、是否有慢查询来自第三方工具)。 二、庖丁解牛:show processlist核心字段拆解(按重要性排序) 执行show full processlist后,返回结果包含12个核心字段,每个字段对应连接的关键状态,下面逐一拆解:
字段名 核心含义 慢查询排查重点 Id连接ID(唯一标识) 定位具体有问题的连接,可通过kill Id终止异常连接 User执行该连接的MySQL用户 区分应用用户(如php_app)、管理员用户(如root),定位慢查询来源主体 Host连接的客户端IP+端口(格式:IP:端口) 排查慢查询来自哪台应用服务器(如PHP服务器IP)、是否有非法IP连接 db当前连接操作的数据库名 定位慢查询发生在哪个业务库(如电商的shop_db、日志的log_db) Command连接当前执行的命令类型 核心!慢查询主要关注Query(执行SQL)、Sleep(空闲连接)、Locked(锁等待) Time该状态持续的时间(单位:秒) 核心!Time>10秒的Query基本是慢查询;Time>300秒的Sleep是空闲连接泄漏 State连接的具体执行状态(如Sending data、Waiting for table lock) 核心!精准判断慢查询卡在哪一步(如IO、锁、计算) Info连接正在执行的SQL语句(show full processlist才显示完整SQL) 核心!找到慢查询的具体SQL,是优化的直接依据
关键字段深度解析(慢查询排查核心) 1.Command字段:区分连接类型 Command值 含义 慢查询关联度 处理建议 Query正在执行SQL语句 ★★★★★ 重点看Time和State,判断是否为慢查询 Sleep空闲连接(无SQL执行) ★★ Time>300秒建议kill,或调整wait_timeoutLocked等待锁释放 ★★★★★ 找到持有锁的连接(Command=Query+State=Updating) Connect正在建立连接 ★ 大量出现需排查应用侧连接池配置 Binlog Dump主从复制的binlog同步 ★ 仅主库出现,Time长是正常的
2.State字段:精准定位慢查询卡点(高频值) State值 含义 慢查询原因分析 优化方向 Sending data正在向客户端返回查询结果(最常见) 要么SQL扫描数据多(无索引),要么IO慢 加索引、限制返回字段、优化SQL Waiting for table lock等待表级锁(MyISAM/InnoDB表锁) 有长事务更新表,导致查询等待锁 改用InnoDB(行锁)、缩短事务、优化更新SQL Waiting for row lock等待行级锁(InnoDB) 并发更新同一行数据(如秒杀扣库存) 减少行锁竞争、优化更新逻辑 Sorting result正在排序查询结果 SQL用了ORDER BY且无排序索引 加排序索引、避免大结果集排序 Creating tmp table创建临时表(内存/磁盘) SQL用了GROUP BY/JOIN导致临时表 优化JOIN逻辑、避免不必要的分组 Updating正在执行UPDATE语句 更新语句无索引,扫描行数多 加更新条件索引、缩小更新范围 Reading from net从客户端读取SQL(少见) 客户端发送SQL慢,或网络卡顿 排查客户端/网络
3.Time字段:判断慢查询阈值 经验阈值:Time>5秒的Query需关注,Time>10秒的必须优化; 极端情况:Time>300秒的Query大概率是全表扫描/死锁,建议先kill再优化。 三、实战拆解:用show processlist定位慢查询(从现象到根因) 场景1:定位单条慢查询(最常见) 步骤1:执行show full processlist,得到结果如下(简化版): Id User Host db Command Time State Info 1234 php_app 192.168.1.10 shop_db Query 25 Sending data SELECT * FROM goods WHERE title LIKE ‘%5G手机%’ AND is_deleted=0 1235 php_app 192.168.1.10 shop_db Sleep 180 NULL
步骤2:庖丁解牛式分析 核心问题 :Id=1234的连接,Command=Query、Time=25秒、State=Sending data,属于典型慢查询;根因定位 :Info中的SQL是SELECT * FROM goods WHERE title LIKE '%5G手机%'——%关键词%导致全表扫描,且无索引;影响判断 :该连接占用MySQL线程,且Sending data状态说明IO消耗大,会拖慢其他查询;临时处理 :若业务紧急,先kill 1234终止慢查询;长期优化 :给title字段加全文索引,或改用ES做模糊搜索。场景2:排查锁阻塞导致的慢查询 步骤1:执行show full processlist,结果如下: Id User Host db Command Time State Info 1456 php_app 192.168.1.10 shop_db Query 30 Waiting for row lock UPDATE goods SET stock=stock-1 WHERE id=1001 AND is_deleted=0 1457 php_app 192.168.1.10 shop_db Query 35 Updating UPDATE goods SET price=2999 WHERE id=1001 AND is_deleted=0
步骤2:庖丁解牛式分析 核心问题 :Id=1456的连接State=Waiting for row lock,等待Id=1457的连接释放行锁;根因定位 :两个连接同时更新goods表的同一行(id=1001),InnoDB行锁导致阻塞;影响判断 :Time=30秒说明阻塞已持续30秒,会导致后续更新该商品的请求全部排队;临时处理 :若1457的更新是长事务,kill 1457释放锁;长期优化 :缩短更新事务的执行时间,或加分布式锁避免并发更新同一行。场景3:排查空闲连接泄漏(PHP应用常见) 步骤1:执行show full processlist,发现大量如下连接: Id User Host db Command Time State Info 1501 php_app 192.168.1.10 shop_db Sleep 360 NULL 1502 php_app 192.168.1.10 shop_db Sleep 420 NULL … … … … … … … …
步骤2:庖丁解牛式分析 核心问题 :大量Command=Sleep且Time>300秒的连接,属于空闲连接泄漏;根因定位 :PHP应用未正确关闭数据库连接(如忘记$pdo = null),或连接池配置不合理;影响判断 :占用MySQL连接数,导致max_connections被占满,新请求无法建立连接;临时处理 :批量kill空闲连接(kill 1501; kill 1502;);长期优化 :调整MySQL参数:wait_timeout=60(空闲60秒断开)、interactive_timeout=60; PHP侧优化:请求结束时显式关闭连接,或使用连接池管理连接。 四、进阶技巧:show processlist高效使用方法 1. 过滤慢查询(只看关键连接) -- 筛选出执行时间>10秒的Query连接(慢查询) SELECT Id, User , Host, db, Time , State, InfoFROM INFORMATION_SCHEMA. PROCESSLISTWHERE Command= 'Query' AND Time > 10 AND InfoIS NOT NULL ; -- 筛选出锁等待的连接 SELECT Id, User , Host, db, Time , State, InfoFROM INFORMATION_SCHEMA. PROCESSLISTWHERE StateLIKE '%lock%' ; 2. 批量终止异常连接(PHP脚本实现) <?php // 连接MySQL $pdo = new PDO ( 'mysql:host=127.0.0.1;dbname=information_schema' , 'root' , 'your_password' ) ; // 筛选出Time>300秒的Sleep连接 $stmt = $pdo -> query ( "SELECT Id FROM PROCESSLIST WHERE Command = 'Sleep' AND Time > 300" ) ; $ids = $stmt -> fetchAll ( PDO :: FETCH_COLUMN , 0 ) ; // 批量kill foreach ( $ids as $id ) { $pdo -> exec ( "KILL{ $id } " ) ; echo "已终止空闲连接:{ $id } \n" ; } 3. 结合慢查询日志验证 show processlist只能看正在执行 的慢查询,已执行完的慢查询需结合慢查询日志:
# 查看慢查询日志 tail -f /var/log/mysql/slow.log# 用pt-query-digest分析慢查询(Percona工具) pt-query-digest /var/log/mysql/slow.log> slow_analysis.log五、避坑指南:show processlist使用误区 ❌ 混淆State和Command:Command=Query不代表慢查询,需结合Time和State判断; ❌ 忽略Host字段:同一IP大量慢查询,需优先排查该应用服务器的代码; ❌ 盲目kill连接:killBinlog Dump(主从复制)、Connect(正在建连接)等核心连接,会导致主从同步中断; ❌ 只看Info不看State:同样的SELECT * FROM goods,State=Sending data是IO问题,State=Sorting result是排序问题,优化方向完全不同。 总结 show processlist排查慢查询的核心逻辑:先看Command(是否Query)→ 再看Time(是否超时)→ 再看State(卡点在哪)→ 最后看Info(具体SQL) ;关键字段:Time(判断慢查询阈值)、State(定位卡点)、Info(找到优化对象); 高效使用技巧:过滤查询、批量处理异常连接、结合慢查询日志,实现“实时排查+事后分析”闭环。