DBAtlas · 데이터베이스 운영 아틀라스

커넥션 폭주 (too many connections)

증상

'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. 원인을 식별한다: 누가/어디서

어떤 애플리케이션/호스트/사용자가 연결을 열고 있는가? 대개 한 애플리케이션 서버의 pool이 폭주했거나 연결 누수(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/idle-in-transaction 연결을 정리한다. 필요하면 문제 애플리케이션의 연결을 일괄 종료한다. 관리자 로그인용으로 예약된 슬롯을 사용한다(PG superuser_reserved_connections).

4. 올바른 해결책: connection pooling

max_connections를 무작정 올리면 메모리를 소모하고 문제를 미룰 뿐이다. 올바른 해결책은 애플리케이션 측 connection pool(HikariCP, PgBouncer, ProxySQL)과 적절한 pool 크기다. pool 크기는 보통 (코어*2 + 디스크 수) 정도다 — Tools > Connection Pool 계산기 참조.

5. 누수와 재발을 방지한다

애플리케이션이 연결을 닫는지 확인한다(finally/using). idle_in_transaction_session_timeout과 wait_timeout을 설정한다. 연결 수에 대한 알림을 설정한다.

DBAtlas에서 열기 →