2026년 07월 18일 | DBMS Error 가이드
이 글에서 다루는 내용
57000 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
57000 operator intervention 는?
PostgreSQL 에러 코드 57000은 operator intervention 카테고리에 속하며, DBA 또는 시스템 관리자가 의도적으로 혹은 특정 조건에 의해 데이터베이스 작업을 강제로 중단시켰을 때 발생하는 에러입니다. 단순한 쿼리 오류가 아니라, 외부 개입(Operator Intervention)으로 인해 정상적으로 실행 중이던 세션이나 트랜잭션이 종료된 상황을 의미합니다. 이 에러는 57014(query_canceled), 57P01(admin_shutdown), 57P02(crash_shutdown), 57P03(cannot_connect_now) 등 더 구체적인 하위 에러 코드들의 부모 카테고리 역할을 합니다.
주요 발생 원인
1. pg_cancel_backend() 또는 pg_terminate_backend() 호출
가장 흔한 원인으로, DBA가 장시간 실행되는 쿼리나 잠금을 유발하는 세션을 강제로 종료할 때 발생합니다. pg_cancel_backend()는 현재 실행 중인 쿼리만 취소하고 세션은 유지하지만, pg_terminate_backend()는 세션 자체를 완전히 종료시킵니다. 특히 배치 작업이나 ETL 파이프라인이 실행 중일 때 DBA가 이 함수를 호출하면 어플리케이션 단에서 57000 계열의 에러가 발생합니다.
2. statement_timeout 또는 lock_timeout 초과
PostgreSQL 설정에서 statement_timeout이 지정되어 있을 경우, 해당 시간을 초과한 쿼리는 자동으로 취소됩니다. 이 경우 에러 코드 57014(query_canceled)가 발생하며, 이는 57000의 하위 분류입니다. 운영 환경에서 기본값을 잘못 설정하거나, 특정 세션에서 과도하게 짧은 타임아웃이 설정된 경우 정상적인 쿼리도 강제 종료될 수 있습니다.
3. 서버 셧다운 또는 재시작 (admin_shutdown)
PostgreSQL 서버가 pg_ctl stop 또는 systemctl stop postgresql 등의 명령으로 종료될 때, 활성화된 모든 세션에 57P01(admin_shutdown) 에러가 전파됩니다. 이 상황은 예정된 유지보수 창(Maintenance Window) 중에도 발생할 수 있으며, 연결 풀링(Connection Pooling)을 사용 중이라면 풀 내의 연결들이 일제히 무효화됩니다.
해결 방법
원인 1: 강제 세션 종료 대응
현재 실행 중인 장시간 쿼리를 파악하고 선별적으로 취소하세요.
-- 현재 실행 중인 쿼리 목록 확인 (5분 이상 실행 중인 쿼리)
SELECT
pid,
now() - pg_stat_activity.query_start AS duration,
query,
state,
wait_event_type,
wait_event
FROM pg_stat_activity
WHERE (now() - pg_stat_activity.query_start) > INTERVAL '5 minutes'
AND state = 'active';
-- 특정 PID의 쿼리만 취소 (세션 유지)
SELECT pg_cancel_backend(12345);
-- 세션 자체를 완전히 종료 (주의: 롤백 발생)
SELECT pg_terminate_backend(12345);
-- 특정 사용자의 모든 세션 종료 (자신 제외)
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE usename = 'target_user'
AND pid <> pg_backend_pid();
원인 2: 타임아웃 설정 확인 및 조정
-- 현재 세션의 타임아웃 설정 확인
SHOW statement_timeout;
SHOW lock_timeout;
SHOW idle_in_transaction_session_timeout;
-- 세션 레벨에서 타임아웃 조정 (해당 세션에만 적용)
SET statement_timeout = '30min';
SET lock_timeout = '10s';
-- 특정 트랜잭션 내에서만 타임아웃 변경
BEGIN;
SET LOCAL statement_timeout = '1h';
-- 장시간 실행 작업 수행
UPDATE large_table SET col = value WHERE condition;
COMMIT;
-- postgresql.conf에서 전역 설정 확인
-- 아래 쿼리로 현재 적용된 설정 조회
SELECT name, setting, unit, context
FROM pg_settings
WHERE name IN ('statement_timeout', 'lock_timeout', 'idle_in_transaction_session_timeout');
원인 3: 셧다운 감지 및 재연결 로직 구현
-- 현재 서버 상태 및 연결 수 확인
SELECT
count(*) AS total_connections,
state,
wait_event_type
FROM pg_stat_activity
GROUP BY state, wait_event_type
ORDER BY total_connections DESC;
-- 연결이 살아있는지 확인하는 헬스체크 쿼리 (애플리케이션에서 주기적으로 실행)
SELECT 1 AS health_check;
-- 트랜잭션 상태 확인 함수 활용
SELECT txid_current_if_assigned();
-- pg_stat_activity에서 비정상 세션 탐지
SELECT pid, usename, application_name, state, query_start, state_change
FROM pg_stat_activity
WHERE state = 'idle in transaction'
AND state_change < now() - INTERVAL '10 minutes';
예방 방법
1. 적절한 타임아웃 정책 수립 및 계층적 적용
운영 환경에서는 롤(Role) 단위, 데이터베이스 단위, 세션 단위로 계층적인 타임아웃 정책을 수립해야 합니다. 무기한 실행되는 쿼리는 잠금 경쟁을 유발하고 시스템 전체 성능을 저하시킬 수 있으므로, OLTP 롤에는 짧은 statement_timeout을 설정하고 배치/분석 롤에는 별도의 긴 타임아웃을 부여하는 방식을 권장합니다.
-- 역할별 차등 타임아웃 설정
ALTER ROLE oltp_user SET statement_timeout = '30s';
ALTER ROLE batch_user SET statement_timeout = '4h';
ALTER ROLE readonly_user SET statement_timeout = '5min';
-- idle in transaction 세션 자동 정리
ALTER SYSTEM SET idle_in_transaction_session_timeout = '5min';
SELECT pg_reload_conf();
2. 연결 풀링과 재시도(Retry) 로직 구현
PgBouncer 또는 애플리케이션 레벨에서 57000 계열 에러를 감지하고 자동으로 재연결 및 재시도하는 로직을 반드시 구현해야 합니다. 특히 57P01(admin_shutdown)처럼 서버 재시작으로 인한 에러는 예정된 유지보수 시에도 발생할 수 있으므로, 지수 백오프(Exponential Backoff) 전략과 함께 최대 재시도 횟수를 명확히 정의하고, 재시도 불가능한 에러(예: 데이터 무결성 위반)와 재시도 가능한 에러(57000 계열)를 코드 레벨에서 명확히 구분하는 것이 중요합니다.
관련 에러
| 에러 코드 | 이름 | 설명 |
|———–|——|——|
| 57014 | query_canceled | statement_timeout 초과 또는 사용자 취소 시 발생. 가장 자주 마주치는 하위 에러 |
| 57P01 | admin_shutdown | 서버 정상 종료(pg_ctl stop) 시 활성 세션에 전파 |
| 57P02 | crash_shutdown | 서버 비정상 종료(crash) 후 복구 과정에서 발생 |
| 57P03 | cannot_connect_now | 서버가 시작 중이거나 복구 중일 때 새 연결 시도 시 발생 |
| 57P04 | database_dropped | 연결된 데이터베이스가 DROP될 때 해당 세션에 전파 |
| 40001 | serialization_failure | 직렬화 격리 수준에서 충돌 발생 시, 재시도 로직과 함께 57000과 혼동될 수 있음 |
57000 계열의 에러들은 모두 외부 개입이나 시스템 수준의 이벤트로 발생하므로, 애플리케이션의 에러 핸들링 코드에서 이 에러 코드 대역을 명시적으로 처리하여 사용자 경험을 보호하는 것이 DBA와 개발자 모두에게 중요한 실무 역량입니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.