PostgreSQL 57P03 오류 원인과 해결 방법 완벽 가이드

57P03
2026년 07월 19일 | DBMS Error 가이드

이 글에서 다루는 내용

57P03 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.

57P03 cannot connect now 는?

PostgreSQL 에러 코드 57P03 (cannot connect now)는 데이터베이스 서버가 현재 클라이언트의 연결 요청을 수락할 수 없는 상태일 때 발생합니다. 주로 서버가 시작 중(startup), 종료 중(shutdown), 또는 복구 중(recovery) 상태에 있을 때 이 에러가 반환됩니다. 일반 운영 환경에서는 흔하지 않지만, 유지보수 작업이나 장애 복구 시 DBA가 반드시 마주치게 되는 중요한 에러입니다.


주요 발생 원인

1. 서버 시작 또는 재시작 진행 중

PostgreSQL 서버가 pg_ctl start 또는 재시작 명령 이후 초기화 작업을 완료하지 않은 상태에서 클라이언트가 연결을 시도하면 이 에러가 발생합니다. 서버는 내부적으로 shared memory 초기화, WAL 복구, background worker 기동 등의 절차를 완료해야 비로소 연결을 수락합니다. 특히 대용량 데이터베이스 환경에서는 기동 시간이 길어질 수 있어 자동화 스크립트에서 충분한 대기 시간을 두지 않으면 이 에러가 반복적으로 발생합니다.

2. Hot Standby / 스탠바이 서버의 복구 모드

스트리밍 복제(Streaming Replication) 환경에서 스탠바이 서버가 WAL 복구를 진행하는 동안, hot_standby 파라미터가 off로 설정되어 있거나 아직 복구가 충분히 진행되지 않은 시점에 연결을 시도하면 57P03 에러가 발생합니다. HA(High Availability) 구성에서 자동 Failover 이후 신규 Primary가 완전히 준비되기 전에 애플리케이션이 재연결을 시도하는 경우가 대표적인 예입니다. 이 경우 복구 완료 시점을 모니터링하여 연결 시도를 제어하는 것이 중요합니다.

3. pg_ctl stop 또는 pg_terminate_backend 에 의한 종료 진행 중

pg_ctl stop -m fast 또는 pg_ctl stop -m smart 명령으로 서버가 종료 중인 상태에서 새로운 연결이 들어오면 57P03 에러가 반환됩니다. Smart 모드의 경우 기존 세션이 정리될 때까지 대기하므로 종료 시간이 길어질 수 있으며, 이 기간 동안 신규 연결은 모두 거부됩니다. 계획된 유지보수 작업 시에는 애플리케이션 단에서 연결 풀을 먼저 비우고 서버 종료를 시작하는 절차를 반드시 수립해야 합니다.


해결 방법

원인 1: 서버 기동 완료 대기

서버가 완전히 기동될 때까지 반복적으로 연결을 시도하는 쉘 스크립트나 SQL을 활용합니다.

-- 서버 준비 상태 확인 (pg_isready 명령어 활용 예시를 SQL로 표현)
-- psql 연결 전 아래 뷰로 서버 상태 확인 가능
SELECT pg_postmaster_start_time();

-- 서버 기동 후 연결 가능 여부 확인
SELECT now() - pg_postmaster_start_time() AS uptime;
-- 서버가 정상 기동되었는지 확인하는 쿼리
SELECT state, wait_event_type, wait_event
FROM pg_stat_activity
WHERE pid = pg_backend_pid();

실무에서는 아래와 같은 쉘 루프를 자동화 스크립트에 삽입합니다.

-- 연결 가능 상태가 될 때까지 폴링하는 방식 (psql 내에서 메타 정보 확인)
-- 아래는 연결 성공 후 서버 상태를 점검하는 쿼리
SELECT version();
SELECT pg_is_in_recovery();  -- false이면 Primary, true이면 Standby/복구 중

원인 2: Hot Standby 복구 상태 확인 및 대기

스탠바이 서버가 복구를 완료했는지 확인합니다.

-- 복구 진행 상태 확인
SELECT pg_is_in_recovery();

-- 복구 중이라면 현재 수신된 WAL 위치와 재생 위치 확인
SELECT
    pg_last_wal_receive_lsn()  AS receive_lsn,
    pg_last_wal_replay_lsn()   AS replay_lsn,
    pg_last_xact_replay_timestamp() AS last_replay_time,
    now() - pg_last_xact_replay_timestamp() AS replication_lag;
-- hot_standby 파라미터 현재 값 확인
SHOW hot_standby;

-- postgresql.conf에서 hot_standby 활성화 후 재기동 필요
-- hot_standby = on  (postgresql.conf 설정)

