MySQL查看当前连接数,show processlist
前言
MySQL连接数太多,报"Too many connections",怎么看当前有多少连接?哪些连接在跑什么SQL?用show processlist。
一、查看当前连接
基本命令
SHOW PROCESSLIST;
输出:
| Id | User | Host | db | Command | Time | State | Info |
|---|---|---|---|---|---|---|---|
| 123 | root | localhost:54321 | mydb | Query | 0 | starting | SHOW PROCESSLIST |
| 124 | www | 192.168.1.100:1234 | mydb | Sleep | 30 | NULL |
每列含义:
- Id:连接ID,kill的时候用
- User:用户名
- Host:客户端IP和端口
- db:当前数据库
- Command:当前命令(Query/Sleep/Connect)
- Time:当前状态持续时间(秒)
- State:状态
- Info:正在执行的SQL
显示完整SQL
SHOW FULL PROCESSLIST;
默认Info列只显示前100个字符,加FULL显示完整SQL。
二、查看连接数
当前连接数
SHOW STATUS LIKE 'Threads_connected';
最大连接数
SHOW VARIABLES LIKE 'max_connections';
历史最大连接数
SHOW STATUS LIKE 'Max_used_connections';
三、杀掉连接
杀掉某个连接
KILL 连接ID;
比如杀掉ID为123的连接:
KILL 123;
杀掉所有Sleep连接
-- 先查出来
SELECT CONCAT('KILL ', id, ';') FROM information_schema.processlist
WHERE user = 'www' AND command = 'Sleep';
把结果复制出来执行,就能批量杀掉。
四、常用查询
按用户统计连接数
SELECT user, COUNT(*) FROM information_schema.processlist
GROUP BY user;
按IP统计连接数
SELECT SUBSTRING_INDEX(host, ':', 1) AS ip, COUNT(*)
FROM information_schema.processlist
GROUP BY ip;
查看执行超过10秒的SQL
SELECT * FROM information_schema.processlist
WHERE time > 10;
五、调整最大连接数
临时调整
SET GLOBAL max_connections = 1000;
永久调整
改my.cnf:
[mysqld]
max_connections = 1000
重启MySQL生效。
常见坑
坑1:Sleep连接太多
大量Sleep连接占着连接数,导致新连接进不来。
原因: 程序没关连接,连接池没配好。
解决:
- 调小
wait_timeout,让空闲连接自动断开 - 检查程序连接池配置
SET GLOBAL wait_timeout = 60;
坑2:看不到其他用户的连接
普通用户只能看到自己的连接。
解决: 用root用户登录,或者PROCESS权限。
坑3:kill了连接还在
kill了连接,但连接还在列表里。
原因: 连接正在回滚,需要等一会。
解决: 等几秒再看,或者重启MySQL。
坑4:连接数突然暴涨
突然一堆连接进来,数据库卡死。
原因: 可能是程序bug,或者被攻击了。
排查: 按IP统计,看哪个IP连接最多。
总结
常用命令:
| 命令 | 作用 |
|---|---|
SHOW PROCESSLIST |
看当前连接 |
SHOW FULL PROCESSLIST |
看完整SQL |
SHOW STATUS LIKE 'Threads_connected' |
看当前连接数 |
KILL 连接ID |
杀掉连接 |
记住: 连接数满了先看processlist,找出是谁占着连接。
遇到问题加QQ23979811 协助处理