[PostgreSQL] 커넥션 폭주 접속 거부

반응형
PostgreSQL 커넥션 폭주 접속 거부

PostgreSQL 커넥션 / 세션 폭주로 인한 접속 거부

유형: 일반오류형 · 트래픽 증가 또는 애플리케이션 설정 오류로 자주 발생

1️⃣ 장애 개요

PostgreSQL은 프로세스 기반 DB 구조로, 클라이언트 커넥션 하나당 서버 프로세스 하나가 할당됩니다.
따라서 동시에 접속 가능한 세션 수에는 명확한 상한(max_connections)이 존재하며, 이를 초과하면 새로운 접속은 즉시 거부됩니다.

2️⃣ 대표 오류 메시지

FATAL: sorry, too many clients already
connection timeout
connection pool exhausted

애플리케이션에서는 DB 에러 대신 “타임아웃”, “풀 소진”, “간헐적 접속 실패” 형태로 보이는 경우가 많습니다.

3️⃣ 사용자 입장에서 보이는 증상

  • 갑자기 DB 접속이 안 됨
  • 애플리케이션 전체 또는 일부 기능이 멈춤
  • 재시도하면 간헐적으로 성공
  • 특정 시간대(배치/피크타임)에만 장애 발생
현장 특징
- 낮에는 정상, 새벽 배치 시간에만 장애 발생
- 특정 API 호출량 증가 시 집중적으로 발생
- 재기동하면 일시적으로 정상 복구

4️⃣ 운영 환경에서 자주 터지는 원인

  • max_connections 한도 초과
    DB 서버가 허용하는 최대 세션 수를 초과
  • 커넥션 풀 미사용 또는 오설정
    요청마다 새 커넥션 생성, 풀 크기 과다
  • 커넥션 누수
    애플리케이션에서 커넥션 반환(close) 누락
  • 장시간 트랜잭션
    트랜잭션 종료 안 된 채 세션 점유
  • idle in transaction
    실제 작업은 없지만 트랜잭션 상태로 대기

5️⃣ 운영 대응 포인트 (핵심 관점)

핵심 질문
“왜 세션 수가 늘었는가?”
단순히 max_connections을 늘리는 것은 근본 해결이 아닙니다.

반드시 아래 항목을 함께 점검해야 합니다.

  • 애플리케이션에서 커넥션 풀을 사용 중인지
  • 풀 크기와 앱 인스턴스 수의 곱이 DB 한도를 넘지 않는지
  • 반납되지 않은 커넥션(누수)이 존재하는지
  • 장기 트랜잭션/idle in transaction 세션 존재 여부
  • 배치 작업 동시 실행 개수 과다 여부

6️⃣ 단기 대응 전략

즉시 조치(운영 중 장애 대응)
- 원인 확인 후 불필요한 세션 정리(강제 종료는 신중)
- 배치/백그라운드 작업 일시 중단 또는 동시성 축소
- 애플리케이션 재기동으로 누수 세션 정리

주의: 단순히 세션을 죽이는 행위는 데이터 정합성 문제를 유발할 수 있으므로, 반드시 세션 상태(트랜잭션 여부)를 확인한 후 수행해야 합니다.

7️⃣ 중·장기 대응 전략

구조 개선 방향
- pgbouncer 등 경량 커넥션 풀러 도입
- 애플리케이션 커넥션 풀 크기 표준화
- 배치 작업 동시성 제한(큐 기반 처리)
- 장기 트랜잭션 모니터링 및 알림 구성

특히 pgbouncer 같은 풀러를 사용하면, DB 입장에서는 적은 수의 커넥션만 유지하면서도 애플리케이션 요청을 효율적으로 처리할 수 있습니다.

8️⃣ 기본 오류 대응 4단계

1) 증상 확인: 접속 거부 vs 타임아웃 vs 풀 소진 구분
2) 현황 파악: 현재 세션 수, idle/active/transaction 상태 확인
3) 원인 분석: 풀 설정·누수·장기 트랜잭션·배치 동시성 점검
4) 구조 개선: 풀러 도입, 연결 전략 재설계, 모니터링 강화

이 장애 유형은 “트래픽 증가”가 아니라 “커넥션 관리 실패”에서 비롯되는 경우가 대부분입니다.
구조를 바꾸지 않으면 max_connections을 늘려도 동일한 장애는 반복됩니다.

반응형