애플리케이션이 갑자기 DB에 못 붙고 다음 에러를 뱉습니다.
OUTPUT
ERROR 1040 (HY000): Too many connections
DB가 받을 수 있는 최대 연결 수(max_connections)를 넘었다는 뜻입니다. 무작정 이 값을 올리기 전에, 연결을 누가 그렇게 많이 잡고 있는지부터 봐야 합니다. 대부분은 커넥션 누수나 풀 설정 실수입니다.
먼저 현황을 본다
SQL
SHOW VARIABLES LIKE 'max_connections'; -- 상한 (기본 151)
SHOW STATUS LIKE 'Threads_connected'; -- 현재 연결 수
SHOW STATUS LIKE 'Max_used_connections'; -- 피크 기록
누가 잡고 있는지 직접 봅니다.
SQL
SELECT user, host, db, COUNT(*) AS conns
FROM information_schema.processlist
GROUP BY user, host, db
ORDER BY conns DESC;
특정 앱 하나가 연결을 독식하고 있다면 그 앱의 풀 설정 또는 누수가 원인입니다.
원인별 해결
| 원인 | 증상 | 해결 |
|---|---|---|
| 커넥션 누수 | 연결 수가 계속 우상향, 안 줄어듦 | 코드에서 close() 누락 지점 수정 |
| 풀 크기 과다 | 앱 인스턴스 × 풀 크기 > max_connections | 풀 크기 줄이기 |
| 슬립 커넥션 적체 | Sleep 상태 연결 다수 | wait_timeout 단축 |
| 트래픽 급증 | 순간 동시 요청 폭증 | max_connections 상향 + 풀 튜닝 |
① 풀 크기 계산
앱 인스턴스 4개가 각자 풀 50개를 잡으면 4 × 50 = 200 > 기본 151이라 바로 고갈됩니다. 실제 동시성에 맞춰 줄입니다.
TEXT
필요 풀 크기 ≈ (코어 수 × 2) + 디스크 스핀들 수 # HikariCP 권장 출발점
② 누수 잡기 (오래 잡힌 연결 확인)
SQL
SELECT id, user, time, state, info
FROM information_schema.processlist
WHERE command = 'Sleep' AND time > 300; -- 5분 넘게 노는 연결
③ 임시 응급 처치 후 근본 원인으로
SQL
SET GLOBAL max_connections = 300; -- 임시. 재시작하면 초기화
KILL <id>; -- 특정 좀비 연결 종료
체크리스트
DB 클라이언트
# 현재 vs 상한
mysql -e "SHOW STATUS LIKE 'Threads_connected'; SHOW VARIABLES LIKE 'max_connections';"
# 앱 풀 합계가 max_connections 안에 드는지
# (인스턴스 수 × 풀 maximumPoolSize) < max_connections
연결 수가 시간이 지나도 줄지 않으면 설정이 아니라 누수입니다. 코드의 커넥션 반환부터 점검하세요.
커넥션 풀을 직접 고갈시켜 보고 processlist로 진단하는 실습은 데이터베이스 트랙에서 회원가입 없이 무료로 할 수 있습니다.