본문 바로가기
소프트웨어개발

PostgreSQL too many connections 해결: 연결 수 진단·풀 설정·max_connections 점검

by 아빠띠띠뽀 2026. 9. 27.

PostgreSQL 접속 수 초과 해결 흐름: 연결 관찰, 앱 풀 예산 계산, 누수 수정, 재검증

그림: 연결 현황을 관찰하고 앱 전체의 풀 예산을 계산한 뒤 누수를 수정·검증하는 흐름입니다. 직접 제작한 개념도입니다.

PostgreSQL에서 too many connections 또는 예약된 연결 슬롯 관련 오류가 나오면 새 접속을 받아 줄 여유가 부족할 가능성이 큽니다. 먼저 접속이 어디서 늘어났는지 확인하고, 앱 인스턴스 전체의 풀 크기를 계산하세요. max_connections를 바로 올리면 원인은 남고 메모리·운영 부담만 커질 수 있습니다.

1. 오류 발생 위치와 시점을 확인하기

앱 로그의 시간·DB 주소·배포 직후 여부를 기록합니다. DB 서버의 슬롯 부족인지, 중간 프록시나 앱 풀의 대기 시간 초과인지 구분해야 합니다. 운영자가 접속할 수 있다면 아래 읽기 전용 쿼리로 설정과 연결 분포를 확인합니다. 진단 권한에 따라 다른 사용자의 세부 정보가 제한될 수 있습니다.

SHOW max_connections;
SELECT datname, usename, application_name, state, count(*) AS connections
FROM pg_stat_activity
WHERE backend_type = 'client backend'
GROUP BY datname, usename, application_name, state
ORDER BY connections DESC;
SELECT pid, application_name, state,
       now() - xact_start AS transaction_age
FROM pg_stat_activity
WHERE state = 'idle in transaction'
ORDER BY xact_start NULLS LAST;

pg_stat_activity는 서버 프로세스의 활동을 보여 줍니다. 전체 행 수와 앱 연결 수를 그대로 같다고 보지 말고 위 예시처럼 클라이언트 백엔드를 구분하세요. PostgreSQL 통계 공식 문서에서 상태와 권한 의미를 확인할 수 있습니다.

2. 관찰 결과별 원인 비교

관찰 가능한 원인 다음 점검
배포 직후 연결 급증 구·신 인스턴스가 동시에 풀 유지 최대 동시 인스턴스와 풀 상한
idle 연결이 많음 큰 풀 또는 반환되지 않는 연결 유휴 설정·반환 코드·풀 지표
idle in transaction 지속 트랜잭션 종료 누락 예외 경로의 rollback·연결 반환
active와 대기가 함께 증가 느린 쿼리·락·요청 집중 쿼리 지연·대기 이벤트·재시도

idle은 풀에서 대기하는 정상 연결일 수도 있습니다. 숫자만 보고 일괄 종료하지 마세요. 트랜잭션 중인 세션을 종료하면 작업이 중단되거나 롤백될 수 있습니다. 이 글의 SQL은 조회용이며 세션 종료 명령을 포함하지 않습니다.

3. 풀 크기는 프로세스 전체로 계산하기

가상의 예로 앱 8개가 각각 풀 최대 20개를 가지면 앱 연결 상한은 160개입니다. 롤링 배포 중 앱이 12개가 되면 240개로 늘 수 있습니다. 여기에 배치·모니터링·관리 접속을 더해야 합니다. 설정에 적힌 “20”만 보고 DB 전체 연결이 충분하다고 판단하면 안 됩니다.

예산은 배포 중 최대 프로세스 수 × 프로세스별 풀 상한 + 기타 연결 + 운영 여유로 검토합니다. 실제 풀을 공유하는 범위는 프레임워크마다 다르므로 워커 프로세스별인지도 확인하세요. 풀을 줄인 뒤에는 연결 대기 시간과 요청 지연을 측정합니다. DB로 들어가는 동시 작업을 줄이는 대신 앱에서 대기가 늘 수 있기 때문입니다.

4. 수정 순서와 재발 방지 체크리스트

  • 연결을 얻은 모든 경로에서 정상·예외 시 반환되는지 확인합니다.
  • 트랜잭션의 commit 또는 rollback이 보장되는지 확인합니다.
  • 배포·자동 확장·배치의 최대 동시 연결을 합산합니다.
  • 느린 쿼리와 락을 해결하고 즉시 무제한 재시도를 피합니다.
  • 변경 뒤 연결 수·풀 대기·DB 메모리·응답 지연을 함께 관찰합니다.

PgBouncer 같은 별도 풀러를 쓸 때는 session·transaction 모드를 앱의 동작에 맞게 선택합니다. transaction pooling에서는 세션 상태에 의존하는 기능의 호환성 확인이 필요합니다. prepared statement는 버전·프로토콜·설정에 따라 지원 조건이 달라지므로 “항상 불가” 또는 “항상 가능”으로 단정하지 마세요. PgBouncer 기능 표와 공식 FAQ를 함께 확인하세요.

5. 자주 묻는 질문

max_connections를 올리면 해결되나요? 일시적 여유는 늘지만 자원 사용도 달라집니다. 원인과 메모리 여유를 확인하고 재시작·서비스별 변경 적용 조건을 검토하세요. 연결 설정 공식 문서가 기준입니다.

앱 재시작으로 잠깐 나아졌다면 끝인가요? 연결 누수가 잠시 초기화됐을 수 있습니다. 부하가 돌아왔을 때 다시 증가하는지 확인해야 합니다.

idle in transaction이 모두 장애 원인인가요? 짧게 나타날 수 있지만 오래 유지되면 열린 트랜잭션의 의도를 확인해야 합니다. 세션 소유자와 작업 영향을 확인한 뒤 조치하세요.

6. 로그와 연결 지표를 같은 시간축에 놓기

기업용 로그 관리 선택 가이드를 참고해 배포·오류·연결 지표를 함께 남기세요. 이 글은 PostgreSQL 18 공식 문서를 2026년 9월 27일 확인해 작성했습니다. 실제 버전과 관리형 서비스 권한에 맞게 조회·변경 조건을 확인하세요.