2026년 07월 20일 | DBMS Error 가이드
이 글에서 다루는 내용
57P05 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
57P05 idle session timeout 는?
PostgreSQL 에러 코드 57P05는 데이터베이스 세션이 아무런 작업 없이 일정 시간 이상 유휴(idle) 상태로 유지될 때 서버가 강제로 해당 세션을 종료하면서 발생하는 에러입니다. PostgreSQL 14 버전부터 도입된 idle_session_timeout 파라미터가 설정된 환경에서, 클라이언트가 접속 상태를 유지하되 아무런 쿼리도 실행하지 않으면 서버는 설정된 시간이 지난 후 해당 커넥션을 끊어버립니다. 이 에러는 주로 커넥션 풀 설정이 적절하지 않거나, 장시간 idle 상태를 유지하는 애플리케이션에서 빈번하게 관찰됩니다.
주요 발생 원인
idle_session_timeout파라미터의 과도하게 짧은 설정
PostgreSQL 서버 또는 특정 사용자/데이터베이스 레벨에서 idle_session_timeout 값이 지나치게 짧게 설정되어 있으면, 잠깐의 유휴 상태에도 세션이 끊어질 수 있습니다. 특히 트랜잭션 간의 대기 시간이 긴 배치 작업이나, 사용자가 직접 psql로 접속하여 작업하는 경우 예고 없이 세션이 종료되어 작업 흐름이 끊기는 상황이 발생합니다. DBA가 보안 또는 리소스 관리 목적으로 이 값을 설정했더라도, 실무 워크플로우와 맞지 않는 경우 애플리케이션 장애로 이어질 수 있습니다.
- 커넥션 풀러(Connection Pooler) 미사용 또는 잘못된 구성
PgBouncer, pgpool-II 등의 커넥션 풀러를 사용하지 않고 애플리케이션이 직접 PostgreSQL에 장시간 커넥션을 유지하는 경우, 애플리케이션 요청이 없는 시간 동안 세션이 idle 상태로 방치됩니다. 이 상태에서 idle_session_timeout이 만료되면 서버가 세션을 강제 종료하고, 다음 쿼리 실행 시 애플리케이션은 57P05 에러를 마주하게 됩니다. 커넥션 풀러를 사용하더라도 server_idle_timeout 설정이 PostgreSQL의 idle_session_timeout보다 길게 설정된 경우 동일한 문제가 발생할 수 있습니다.
- 애플리케이션의 커넥션 재사용 로직 부재 또는 미흡한 에러 핸들링
일부 애플리케이션이나 ORM 프레임워크는 커넥션이 서버 측에서 끊겼는지 확인하지 않고 기존 커넥션을 그대로 재사용하려는 시도를 합니다. 서버가 57P05로 세션을 종료했음에도 클라이언트는 여전히 커넥션이 살아있다고 판단하여 쿼리를 전송하고, 그 결과 에러가 발생합니다. 특히 Java의 JDBC, Python의 SQLAlchemy, Node.js의 pg 라이브러리 등에서 커넥션 유효성 검사(validation) 로직이 없거나 pre_ping 옵션이 비활성화된 경우 이 문제가 자주 발생합니다.
해결 방법
1. idle_session_timeout 값 확인 및 조정
먼저 현재 설정값을 확인합니다.
-- 현재 idle_session_timeout 설정 확인
SHOW idle_session_timeout;
-- 전체 시스템 설정 확인
SELECT name, setting, unit, context
FROM pg_settings
WHERE name = 'idle_session_timeout';
필요에 따라 값을 조정합니다. 0으로 설정하면 타임아웃이 비활성화됩니다.
-- postgresql.conf 또는 ALTER SYSTEM으로 전역 설정 변경 (단위: ms)
ALTER SYSTEM SET idle_session_timeout = '30min';
-- 변경 사항 반영 (reload만으로 적용 가능)
SELECT pg_reload_conf();
-- 특정 데이터베이스에만 설정 (해당 DB 접속 후)
ALTER DATABASE myapp_db SET idle_session_timeout = '1h';
-- 특정 사용자에게만 설정
ALTER ROLE app_user SET idle_session_timeout = '30min';
-- 특정 세션에서만 임시 변경
SET idle_session_timeout = '0'; -- 현재 세션에서만 타임아웃 비활성화
2. 커넥션 풀러 설정 최적화
PgBouncer를 사용하는 경우 pgbouncer.ini에서 server_idle_timeout을 PostgreSQL의 idle_session_timeout보다 짧게 설정합니다.
-- PgBouncer 설정 확인을 위해 현재 세션 idle 시간 확인
SELECT pid,
usename,
application_name,
state,
now() - state_change AS idle_duration,
query
FROM pg_stat_activity
WHERE state = 'idle'
ORDER BY idle_duration DESC;
-- 오래된 idle 세션 강제 종료 (긴급 상황 시)
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE state = 'idle'
AND now() - state_change > interval '10 minutes'
AND pid <> pg_backend_pid();
3. 애플리케이션 레벨 커넥션 유효성 검사 설정
SQLAlchemy(Python)를 예로 들면, pool_pre_ping=True 옵션을 활성화합니다.
-- 애플리케이션에서 커넥션 테스트용 경량 쿼리 실행 예시
-- (keep-alive 또는 health check 쿼리로 활용)
SELECT 1;
-- 세션 상태 모니터링 쿼리 (DBA 관리용)
SELECT pid,
usename,
datname,
application_name,
client_addr,
state,
EXTRACT(EPOCH FROM (now() - state_change)) AS idle_seconds,
backend_start,
query_start
FROM pg_stat_activity
WHERE state IN ('idle', 'idle in transaction')
AND EXTRACT(EPOCH FROM (now() - state_change)) > 60
ORDER BY idle_seconds DESC;
예방 방법
idle_session_timeout과 커넥션 풀러 타임아웃의 계층적 조율
실무에서 가장 효과적인 예방 방법은 PgBouncer의 server_idle_timeout을 PostgreSQL의 idle_session_timeout보다 항상 짧게 유지하는 것입니다. 예를 들어 PostgreSQL에 idle_session_timeout = 10min이 설정되어 있다면, PgBouncer의 server_idle_timeout은 8min으로 설정하여 PostgreSQL이 세션을 끊기 전에 커넥션 풀러가 먼저 커넥션을 반환하도록 구성합니다. 이렇게 하면 57P05 에러 자체가 애플리케이션까지 전파되지 않으며, 커넥션 풀도 항상 유효한 커넥션만 보유하게 됩니다.
- 정기적인 idle 세션 모니터링 및 알람 설정
pg_stat_activity 뷰를 주기적으로 쿼리하여 장시간 idle 상태인 세션을 감지하고, Prometheus + pg_exporter 또는 Datadog 같은 모니터링 도구를 통해 idle 세션 수가 임계치를 초과할 경우 알람이 발생하도록 구성해두면 사전에 문제를 감지할 수 있습니다. 아울러 애플리케이션 프레임워크에서는 반드시 커넥션 pre_ping 또는 testOnBorrow 옵션을 활성화하고, 커넥션 최대 생존 시간(maxLifetime)을 idle_session_timeout보다 짧게 설정하는 것을 Best Practice로 권장합니다.
관련 에러
57P01(admin_shutdown): 관리자가pg_terminate_backend()또는 서버 셧다운으로 세션을 강제 종료했을 때 발생합니다.57P02(crash_shutdown): 서버 크래시로 인해 세션이 비정상 종료될 때 발생합니다.57P03(cannot_connect_now): 서버가 시작 중이거나 복구 중이어서 접속이 불가능할 때 발생합니다.57P04(database_dropped): 세션이 연결된 데이터베이스가 삭제되었을 때 발생합니다.25P03(idle_in_transaction_session_timeout):idle_session_timeout과 유사하지만, 트랜잭션 내에서 idle 상태일 때 적용되는 별도의 타임아웃 에러로,idle_in_transaction_session_timeout파라미터로 제어됩니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.