왜 당신의 PostgreSQL은 계속 연결이 부족해지는가

발행: (2026년 3월 18일 AM 02:31 GMT+9)
5 분 소요
원문: Dev.to

Source: Dev.to

연결 제한 이해하기

PostgreSQL은 max_connections 설정으로 정의된 동시 연결 수의 최대치를 강제합니다. 일반적인 기본값은 다음과 같습니다:

  • 소규모/기본 티어: 50–100 연결
  • 범용 티어: 100–200 연결

애플리케이션이 이 제한보다 더 많은 연결을 열려고 하면 PostgreSQL은 TooManyConnectionsError를 반환합니다. 데이터베이스 자체는 여전히 작동 중이며, 단지 새로운 연결을 받을 여유가 없을 뿐입니다.

단일 풀만으로는 부족한 이유

연결 풀을 사용하더라도 여러 풀을 만들면 제한을 빠르게 초과할 수 있습니다.

일반적인 애플리케이션에서 일어나는 일

class DatabaseClient:
    def __init__(self):
        self.pool = create_pool(min=2, max=10)   # each instance gets its own pool

서비스가 여러 구성 요소를 생성하고 각각 DatabaseClient를 인스턴스화한다면:

구성 요소생성된 풀 수풀당 연결 수
헬스 체크러110
의존성 체크러110
각 워커 (예: 6개)6각각 10 (총 60)
총합880

두 개의 컨테이너를 실행하면 이 수가 두 배가 되어 160 연결이 되며, max_connections 100을 쉽게 초과해 오류가 발생합니다.

해결책: 단일 공유 풀

모듈 또는 프로세스 수준에서 하나의 풀을 생성하고 모든 DatabaseClient 인스턴스가 이를 빌려 쓰도록 합니다.

# shared_pool.py
_shared_pool = None

def get_shared_pool():
    global _shared_pool
    if _shared_pool is None:
        _shared_pool = create_pool(min=2, max=5)   # configure as needed
    return _shared_pool
# client.py
from shared_pool import get_shared_pool

class DatabaseClient:
    def get_connection(self):
        return get_shared_pool().acquire()

이제 DatabaseClient 객체를 몇 개 만들든 모두 같은 제한된 연결 집합을 공유합니다.

주의해야 할 함정

  1. close() 함정
    클라이언트의 close() 메서드가 공유 풀을 종료시키면 이후 호출이 모두 실패합니다. 개별 인스턴스에서는 close()를 아무 작업도 하지 않게 하고, 프로세스 종료 시에만 풀을 닫도록 합니다.

  2. 헬스 체크에 미치는 연쇄 효과
    데이터베이스가 연결을 다 쓰면 헬스 체크 쿼리도 실패합니다. 오케스트레이터가 컨테이너를 재시작하면 새 풀을 만들게 되고 문제가 악화될 수 있습니다.

  3. 풀 크기 설정 가능하게
    환경 변수(예: PG_POOL_MAX_SIZE=5)를 사용해 풀 크기를 조정하면 재배포 없이도 설정을 바꿀 수 있습니다.

  4. 배포 전 계산하기

    pool_max_size × max_replicas < max_connections - admin_headroom

    예시

    • 풀 최대 크기: 5
    • 서비스 전체 복제본 수: 10 → 5 × 10 = 50
    • max_connections: 100
    • 관리자 여유 공간: 20 → 100 − 20 = 80

    50 < 80 이므로 설정이 안전합니다. 부등식이 성립하지 않으면 풀 크기를 줄이거나 PgBouncer와 같은 전용 풀러를 도입하세요.

변경 사항 적용 전 체크리스트

  • ✅ 모듈/프로세스 수준에서 단일 공유 풀 사용
  • ✅ 풀 크기를 환경 변수로 설정 가능하게 함
  • ✅ 개별 인스턴스의 close()는 아무 동작도 하지 않음
  • ✅ 프로세스 종료 시에만 공유 풀을 닫음
  • ✅ 모든 서비스에 대한 연결 수 계산을 검증
  • ✅ 구문 및 단위 테스트를 실행해 코드가 정상 동작하는지 확인

TL;DR

  • 여러 풀 = 연결 고갈
  • 하나의 공유 풀 = 안정적이고 예측 가능한 사용

문제가 보통 풀 부족이 아니라 풀이 너무 많음이라는 점을 이해하면 새벽 1시의 패닉을 관리 가능한 상황으로 바꿀 수 있습니다. 데이터베이스 연결이 부족하다는 알림을 받은 분들에게 도움이 되길 바랍니다. 🙂

0 조회
Back to Blog

관련 글

더 보기 »