본문 바로가기
개발자 전향 프로젝트

FATAL: remaining connection slots are reserved for roles with the SUPERUSER attribute 에러 디버깅

by 샘오리 2025. 6. 17.
728x90
반응형

환경:

Django 4.0.5

Postgres 16.4

 

문제:

DB 트랜잭션이 요구되는 모든 작업 불가

 

 

원인:

FATAL: remaining connection slots are reserved for non-replication superuser connections 에러는 PostgreSQL의 최대 연결 수(max_connections)를 초과했을 때 발생하는 에러로 슈퍼유저나 복제(replicaton) 연결을 위한 슬롯을 제외하고, 일반 연결을 모두 소진했을 때 나타나는 경우가 일반적이다.

 

특히 Django에서 ASGI 서버(Daphne, Uvicorn 등)로 웹소켓 연결을 사용할 때 "FATAL: remaining connection slots are reserved for non-replication superuser connections" 오류가 자주 발생할 수 있다. 그 이유는 요청 처리 후 데이터베이스 연결이 제대로 종료되지 않아, 열려 있는 연결이 빠르게 쌓이기 때문이다.

 

해결책:

 

1. POOL_SIZE를 줄이고 RECYCLE을 늘리기

 

동시 연결의 수를 제한하기 위해 POOL_SIZE를 줄이고, 불필요하게 모든 Connection을 죽이지 않기 위해 

RECYCLE의 경우 늘리기

 

*POOL_SIZE = 프로세스 별 항시 지속 연결해야하는 connection의 수

MAX_OVERFLOW = 프로세스 별 최대 몇개의 Connection 까지 추가로 허용할지

RECYCLE = 프로세스 별 모든 connection의 수명

 

동시 연결의 수의 공식은 아래와 같으므로

(POOL_SIZE + MAX_OVERFLOW) X 총 프로세스의 수

 

=>

 

아래는 추천 설정

'POOL_OPTIONS': {
    'POOL_SIZE': 5,
    'MAX_OVERFLOW': 10,
    'RECYCLE': 3600
}

 

 

2. PG System의 MAX_CONNECTION을 문제됐던 Connection의 2배로 늘리기

 

ALTER SYSTEM SET max_connections = 기존 Connection * 2;

 


*max_connections가 100일 경우 여유롭게 2배 정도의 connections로 설정. 

많이 늘리는 것이 trade-off인 것이 메모리 사용률이 늘어나기 때문.

** PG DB 재시작 필수

 

3. idle in transaction(트랜잭션이 시작되고 끝나지 않은 연결)의 경우 pid를 자동으로 지정된 시간 이후 KILL

 

아래는 60초 예시

ALTER SYSTEM SET idle_in_transaction_session_timeout = '60s';
SELECT pg_reload_conf();

 

*BEGIN만 하고 COMMIT을 하지 않은 쿼리로 인한 idle in transaction 상태 청소하는 용도

728x90
반응형