在**关系型数据库(MySQL / PostgreSQL / Oracle 等)**中,**连接泄漏(Connection Leak)**通常指:
应用获取了数据库连接,但未能正确关闭(未 release / 未 return 到连接池),导致连接数持续增长,最终耗尽连接池或数据库最大连接数。
下面从 现象 → 定位 → 根因 → 解决 四个层面讲怎么排查。
-- MySQL
SHOW STATUS LIKE 'Threads_connected';
-- PostgreSQL
SELECT count(*) FROM pg_stat_activity;
-- Oracle
SELECT COUNT(*) FROM v$session;
典型特征:
-- MySQL
SELECT
host, user, count(*)
FROM information_schema.processlist
GROUP BY host, user;
-- PostgreSQL
SELECT
client_addr, usename, count(*)
FROM pg_stat_activity
GROUP BY client_addr, usename;
重点看:
-- MySQL
SELECT *
FROM information_schema.processlist
WHERE command = 'Sleep'
ORDER BY time DESC;
-- PostgreSQL
SELECT *
FROM pg_stat_activity
WHERE state = 'idle'
ORDER BY backend_start ASC;
异常信号:
常见连接池:
检查连接池配置是否合理:
maxPoolSize
minIdle
connectionTimeout
idleTimeout
maxLifetime
连接泄漏 ≠ 连接池小
连接池只是“延迟爆炸”
错误示例(泄漏):
Connection conn = dataSource.getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
// 忘了 close
正确写法:
try (Connection conn = dataSource.getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql)) {
// 自动关闭
}
排查重点:
开启监控:
spring:
hikaricp:
register-mbeans: true
查看指标:
activeidlepending/druid/index.html
可看到:
✅ 典型根因:
close() 连接 / Statement / ResultSet设置数据库侧自动断开空闲连接
-- MySQL
wait_timeout = 300
interactive_timeout = 300
设置连接池最大存活时间(小于数据库 timeout)
临时重启泄漏应用实例
如果你愿意,可以告诉我:
我可以直接帮你针对性分析泄漏点。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。