2026년 09월 22일 | DBMS Error 가이드
이 글에서 다루는 내용
57P01 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
57P01 admin shutdown 는?
PostgreSQL 에러 코드 57P01 admin_shutdown은 데이터베이스 관리자가 서버를 명시적으로 종료하거나 재시작할 때 현재 연결 중인 클라이언트 세션에 전달되는 에러입니다. 이 에러는 서버 측에서 강제로 연결을 끊는 상황, 즉 pg_ctl stop, systemctl stop postgresql, 또는 SQL 레벨의 SELECT pg_terminate_backend() 호출 시 발생할 수 있습니다. 일반적으로 애플리케이션 레벨에서는 갑작스러운 연결 해제로 인식되며, 트랜잭션이 진행 중이었다면 해당 작업은 롤백 처리됩니다.
주요 발생 원인
- 관리자에 의한 계획된 서버 종료 (Planned Shutdown)
운영 환경에서 패치 적용, 설정 변경, 또는 정기 점검을 위해 DBA가 PostgreSQL 서버를 정지시키는 경우가 가장 흔한 원인입니다. pg_ctl stop -m fast 명령어는 현재 활성 세션에 즉시 종료 신호를 보내기 때문에, 연결을 유지하고 있던 클라이언트는 57P01 에러를 수신하게 됩니다. 특히 배치 작업이나 장시간 실행 중인 쿼리가 있는 경우, 예고 없이 서버가 종료되면 데이터 정합성 문제로 이어질 수 있습니다.
pg_terminate_backend()함수 호출에 의한 강제 세션 종료
DBA가 특정 세션의 장시간 실행 쿼리, 데드락, 또는 과도한 리소스 사용 등을 이유로 pg_terminate_backend() 함수를 사용하여 특정 프로세스를 강제 종료할 때 발생합니다. 이 경우 종료된 세션의 클라이언트는 57P01 에러를 받으며, 진행 중이던 트랜잭션은 자동으로 롤백됩니다. 모니터링 시스템이나 자동화 스크립트가 idle 세션을 청소하는 과정에서도 의도치 않게 발생할 수 있습니다.
- 클라우드 환경 또는 HA 구성에서의 자동 Failover / 재시작
AWS RDS, Azure Database for PostgreSQL, GCP Cloud SQL 같은 클라우드 관리형 서비스나 Patroni, Repmgr 기반의 고가용성 구성에서 자동 Failover가 발생할 때, 기존 Primary 서버의 연결들이 강제로 종료되며 57P01이 발생합니다. 또한 클라우드 인프라의 예약된 유지 보수(Maintenance Window) 작업 중에도 동일한 에러가 발생합니다. 이 경우 애플리케이션이 자동으로 새로운 Primary에 재접속하는 로직을 갖추지 않으면 서비스 장애로 이어집니다.
해결 방법
원인 1: 계획된 서버 종료 시 안전하게 처리하기
서버를 종료하기 전에 현재 활성 세션과 실행 중인 트랜잭션 현황을 먼저 확인하는 것이 좋습니다.
-- 현재 활성 연결 및 실행 중인 쿼리 확인
SELECT
pid,
usename,
application_name,
client_addr,
state,
query_start,
now() - query_start AS query_duration,
left(query, 100) AS query_preview
FROM pg_stat_activity
WHERE state != 'idle'
AND pid != pg_backend_pid()
ORDER BY query_start;
서버 종료 전 smart 모드를 사용하면 기존 연결이 자연스럽게 종료될 때까지 기다립니다.
# Smart 모드: 새 연결은 거부하되 기존 연결이 끝날 때까지 대기
pg_ctl stop -m smart -D /var/lib/postgresql/data
# Fast 모드: 즉시 종료 (일반적으로 많이 사용)
pg_ctl stop -m fast -D /var/lib/postgresql/data
원인 2: 특정 세션을 안전하게 종료하기
장시간 실행 중인 쿼리나 문제가 되는 세션을 식별하고 단계적으로 종료합니다.
-- 10분 이상 실행 중인 쿼리 목록 조회
SELECT
pid,
usename,
application_name,
state,
now() - query_start AS running_time,
wait_event_type,
wait_event,
left(query, 200) AS query_text
FROM pg_stat_activity
WHERE state = 'active'
AND query_start < now() - interval '10 minutes'
AND pid != pg_backend_pid()
ORDER BY running_time DESC;
-- 1단계: pg_cancel_backend로 현재 쿼리만 취소 (세션 유지)
SELECT pg_cancel_backend(pid)
FROM pg_stat_activity
WHERE state = 'active'
AND query_start < now() - interval '10 minutes'
AND pid != pg_backend_pid();
-- 2단계: 쿼리 취소가 안 되는 경우 세션 자체를 종료
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE state = 'active'
AND query_start < now() - interval '30 minutes'
AND pid != pg_backend_pid();
-- idle 상태로 오래된 세션 정리 (30분 이상 idle)
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE state = 'idle'
AND state_change < now() - interval '30 minutes'
AND usename != 'replication'
AND pid != pg_backend_pid();
원인 3: 애플리케이션에서의 재연결 로직 구현
57P01 에러 발생 시 애플리케이션이 자동으로 재연결하도록 Connection Pool 설정이나 코드 레벨에서 처리합니다.
-- 연결 풀(PgBouncer 사용 시) 상태 확인
-- PgBouncer admin console에서 실행
SHOW POOLS;
SHOW CLIENTS;
SHOW SERVERS;
-- PostgreSQL 서버 재시작 후 연결 상태 확인
SELECT
count(*) AS total_connections,
state,
usename
FROM pg_stat_activity
GROUP BY state, usename
ORDER BY total_connections DESC;
애플리케이션 설정(예: JDBC)에서는 아래와 같이 자동 재연결 옵션을 활성화할 수 있습니다.
-- 연결 파라미터 확인 (현재 세션)
SHOW tcp_keepalives_idle;
SHOW tcp_keepalives_interval;
SHOW tcp_keepalives_count;
-- 서버 레벨 TCP Keepalive 설정 (postgresql.conf)
-- tcp_keepalives_idle = 60 (60초 idle 후 keepalive 시작)
-- tcp_keepalives_interval = 10 (10초 간격으로 재시도)
-- tcp_keepalives_count = 5 (5번 실패 시 연결 종료)
예방 방법
- Connection Pooler 및 자동 재연결 로직 도입
PgBouncer나 pgpool-II 같은 Connection Pooler를 애플리케이션과 PostgreSQL 사이에 배치하면, 서버 재시작 시 클라이언트 연결을 자동으로 관리할 수 있습니다. PgBouncer의 server_lifetime, server_idle_timeout 파라미터를 적절히 설정하고, 애플리케이션 레벨에서도 57P01 에러 코드를 감지하여 자동 재연결을 시도하는 예외 처리 로직을 반드시 구현해야 합니다. 특히 Spring Boot + HikariCP 조합을 사용하는 경우 connectionTestQuery, keepaliveTime, idleTimeout 설정을 검토하세요.
- 서버 종료 전 사전 공지 및 Graceful Shutdown 절차 수립
운영 환경에서 계획된 서버 종료가 필요한 경우, pg_ctl stop -m smart 모드를 우선 시도하고, 일정 시간이 지나도 연결이 남아 있다면 단계적으로 fast 모드로 전환하는 표준 절차를 수립해야 합니다. 또한 PostgreSQL의 log_connections, log_disconnections 파라미터를 활성화하여 세션 종료 이벤트를 로그로 남기고, 이를 중앙 로그 시스템(ELK, Grafana Loki 등)과 연동하여 57P01 발생 패턴을 사전에 모니터링하는 체계를 갖추는 것이 중요합니다.
관련 에러
57P02(crash_shutdown): 서버가 비정상적으로 크래시될 때 발생하는 에러로,57P01의 비계획적 버전입니다. 복구 시 WAL 재생이 필요합니다.57P03(cannot_connect_now): 서버가 시작 중이거나 복구 중일 때 연결을 시도하면 발생하며,57P01이후 재연결 시 마주칠 수 있습니다.08006(connection_failure): 네트워크 레벨의 연결 실패로, Failover 상황에서57P01과 함께 발생할 수 있습니다.08001(sqlclient_unable_to_establish_sqlconnection): 클라이언트가 서버에 연결 자체를 못하는 경우로, 서버 종료 후 재연결 시도 시 발생합니다.25P03(idle_in_transaction_session_timeout):idle_in_transaction_session_timeout설정에 의해 세션이 종료될 때 발생하며,pg_terminate_backend()와 유사한 결과를 냅니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.