
1. 为什么你需要关注MySQL的processlist第一次接触MySQL性能优化时我盯着满屏的慢查询日志手足无措。直到一位前辈告诉我先看看processlist那里藏着数据库的实时心电图。这句话彻底改变了我排查问题的思路。processlist就像MySQL的实时监控大屏它能告诉你当前所有连接在做什么STATE每个操作持续了多久TIME具体执行的SQL内容INFO连接来源和用户HOST/USER我遇到过最典型的案例是某电商平台大促时数据库突然卡死。通过processlist发现大量Sending data状态的连接TIME值都超过30秒。最终定位到是一个未加索引的商品搜索接口被疯狂调用。加上索引后响应时间从30秒降到30毫秒。2. 两种查看processlist的方法对比2.1 基础命令show processlist新手最常用的方式登录MySQL后直接输入SHOW PROCESSLIST;或者查看完整SQLSHOW FULL PROCESSLIST;优点是简单直接但缺点也很明显INFO字段默认只显示前100字符长SQL会被截断无法按字段过滤排序输出格式固定不利于自动化分析2.2 进阶方案查询information_schema.processlist这是我强烈推荐的方式SELECT * FROM information_schema.processlist;它的优势在于完整显示SQL内容无截断支持WHERE条件过滤可以配合ORDER BY排序方便与其他系统表关联查询实际工作中我常用这样的组合查询SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, LEFT(INFO, 200) AS SQL片段 FROM information_schema.processlist WHERE TIME 5 -- 只查耗时长的 ORDER BY TIME DESC;3. 关键字段实战解析手册3.1 STATE与TIME的死亡组合这两个字段必须放在一起看。就像医生既要看症状STATE也要看病程时长TIME。以下是我整理的高危组合清单STATE值TIME阈值危险等级典型问题Sending data3秒★★★★全表扫描/无索引Sorting result5秒★★★☆排序缓冲区不足Copying to tmp10秒★★★★内存表转磁盘临时表Waiting for...30秒★★☆☆锁等待/资源竞争NULL60秒★☆☆☆连接泄漏上周刚处理过一个案例STATE显示Creating sort indexTIME持续8秒。检查发现是用户导出的Excel报表查询排序字段没加索引。加上索引后导出速度从15秒降到0.3秒。3.2 COMMAND字段的隐藏信息很多人以为这是SQL命令类型其实它表示连接状态。常见值包括Sleep空闲连接。注意TIME过长的可能是连接池泄漏Query正在执行查询。重点关注其STATE和TIMEBinlog Dump主从复制线程。TIME为负数是正常现象Killed已被终止的连接。大量出现可能预示杀连接太频繁曾有个客户系统每天凌晨卡顿发现大量Sleep连接TIME超过8小时。原来是应用服务器重启时没正确关闭数据库连接。4. 高效查询技巧与自动化监控4.1 快速定位问题SQL的查询模板这是我用了5年的黄金查询SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, LEFT(INFO, 300) AS SQL片段, CONCAT(KILL , ID, ;) AS 终止命令 FROM information_schema.processlist WHERE TIME 5 AND COMMAND ! Sleep AND STATE NOT IN (Waiting for table metadata lock, NULL) ORDER BY TIME DESC LIMIT 10;这个查询会自动过滤掉空闲连接排除某些正常等待状态按耗时降序排列生成KILL命令方便应急处理4.2 自动化监控方案对于重要系统建议设置定时任务每分钟收集processlist快照#!/bin/bash LOG_FILE/var/log/mysql_processlist.log echo $(date) $LOG_FILE mysql -uroot -p密码 -e SELECT ID,USER,HOST,DB, COMMAND,TIME,STATE, LEFT(INFO,200) AS SQL FROM information_schema.processlist WHERE TIME 10 ORDER BY TIME DESC $LOG_FILE然后配合简单的监控脚本当发现危险状态时触发告警# monitor.py import re def check_dangerous_states(log_file): danger_patterns [ (rSending data.*TIME 30, 严重全表扫描), (rCopying to tmp table.*TIME 60, 超大临时表), (rWaiting for table metadata lock.*TIME 120, 元数据锁阻塞) ] with open(log_file) as f: logs f.read() for pattern, msg in danger_patterns: if re.search(pattern, logs): send_alert(f发现{msg}{pattern}) def send_alert(message): # 实现邮件/短信告警逻辑 print(f[ALERT] {message})5. 真实案例复盘一次惊心动魄的故障排查去年双11前夜某电商数据库突然响应变慢。通过processlist发现有30多个连接STATE为Waiting for table metadata lockTIME普遍超过60秒INFO显示都是商品表操作最终定位到原因凌晨的统计报表脚本执行了ALTER TABLE添加列锁住了整张表。而白天流量激增时所有商品查询都在等待这个锁。解决方案立即KILL掉ALTER操作用了之前生成的终止命令将DDL操作改到低峰期执行后续所有表结构变更必须通过pt-online-schema-change工具这次经历让我深刻理解processlist不仅是诊断工具更是数据库的生命体征监护仪。现在我的团队有个规矩——所有性能问题排查第一步永远是看processlist。