贝利信息

SQL 数据库连接耗尽的原因

日期:2026-01-25 00:00 / 作者:冷漠man
数据库连接耗尽最常见原因是连接池配置过小且并发请求高,其次为连接未正确关闭、长事务或慢查询阻塞、连接池与数据库最大连接数不匹配。

连接池配置过小但并发请求高

数据库连接耗尽最常见原因是连接池最大值(如 maxPoolSize)设得太低,而应用短时间内发起大量查询。比如 Spring Boot 默认 HikariCP 的 maximumPoolSize 是 10,若接口 QPS 达到 50 且平均响应时间 200ms,理论瞬时连接需求就可能突破 10(50 × 0.2 = 10),实际因排队和重试很容易打满。

实操建议:

连接未正确关闭导致泄漏

Java 中忘记在 finally 块或 try-with-resources 中关闭 Connecti

onStatementResultSet,或 Go 中漏掉 rows.Close(),都会让连接一直被占用,直到超时或进程重启。

典型现象是连接数缓慢上涨,且 SHOW PROCESSLIST(MySQL)里能看到大量 Sleep 状态连接,状态持续几分钟以上。

实操建议:

长事务或慢查询阻塞连接释放

一个执行 30 秒的 UPDATE 语句会独占一个连接整整半分钟,期间该连接无法复用。如果这类语句频繁出现,连接池很快被占满,新请求只能等待或失败。

更隐蔽的是隐式事务:比如 MySQL 在 autocommit=false 下执行一条 SELECT 后没提交,后续所有操作都在同一事务中,连接就一直挂着。

实操建议:

连接池与数据库最大连接数不匹配

应用端配了 maximumPoolSize=100,但 MySQL 的 max_connections 只有 50,结果一半连接永远拿不到,报错通常是 Too many connections 或 HikariCP 的 Connection is not available, request timed out after 30000ms

还要注意中间件影响:比如用了读写分离代理(MyCat、ShardingSphere),它本身也维护连接池,会额外消耗后端数据库连接。

实操建议:

真正难排查的往往是组合问题:比如连接池偏小 + 几个慢查询 + 一处忘了 close,三者叠加才触发耗尽。监控必须覆盖应用连接池指标、数据库活跃连接、SQL 执行时长三个层面,缺一不可。