2026년 07월 19일 | DBMS Error 가이드
이 글에서 다루는 내용
57P02 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
57P02 crash shutdown 는?
PostgreSQL 에러 코드 57P02 crash_shutdown은 데이터베이스 서버가 비정상적으로 종료되었음을 나타내는 에러입니다. 이 에러는 서버가 예기치 않게 크래시(crash)되거나 강제 종료된 후, 클라이언트 연결이 끊어졌을 때 발생합니다. 일반적으로 PostgreSQL 백엔드 프로세스가 시그널(SIGQUIT 등)을 받아 즉시 종료되거나, 운영체제 수준의 OOM(Out of Memory) Killer에 의해 프로세스가 강제 종료될 때 이 에러 코드와 함께 연결이 단절됩니다.
주요 발생 원인
- OOM(Out of Memory) Killer에 의한 프로세스 강제 종료
리눅스 커널의 OOM Killer는 시스템 메모리가 극도로 부족해지면 메모리를 많이 사용하는 프로세스를 강제로 종료합니다. PostgreSQL의 postmaster 또는 개별 백엔드 프로세스가 OOM Killer에 의해 종료될 경우, 모든 현재 연결은 57P02 crash_shutdown 에러와 함께 끊어집니다. 특히 work_mem이나 shared_buffers를 과도하게 설정했거나, 대용량 정렬/해시 조인 쿼리가 동시에 다수 실행될 때 발생 빈도가 높습니다.
- SIGQUIT 시그널 수신 또는
pg_ctl stop -m immediate실행
PostgreSQL은 SIGQUIT 시그널을 받으면 체크포인트나 WAL 플러시 없이 즉시 모든 프로세스를 종료합니다. DBA가 실수로 pg_ctl stop -m immediate 명령을 실행하거나, 운영체제 재부팅/패닉 상황에서 PostgreSQL 프로세스가 갑작스럽게 종료될 때 이 에러가 발생합니다. 이 경우 다음 기동 시 반드시 crash recovery(WAL replay)가 수행됩니다.
- 하드웨어 장애 또는 스토리지 I/O 에러
디스크 장애, RAID 컨트롤러 오류, SAN/NAS 스토리지의 연결 불안정 등 하드웨어 수준의 문제가 발생하면 PostgreSQL이 데이터 파일에 접근하지 못하게 되고, 이로 인해 postmaster가 PANIC 상태로 전환되어 즉시 종료됩니다. 스토리지 I/O 에러는 pg_log에 could not write to file, fsync failed 등의 메시지와 함께 기록되며, 이후 연결된 모든 세션은 57P02 에러를 경험하게 됩니다.
해결 방법
원인 1: OOM Killer 대응
먼저 OOM 발생 여부를 시스템 로그에서 확인합니다.
# 리눅스 시스템 로그에서 OOM 이벤트 확인
sudo dmesg | grep -i "oom\|killed"
sudo grep -i "oom\|out of memory" /var/log/syslog
PostgreSQL 설정에서 메모리 파라미터를 적절히 조정합니다.
-- 현재 메모리 관련 설정 확인
SHOW shared_buffers;
SHOW work_mem;
SHOW max_connections;
-- 메모리 사용량 추정 (대략적인 최대 메모리 사용량)
-- max_connections * work_mem 이 전체 RAM의 20~25%를 넘지 않도록 조정
SELECT
current_setting('max_connections')::int AS max_conn,
pg_size_pretty(
current_setting('work_mem') :: bigint *
current_setting('max_connections') :: bigint
) AS estimated_max_work_mem;
Linux의 OOM Killer로부터 PostgreSQL을 보호하려면 oom_score_adj 값을 조정합니다.
# PostgreSQL postmaster PID 확인
cat /var/run/postgresql/*.pid
# OOM 점수 낮추기 (값이 낮을수록 종료 우선순위 낮음)
echo -1000 > /proc/$(cat /var/run/postgresql/*.pid)/oom_score_adj
원인 2: 서버 재기동 후 복구 확인
크래시 이후 PostgreSQL을 재시작하면 자동으로 WAL 기반 crash recovery가 수행됩니다.
# PostgreSQL 서비스 재시작
sudo systemctl restart postgresql
# 또는 pg_ctl을 통한 재시작
pg_ctl start -D /var/lib/postgresql/data -l /var/log/postgresql/startup.log
복구 완료 후 데이터 정합성을 확인합니다.
-- 데이터베이스 무결성 확인 (amcheck 확장 사용)
CREATE EXTENSION IF NOT EXISTS amcheck;
-- 인덱스 무결성 검사
SELECT bt_index_check(oid)
FROM pg_class
WHERE relkind = 'i' AND relnamespace NOT IN (
SELECT oid FROM pg_namespace WHERE nspname = 'pg_catalog'
);
-- 테이블 통계 재수집 (복구 후 권장)
ANALYZE VERBOSE;
-- 현재 트랜잭션 상태 확인
SELECT pid, state, query_start, wait_event_type, query
FROM pg_stat_activity
WHERE state != 'idle';
원인 3: 스토리지 I/O 에러 대응
PostgreSQL 로그에서 스토리지 관련 에러를 확인합니다.
-- PostgreSQL 로그 위치 확인
SHOW log_directory;
SHOW data_directory;
-- pg_log에서 최근 에러 확인 (log_fdw 사용 시)
-- 또는 직접 로그 파일 조회
# 디스크 상태 확인
sudo smartctl -a /dev/sda
sudo iostat -x 1 5
# 파일시스템 에러 확인
sudo dmesg | grep -i "error\|fail\|i/o"
데이터 파일 손상 여부를 pg_filedump나 pg_checksums로 확인합니다.
# PostgreSQL 데이터 체크섬 확인 (initdb 시 --data-checksums 옵션 사용한 경우)
pg_checksums --check -D /var/lib/postgresql/data
-- 체크섬 에러 발생 시 해당 페이지 확인
SELECT * FROM pg_stat_database WHERE checksum_failures > 0;
-- 특정 테이블의 체크섬 에러 확인
SELECT checksum_failures, stats_reset
FROM pg_stat_database
WHERE datname = current_database();
예방 방법
- 모니터링 및 알림 체계 구축
PostgreSQL의 pg_stat_activity, pg_stat_bgwriter, pg_stat_database 뷰를 주기적으로 모니터링하고, Prometheus + pg_exporter 또는 Zabbix 같은 모니터링 도구를 활용해 메모리 사용량, 디스크 I/O, 연결 수에 대한 임계값 알림을 설정하는 것이 중요합니다. 특히 postgresql.conf에서 log_min_messages = WARNING 이상으로 설정하고, 로그를 외부 시스템(ELK, CloudWatch 등)으로 전송하여 크래시 징후를 사전에 감지할 수 있어야 합니다.
“`sql
— 로그 설정 강화
ALTER SYSTEM SET log_min_messages = ‘WARNING’;
ALTER SYSTEM SET log_checkpoints = on;
ALTER SYSTEM SET log_connections = on;
ALTER SYSTEM SET log_disconnections = on;
ALTER SYSTEM SET log_line_prefix = ‘%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h ‘;
SELECT pg_reload_conf();
“`
- 정기적인 백업 및 WAL 아카이빙 설정
크래시 발생 시 데이터 손실을 최소화하기 위해 pg_basebackup을 이용한 정기 베이스 백업과 함께 WAL 아카이빙을 반드시 활성화해야 합니다. archive_mode = on, archive_command를 설정하여 WAL 파일을 안전한 외부 스토리지에 보관하면, 크래시 이후 PITR(Point-In-Time Recovery)을 통해 특정 시점으로 데이터를 복구할 수 있습니다.
“`sql
— WAL 아카이빙 설정 확인
SHOW archive_mode;
SHOW archive_command;
SHOW wal_level;
— 아카이빙 상태 확인
SELECT * FROM pg_stat_archiver;
— 마지막 성공한 아카이브 확인
SELECT last_archived_wal, last_archived_time, last_failed_wal, last_failed_time
FROM pg_stat_archiver;
“`
관련 에러
- 57P01 (admin_shutdown): DBA가
pg_terminate_backend()또는pg_ctl stop -m fast로 정상적으로 서버를 종료할 때 발생하는 에러로,57P02와 달리 계획된 종료입니다. - 57P03 (cannot_connect_now): PostgreSQL이 기동 중(startup recovery 또는 crash recovery 진행 중)일 때 연결을 시도하면 발생하는 에러입니다.
57P02이후 재기동 과정에서 자주 함께 목격됩니다. - 08006 (connection_failure): 네트워크 레벨에서 연결이 끊어질 때 발생하며,
57P02와 증상이 유사하지만 원인은 네트워크에 있습니다. - XX000 (internal_error): PostgreSQL 내부 오류로 인해 백엔드 프로세스가 비정상 종료될 때 발생하며, 이로 인해 연쇄적으로
57P02가 발생할 수 있습니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.