원인 3: 서버 종료 상태 모니터링

종료 중인 서버의 상태를 사전에 확인하고, 연결 시도를 제어합니다.

-- 현재 활성 연결 수 및 상태 확인 (종료 전 점검용)
SELECT
    count(*)                        AS total_connections,
    count(*) FILTER (WHERE state = 'active')   AS active,
    count(*) FILTER (WHERE state = 'idle')     AS idle,
    count(*) FILTER (WHERE state = 'idle in transaction') AS idle_in_tx
FROM pg_stat_activity
WHERE datname IS NOT NULL;
-- 특정 데이터베이스의 모든 연결을 안전하게 종료한 후 서버 shutdown
-- 1단계: 새 연결 차단
REVOKE CONNECT ON DATABASE mydb FROM PUBLIC;

-- 2단계: 기존 연결 강제 종료
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE datname = 'mydb'
  AND pid <> pg_backend_pid();

-- 3단계: 서버 종료 (OS 레벨에서 pg_ctl stop 실행)
-- max_connections 설정 확인
SHOW max_connections;

-- 현재 사용 중인 연결 수 확인
SELECT count(*) FROM pg_stat_activity;

예방 방법

1. 연결 재시도 로직(Retry Logic) 및 연결 풀러(Connection Pooler) 도입

애플리케이션 레벨에서 57P03 에러를 포함한 일시적 연결 에러에 대해 지수 백오프(Exponential Backoff) 방식의 재시도 로직을 반드시 구현하세요. PgBouncer나 Pgpool-II 같은 커넥션 풀러를 앞단에 두면, 서버 재시작 시에도 풀러가 연결 복구를 대신 처리해 주어 애플리케이션 레벨의 에러 노출을 최소화할 수 있습니다. 또한 pg_isready 명령어를 배포 파이프라인과 헬스체크에 통합하여 서버가 준비 상태인지 확인한 후 트래픽을 전환하는 절차를 수립하세요.

-- pg_isready 활용 예 (쉘 명령어이지만 참고용)
-- pg_isready -h localhost -p 5432 -d mydb
-- 반환 코드: 0 = 정상, 1 = 연결 거부, 2 = 응답 없음, 3 = 파라미터 오류

-- 연결 풀러 상태 확인을 위한 모니터링 쿼리 (PgBouncer 사용 시)
-- SHOW POOLS;  (PgBouncer 콘솔에서 실행)

-- PostgreSQL 서버에서 연결 상태 지속 모니터링
SELECT client_addr, state, wait_event, query_start, state_change
FROM pg_stat_activity
ORDER BY query_start;

2. 유지보수 절차 표준화 및 postgresql.conf 파라미터 튜닝

계획된 서버 재시작이나 유지보수 시에는 반드시 표준화된 절차(Runbook)를 따르세요. pg_ctl reload로 해결 가능한 파라미터 변경은 재시작 없이 처리하고, 재시작이 필요한 경우 Low-traffic 시간대를 선택합니다. hot_standby = on, wal_level = replica 이상으로 설정하여 스탠바이에서 읽기 쿼리를 허용하고, 페일오버 시 57P03 에러 노출 시간을 줄이세요.

-- 재시작 없이 반영 가능한 파라미터 확인
SELECT name, setting, context
FROM pg_settings
WHERE context IN ('postmaster', 'sighup')
ORDER BY context, name;

-- 현재 hot_standby 및 wal_level 설정 확인
SHOW wal_level;
SHOW hot_standby;

-- 파라미터 변경 후 reload (재시작 불필요한 경우)
SELECT pg_reload_conf();

관련 에러

  • 57P01 (admin_shutdown): 관리자가 명시적으로 서버를 종료했을 때 발생하는 에러로, 57P03과 함께 서버 가용성 관련 에러군에 속합니다.
  • 57P02 (crash_shutdown): 서버가 비정상 종료(crash)된 후 복구 중일 때 발생하며, 57P03과 증상이 유사합니다.
  • 53300 (too_many_connections): max_connections 한도 초과로 연결이 거부될 때 발생하며, 57P03과 함께 연결 실패의 주요 원인입니다.
  • 08006 (connection_failure): 네트워크 레벨의 연결 실패로, 57P03이 서버 상태 문제라면 08006은 물리적 연결 문제에 해당합니다.
  • 08001 (sqlclient_unable_to_establish_sqlconnection): 클라이언트가 연결 자체를 수립하지 못할 때 발생하며, 57P03과 혼동되기 쉬운 에러입니다.

DBMS 에러 코드 시리즈

주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.

본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.

댓글 남기기