2026년 09월 22일 | DBMS Error 가이드
이 글에서 다루는 내용
57P02 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
57P02 crash shutdown 는?
PostgreSQL 에러 코드 57P02 crash_shutdown은 데이터베이스 서버가 비정상적으로 종료(크래시)된 후, 클라이언트 세션이 해당 사실을 인지하거나 서버 복구 과정 중 연결이 끊어질 때 발생하는 에러입니다. 일반적으로 서버 프로세스(postmaster)가 예기치 않게 종료되거나, 운영 체제 수준의 OOM(Out of Memory) Killer, 하드웨어 장애, 또는 pg_ctl stop -m immediate 명령처럼 강제 종료 명령이 실행될 때 트리거됩니다. 이 에러는 단순한 쿼리 오류가 아니라 서버 인프라 수준의 심각한 문제를 나타내므로, 반드시 원인을 파악하고 데이터 무결성을 확인해야 합니다.
주요 발생 원인
1. OS 레벨 OOM Killer에 의한 PostgreSQL 프로세스 강제 종료
리눅스 운영 체제는 메모리가 부족해지면 OOM(Out of Memory) Killer를 통해 메모리를 많이 사용하는 프로세스를 강제로 종료합니다. PostgreSQL의 백엔드 프로세스 또는 postmaster 자체가 OOM Killer의 대상이 되면, 서버가 크래시 셧다운 상태로 진입하며 모든 활성 세션이 57P02 에러를 수신하게 됩니다. 특히 work_mem 설정이 과도하게 높거나 동시 접속 수가 많을 경우 이 문제가 빈번하게 발생합니다.
2. 하드웨어 장애 또는 스토리지 I/O 에러
디스크 오류, RAID 컨트롤러 장애, SAN/NAS 스토리지 연결 불안정 등 하드웨어 수준의 문제는 PostgreSQL이 데이터를 디스크에 안전하게 쓰지 못하게 만들고, 결국 서버 프로세스가 PANIC 상태로 전환되어 강제 종료됩니다. PostgreSQL은 데이터 무결성을 최우선으로 하기 때문에, 스토리지에서 예기치 않은 에러가 발생하면 스스로 크래시를 유발하는 방어적 메커니즘을 갖고 있습니다. 이 경우 PostgreSQL 로그에는 PANIC 또는 could not write to file 관련 메시지가 선행하여 기록됩니다.
3. 잘못된 PostgreSQL 설정 또는 강제 종료 명령 실행
pg_ctl stop -m immediate 또는 kill -9를 이용한 강제 종료는 PostgreSQL이 WAL(Write-Ahead Log)을 정상적으로 플러시하지 못한 상태에서 프로세스를 중단시킵니다. 또한 shared_buffers, max_connections, huge_pages 등 메모리 관련 파라미터를 시스템 리소스 이상으로 설정하면 서버 기동 자체가 실패하거나, 런타임 중 크래시가 발생할 수 있습니다. 관리자의 실수나 배포 스크립트의 오류로 발생하는 경우도 적지 않습니다.
해결 방법
1단계: 서버 상태 및 로그 확인
먼저 PostgreSQL 로그를 통해 크래시 원인을 파악해야 합니다.
-- PostgreSQL 로그에서 최근 PANIC, FATAL 메시지 확인
-- (psql로 접속 가능한 경우)
SELECT log_time, error_severity, message
FROM pg_log -- pg_log는 로그 테이블을 외부 테이블로 구성한 경우
ORDER BY log_time DESC
LIMIT 20;
-- 현재 서버 상태 확인 (접속 가능한 경우)
SELECT pg_postmaster_start_time() AS server_start_time,
now() - pg_postmaster_start_time() AS uptime,
version() AS pg_version;
OS 레벨에서는 다음 명령으로 OOM Killer 발생 여부를 확인합니다.
# OOM Killer 로그 확인
sudo dmesg | grep -i "oom\|killed process"
sudo grep -i "out of memory\|oom" /var/log/syslog
2단계: 크래시 복구 (자동 복구 확인)
PostgreSQL은 크래시 후 재시작 시 WAL 기반 자동 복구(crash recovery)를 수행합니다.
# PostgreSQL 서비스 재시작
sudo systemctl restart postgresql
# 복구 진행 상황은 로그에서 확인
sudo tail -f /var/log/postgresql/postgresql-*.log
복구 완료 후 데이터 무결성을 확인합니다.
-- 데이터베이스 무결성 체크 (pg_catalog 접근 가능 여부 확인)
SELECT datname, pg_size_pretty(pg_database_size(datname)) AS size
FROM pg_database
ORDER BY pg_database_size(datname) DESC;
-- 테이블 레벨 무결성 체크
-- (특정 테이블이 의심스러운 경우)
SELECT schemaname, tablename, pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) AS total_size
FROM pg_tables
WHERE schemaname = 'public'
ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC;
3단계: OOM 문제 해결 – 메모리 설정 최적화
-- 현재 메모리 관련 설정 확인
SHOW work_mem;
SHOW shared_buffers;
SHOW max_connections;
-- 세션별 메모리 사용량 확인
SELECT pid,
usename,
application_name,
pg_size_pretty(query_mem) AS query_mem
FROM (
SELECT pid,
usename,
application_name,
(SELECT setting::bigint * 1024
FROM pg_settings
WHERE name = 'work_mem') AS query_mem
FROM pg_stat_activity
WHERE state != 'idle'
) sub
ORDER BY query_mem DESC;
postgresql.conf에서 아래 파라미터를 조정합니다.
-- work_mem 을 세션 레벨에서 낮춰 OOM 방지
ALTER SYSTEM SET work_mem = '64MB'; -- 전체 서버 기본값 조정
ALTER SYSTEM SET shared_buffers = '4GB'; -- 전체 RAM의 25% 권장
ALTER SYSTEM SET max_connections = '200'; -- 실제 필요한 수준으로 제한
-- 설정 반영 (일부는 재시작 필요)
SELECT pg_reload_conf();
4단계: 스토리지 I/O 에러 점검
-- PostgreSQL 데이터 디렉토리 확인
SHOW data_directory;
-- 임시 파일 사용량 확인 (스토리지 압박 여부)
SELECT datname,
temp_files,
pg_size_pretty(temp_bytes) AS temp_size
FROM pg_stat_database
ORDER BY temp_bytes DESC;
# OS 레벨에서 디스크 에러 확인
sudo dmesg | grep -i "i/o error\|scsi\|ata"
sudo smartctl -a /dev/sda # SMART 디스크 상태 확인
5단계: 강제 종료로 인한 복구 (최후 수단)
자동 복구가 실패한 경우, WAL 복구를 강제 실행할 수 있습니다.
# PostgreSQL 단일 사용자 모드로 복구 시도
sudo -u postgres postgres --single -D /var/lib/postgresql/data postgres
# pg_resetwal은 마지막 수단 (데이터 손실 위험!)
# 반드시 백업 후 실행
sudo -u postgres pg_resetwal -D /var/lib/postgresql/data
-- 복구 후 VACUUM FULL로 테이블 정리
VACUUM FULL ANALYZE;
-- 복구 후 시스템 카탈로그 무결성 확인
SELECT count(*) FROM pg_class;
SELECT count(*) FROM pg_attribute;
예방 방법
1. 메모리 및 리소스 모니터링 자동화와 OOM 방지 설정
PostgreSQL 프로세스가 OOM Killer의 대상이 되지 않도록 /proc/PID/oom_score_adj 값을 조정하고, Prometheus + pg_stat_statements를 활용한 실시간 메모리 모니터링 체계를 구축하세요. work_mem은 서버 전체 기본값을 낮게 유지하고, 필요한 쿼리에서만 세션 단위로 높이는 패턴을 사용하는 것이 안전합니다.
-- 세션 단위 work_mem 조정 패턴 (Best Practice)
SET work_mem = '256MB'; -- 이 세션에서만 높임
SELECT * FROM large_table ORDER BY some_column;
RESET work_mem; -- 쿼리 후 원래대로 복원
2. WAL 아카이빙과 정기적인 백업 및 복구 테스트
크래시 발생 시 데이터 손실을 최소화하려면 WAL 아카이빙을 활성화하고, PITR(Point-In-Time Recovery) 환경을 반드시 구성해야 합니다. 또한 월 1회 이상 실제 복구 테스트를 수행하여 백업의 유효성을 검증하고, pg_basebackup 또는 pgBackRest 같은 전문 백업 도구를 사용하는 것을 강력히 권장합니다.
-- WAL 아카이빙 설정 확인
SHOW archive_mode;
SHOW archive_command;
SHOW wal_level;
-- 아카이빙 상태 확인
SELECT * FROM pg_stat_archiver;
관련 에러
57P01(admin_shutdown): 관리자가pg_ctl stop -m fast또는SELECT pg_terminate_backend()로 정상적으로 서버를 종료할 때 발생하는 에러로,57P02와 달리 계획된 종료입니다.08006(connection_failure): 크래시 이후 클라이언트가 재연결을 시도할 때 연결 자체가 실패하는 경우 발생합니다.XX000(internal_error): PostgreSQL 내부 로직에서 처리할 수 없는 상태가 발생했을 때 나타나며, 크래시의 전조 증상으로 로그에 함께 기록되는 경우가 많습니다.53200(out_of_memory): PostgreSQL 내부에서 메모리 할당에 실패했을 때 발생하며, OOM으로 인한57P02직전에 로그에 기록될 수 있습니다.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.