환경:
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 상태 청소하는 용도
'개발자 전향 프로젝트' 카테고리의 다른 글
| VSCode Remote Explorer 통해 SSH 접근 시 에러 디버깅 (2) | 2025.06.20 |
|---|---|
| 자주 사용하는 도커 로그 구하는 법 (0) | 2025.06.18 |
| 윈도우 함수란? (0) | 2025.05.20 |
| ELK + 내장 Filebeat (0) | 2025.03.26 |
| 페이징의 종류와 각각의 장단점 (파이썬+장고) (0) | 2025.01.23 |