
数据库连接池问题排查
1. 确认现状
-- 当前总连接数
SHOW STATUS LIKE 'Threads_connected';
-- 最大连接数上限
SHOW VARIABLES LIKE 'max_connections';2. 连接分布统计
-- 按数据库统计连接数
SELECT db, COUNT(*) AS cnt
FROM information_schema.PROCESSLIST
GROUP BY db ORDER BY cnt DESC;
-- 按用户/IP 统计连接数
SELECT SUBSTRING_INDEX(host, ':', 1) AS ip, user, COUNT(*) AS cnt
FROM information_schema.PROCESSLIST
GROUP BY ip, user
ORDER BY cnt DESC;3. Sleep 连接排查
-- 找出 Sleep 连接及时长(前 20 个)
SELECT id, user, host, db, command, time, state
FROM information_schema.PROCESSLIST
WHERE command = 'Sleep'
ORDER BY time DESC
LIMIT 20;说明: time 列单位为秒,表示当前状态持续时长。Sleep 连接是连接池保活的空闲连接,短时间是正常的。4. 批量 Kill 长时间 Sleep 连接
-- 生成 KILL 语句(仅查看,不执行)
SELECT CONCAT('KILL ', id, ';') AS kill_sql
FROM information_schema.PROCESSLIST
WHERE command = 'Sleep' AND time > 300
ORDER BY time DESC;⚠️ 谨慎操作: 复制输出结果粘贴执行才会真正 kill。建议先确认业务影响。
5. 一键批量 Kill(存储过程)
DROP PROCEDURE IF EXISTS batch_kill_sleep;
DELIMITER $$
CREATE PROCEDURE batch_kill_sleep(IN max_seconds INT)
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE conn_id BIGINT;
DECLARE cur CURSOR FOR
SELECT id FROM information_schema.PROCESSLIST
WHERE command = 'Sleep' AND time > max_seconds;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur;
read_loop: LOOP
FETCH cur INTO conn_id;
IF done THEN LEAVE read_loop; END IF;
KILL conn_id;
END LOOP;
CLOSE cur;
END$$
DELIMITER ;
-- 执行:kill 空闲超过 300 秒的 Sleep 连接
CALL batch_kill_sleep(300);
-- 用完清理
DROP PROCEDURE IF EXISTS batch_kill_sleep;6. ❌[不推荐,建议还是业务上处理]❌调整空闲超时参数
-- 查看当前超时配置
SHOW VARIABLES LIKE '%wait_timeout%';
-- 临时调整(立即生效,重启失效)
SET GLOBAL wait_timeout = 1800;
SET GLOBAL interactive_timeout = 1800;默认 28800 秒(8小时),建议调整为 600~1800 秒(10~30分钟)。
持久化配置(写入 my.cnf):
[mysqld]
wait_timeout = 1800 #交互连接空闲超时,Navicat 等交互工具,30分钟无操作断开
interactive_timeout = 1800 #非交互连接空闲超时,用程序连接,30分钟无操作断开常见原因速查
| 原因 | 排查方式 | 处理 |
|---|---|---|
| 连接池配置过大 | 检查应用连接池 max size | 调小连接池上限 |
| Sleep 连接堆积 | time 字段几百秒以上 | 调低 wait_timeout |
| 连接未释放(泄漏) | 连接数只增不减 | 检查代码连接关闭逻辑 |
| 慢查询占用连接 | SHOW PROCESSLIST 大量 Query | 开慢查询日志,优化 SQL |
| 突发流量/扩容 | Pod 数量增加 | 限流、排队或扩容 |
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 运维小弟