DBAtlas · 数据库运维图谱

连接风暴(连接过多)

症状

出现 'too many connections'、'ORA-00018'、'remaining connection slots reserved'——新连接被拒绝。

1. 测量当前状态

当前有多少连接,上限是多少,活动与空闲连接各有多少?

Oracle

SELECT COUNT(*) total, SUM(CASE WHEN status='ACTIVE' THEN 1 ELSE 0 END) active FROM v$session WHERE type='USER';

PostgreSQL

SELECT count(*), state FROM pg_stat_activity WHERE backend_type = 'client backend' GROUP BY state;

MySQL

SHOW STATUS LIKE 'Threads_connected'; SHOW VARIABLES LIKE 'max_connections';

SQL Server

SELECT COUNT(*), status FROM sys.dm_exec_sessions WHERE is_user_process=1 GROUP BY status;

Redis

INFO clients

2. 确定来源:谁/从哪里

是哪个应用/主机/用户在打开这些连接?通常是某台应用服务器的连接池暴涨,或存在连接泄漏(大量 idle in transaction 会话)。

PostgreSQL

SELECT client_addr, usename, state, count(*) FROM pg_stat_activity WHERE backend_type = 'client backend' GROUP BY 1,2,3 ORDER BY 4 DESC;

MySQL

SELECT host, user, count(*) FROM information_schema.processlist GROUP BY host, user ORDER BY 3 DESC;

SQL Server

SELECT host_name, program_name, login_name, COUNT(*) FROM sys.dm_exec_sessions WHERE is_user_process=1 GROUP BY host_name, program_name, login_name ORDER BY 4 DESC;

3. 立即争取喘息空间

清理长时间空闲/idle in transaction 的连接。必要时批量断开问题应用的连接。使用为管理员登录预留的连接槽(PG superuser_reserved_connections)。

4. 正确的解决办法:连接池

无限制地调高 max_connections 会消耗内存,只是推迟问题。正确的做法是在应用端使用连接池(HikariCP、PgBouncer、ProxySQL)并设置合理的池大小。池大小通常约为(核数*2 + 磁盘数)——参见 Tools > Connection Pool 计算器。

5. 防止泄漏和再次发生

确保应用关闭连接(finally/using)。设置 idle_in_transaction_session_timeout 和 wait_timeout。设置连接数告警。

在 DBAtlas 中打开 →