根本原因是大量Sleep连接长期滞留占满max_connections配额;应先通过show processlist、Threads_connected等命令诊断连接状态,再优先调短wait_timeout而非盲目扩容。
根本原因不是连接数设得太低,而是大量 sleep 连接长期滞留,占满 max_connections 配额。
查清当前连接状态和真实瓶颈
别急着调大 max_connections,先看连接到底在干什么:
- 执行
show processlist;—— 重点关注State列为Sleep的行,数量远超活跃业务连接就说明是闲置连接堆积 - 执行
show status like 'Threads_connected';和show status like 'Max_used_connections';—— 前者是当前总连接数,后者是历史峰值,对比能判断是否真有高并发需求 - 执行
show global variables like '%wait_timeout%';—— 查默认值,MySQL 通常为28800(8 小时),PostgreSQL 对应的是idle_in_transaction_session_timeout和tcp_keepalives_idle
MySQL:优先调短 wait_timeout 而非盲目扩连接数
临时生效快、副作用小,适合开发/测试环境快速缓解:
- 执行
set global wait_timeout = 300;(单位秒,建议 300–600) - 执行
set global interactive_timeout = 300;(交互式连接也需同步调整) - 该设置立即生效,但重启 MySQL 后失效;如需永久生效,编辑
/etc/my.cnf或my.ini,在[mysqld]段下添加:wait_timeout = 300<br>interactive_timeout = 300
- 注意:太小(如
PostgreSQL:重点处理 idle in transaction 连接
这类连接比普通 idle 更危险——它持有锁却不推进事务,极易引发雪崩:
- 查问题连接:
SELECT pid, datname, usename, state, query_start, query FROM pg_stat_activity WHERE state = 'idle in transaction'; - 杀掉指定连接:
SELECT pg_terminate_backend(<em>pid</em>);(把 pid 替换为实际进程 ID) - 永久预防:执行
ALTER SYSTEM SET idle_in_transaction_session_timeout = '30s';,然后SELECT pg_reload_conf();生效 - 若应用使用连接池(如 HikariCP),务必检查
spring.datasource.hikari.leak-detection-threshold是否启用(建议 ≤5000ms),否则泄漏连接不会被及时回收
Navicat 自身配置与协同规范
工具层的误用会放大服务端压力:
- 关闭 Navicat 的「自动保存连接」和「自动重连」选项,避免断连后无脑新建连接
- 多人共用同一套数据库账号时,禁用「记住密码」并统一使用连接分组命名(如
dev_zhangsan),便于通过usename字段快速定位归属 - 定期执行清理脚本(MySQL 示例):
KILL $(mysql -Nse "SELECT GROUP_CONCAT(ID) FROM information_schema.PROCESSLIST WHERE Command='Sleep' AND Time > 300");
(慎用,建议先SELECT确认) - 真正棘手的从来不是参数数字,而是没人知道谁在跑长事务、谁没关查询窗口、谁在本地启了三个未关闭的 Navicat 实例


















