连接池配置不当会导致连接失效、泄漏和数据库崩溃,需合理设置idleTimeout、启用连接检测、按公式计算maximumPoolSize、区分真实空闲连接、实施账号级连接限流、持久化MySQL配置并预留内存余量。

连接池没配好,等于白用
连接池不是加了依赖就自动生效的,常见错误是只设了 maximumPoolSize,却忽略空闲连接回收逻辑。比如 HikariCP 默认 idleTimeout=600000(10 分钟),而 MySQL 的 wait_timeout 是 28800 秒(8 小时)——两边不匹配,池子里的连接早该被 MySQL 主动断开,但连接池还当它活着,下次复用时抛 Connection reset 或卡在 Sleep 状态。
- 务必让连接池的
idleTimeout比 MySQL 的wait_timeout小至少 30 秒,例如 MySQL 设为300(5 分钟),HikariCP 就设idleTimeout=270000 - 开启连接有效性检测:
connectionTestQuery=SELECT 1(Druid)或connection-test-query=SELECT 1(HikariCP 5.0+),避免拿到底层已断的连接 - 别把
maximumPoolSize直接设成 MySQL 的max_connections,建议按公式:应用实例数 × 每实例平均并发连接数 × 1.2,再向上取整
sleep 连接堆积,先看状态再 kill
大量 Sleep 状态连接占满 max_connections,不是立刻 KILL,而是先确认它是否真“空闲”。有些连接看似 Sleep,实则正处在事务中(INNODB_TRX 里有记录),贸然中断会丢数据或锁表。
- 查真实空闲连接:
SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND = 'Sleep' AND TIME > 300 AND ID NOT IN (SELECT TRX_MYSQL_THREAD_ID FROM INFORMATION_SCHEMA.INNODB_TRX) - 批量清理超时空闲连接(慎用):
SELECT CONCAT('KILL ', ID, ';') FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND = 'Sleep' AND TIME > 600;,复制结果再执行 - 临时救急但不推荐:用
mysqladmin -u root -p processlist | grep "Sleep" | awk '{if ($6 > 600) print "KILL " $2 ";"}' | mysql -u root -p,适合脚本化巡检
限流不是挡用户,是保数据库不死
应用层限流(如 Sentinel、Resilience4j)只能缓解 QPS 冲击,对连接泄漏或慢查询引发的连接堆积几乎无效。真正起作用的是数据库侧的连接级限流——靠 max_user_connections 和账号隔离。
- 给每个业务应用分配独立数据库账号,然后限制其最大连接数:
ALTER USER 'app_order'@'%' WITH MAX_USER_CONNECTIONS 100; - 配合应用名识别(MySQL 5.7+ 支持
program_name)做更细粒度控制,避免一个服务 bug 拖垮全库 - 不要依赖应用层“统一限流”来兜底连接数,因为连接建立发生在请求进入限流器之前;必须在连接建立入口(如连接池初始化、JDBC URL 参数)就做约束
配置改完不持久,重启就回滚
SET GLOBAL max_connections = 2000 这类命令只是临时生效,MySQL 重启后还原。更危险的是,盲目调大 max_connections 可能触发内存溢出——每个连接默认消耗约 2MB 内存(含线程栈、排序缓冲区等),2000 连接就是 4GB,远超多数 8GB 服务器的安全水位。
- 永久修改必须写入配置文件:
[mysqld]下添加max_connections = 1024,同时配套调低wait_timeout = 300和interactive_timeout = 300 - 内存要留余量:用
innodb_buffer_pool_size占总内存 50%~75%,剩余留给连接线程和 OS 缓存;可粗略估算:max_connections × (sort_buffer_size + read_buffer_size + thread_stack) < 总内存 × 0.2 - 上线前用
mysqltuner.pl扫描配置合理性,它会直接警告 “max_connections * per-thread memory > available RAM”
最常被忽略的一点:连接池的 leakDetectionThreshold(如 HikariCP 的毫秒值)必须打开并设合理,否则连接泄漏就像慢性失血,等发现时往往已不可逆。


















