DBAtlas · Atlas de operações de banco de dados

Connection storm (conexões demais)

Sintoma

'too many connections', 'ORA-00018', 'remaining connection slots reserved' — novas conexões estão sendo rejeitadas.

1. Meça o estado atual

Quantas conexões existem, qual é o limite, e quantas estão ativas vs. ociosas?

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. Identifique a origem: quem/de onde

Qual aplicação/host/usuário está abrindo as conexões? Geralmente o pool de um único servidor de aplicação estourou ou há um vazamento de conexões (um monte de sessões 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. Ganhe fôlego imediatamente

Limpe as conexões ociosas há muito tempo/idle in transaction. Se necessário, derrube em massa as conexões da aplicação problemática. Use o slot reservado para login de administrador (PG superuser_reserved_connections).

4. A correção certa: pooling de conexões

Aumentar max_connections sem limite consome memória e só adia o problema. A correção certa é um pool de conexões no lado da aplicação (HikariCP, PgBouncer, ProxySQL) com um tamanho de pool razoável. O tamanho do pool costuma ficar em torno de (núcleos*2 + número de discos) — veja a calculadora em Ferramentas > Connection Pool.

5. Evite vazamentos e recorrência

Garanta que a aplicação feche as conexões (finally/using). Defina idle_in_transaction_session_timeout e wait_timeout. Configure um alerta para o número de conexões.

Abrir no DBAtlas →