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

F0001
2026년 07월 22일 | DBMS Error 가이드

이 글에서 다루는 내용

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

F0001 lock file exists 는?

PostgreSQL 에러 코드 F0001 lock file exists는 데이터베이스 서버가 시작될 때, 이미 다른 PostgreSQL 프로세스가 실행 중이거나 비정상 종료로 인해 잠금 파일(postmaster.pid)이 남아 있을 때 발생하는 치명적인 에러입니다. PostgreSQL은 시작 시 데이터 디렉터리(PGDATA) 내에 postmaster.pid 파일을 생성하여 현재 실행 중인 프로세스의 PID를 기록하는데, 이 파일이 이미 존재하면 서버는 충돌을 방지하기 위해 시작을 거부합니다. 이 에러는 단순한 설정 오류가 아니라 운영 환경의 상태 이상을 나타내므로, 원인을 정확히 파악하고 신중하게 처리해야 합니다.


주요 발생 원인

1. PostgreSQL 비정상 종료 후 잠금 파일 잔존

서버 크래시, 강제 종료(kill -9), 시스템 전원 차단 등으로 인해 PostgreSQL이 정상적인 종료 절차를 거치지 못하면 postmaster.pid 파일이 삭제되지 않고 데이터 디렉터리에 남게 됩니다. 이후 서버를 재시작하려 할 때, PostgreSQL은 이 파일을 발견하고 이미 다른 인스턴스가 실행 중이라고 판단하여 시작을 거부합니다. 이 경우 실제로 해당 PID의 프로세스가 살아있는지 반드시 확인해야 합니다.

2. 동일 포트/데이터 디렉터리에 여러 PostgreSQL 인스턴스 실행 시도

하나의 서버에서 동일한 PGDATA 경로 또는 동일한 포트 번호를 사용하는 두 번째 PostgreSQL 인스턴스를 실행하려 할 때 이 에러가 발생합니다. 특히 컨테이너(Docker) 환경이나 자동화 스크립트에서 중복 실행이 발생하기 쉽습니다. PostgreSQL은 데이터 무결성을 보호하기 위해 동일 데이터 디렉터리에 대한 다중 접근을 엄격히 차단합니다.

3. 운영체제 재부팅 후 tmpfs 또는 /var/run 초기화 문제

일부 리눅스 배포판에서는 /var/run/postgresql/ 디렉터리가 tmpfs로 마운트되어 재부팅 시 자동으로 초기화됩니다. 반면 데이터 디렉터리 내의 postmaster.pid는 영구 스토리지에 위치하기 때문에 재부팅 후에도 남아 있는 불일치 상태가 생깁니다. 이 경우 소켓 파일은 사라졌지만 PID 파일은 남아 있어 서버 시작이 실패하는 상황이 발생합니다.


해결 방법

원인 1 해결: 잔존 잠금 파일 처리

먼저 postmaster.pid 파일 내에 기록된 PID가 실제로 실행 중인 프로세스인지 확인합니다.

-- PostgreSQL 내부에서 현재 접속 가능한 경우 프로세스 확인
-- (서버가 이미 실행 중일 때)
SELECT pid, usename, application_name, client_addr, state
FROM pg_stat_activity
WHERE pid = pg_backend_pid();
# 셸에서 PID 파일 내용 확인
cat /var/lib/postgresql/data/postmaster.pid

# 해당 PID 프로세스 생존 여부 확인
ps aux | grep <PID>

# 프로세스가 존재하지 않는 경우에만 PID 파일 삭제
rm /var/lib/postgresql/data/postmaster.pid

# PostgreSQL 재시작
pg_ctl start -D /var/lib/postgresql/data

> ⚠️ 경고: postmaster.pid 파일을 삭제하기 전에 반드시 해당 PID의 프로세스가 실제로 존재하지 않음을 확인하세요. 살아있는 프로세스가 있는 상태에서 파일을 삭제하면 데이터 손상이 발생할 수 있습니다.

원인 2 해결: 실행 중인 PostgreSQL 인스턴스 확인 및 정리

-- pg_stat_activity를 통해 현재 연결 현황 파악 (접속 가능한 경우)
SELECT pid, datname, usename, application_name, state, query_start
FROM pg_stat_activity
ORDER BY query_start DESC;
# 실행 중인 PostgreSQL 프로세스 전체 확인
ps aux | grep postgres

# 포트 충돌 여부 확인
ss -tlnp | grep 5432

# 정상 종료 시도
pg_ctl stop -D /var/lib/postgresql/data -m fast

# 위 명령이 실패할 경우 강제 종료 (주의: 데이터 손상 가능성 있음)
pg_ctl stop -D /var/lib/postgresql/data -m immediate

원인 3 해결: 재부팅 후 소켓 디렉터리 재생성

# 소켓 파일 디렉터리 재생성 및 권한 설정
mkdir -p /var/run/postgresql
chown postgres:postgres /var/run/postgresql
chmod 2775 /var/run/postgresql

# PID 파일 확인 후 삭제 (프로세스 없는 경우)
ls -la /var/lib/postgresql/data/postmaster.pid
rm /var/lib/postgresql/data/postmaster.pid

# 서버 재시작
systemctl start postgresql
-- 서버 재시작 후 정상 동작 확인
SELECT version();
SELECT pg_postmaster_start_time();

-- 데이터베이스 목록 확인
SELECT datname, datdba, encoding, datcollate
FROM pg_database
ORDER BY datname;

예방 방법

1. 시스템 서비스로 PostgreSQL 관리 및 셧다운 훅 설정

PostgreSQL을 systemd 서비스로 등록하고, 시스템 종료/재시작 시 항상 정상 종료 절차가 수행되도록 구성합니다. /etc/systemd/system/postgresql.service 파일에 TimeoutStopSec를 충분히 크게 설정하여 체크포인트 완료 후 종료되도록 보장합니다. 또한 모니터링 도구(Prometheus + postgres_exporter, Zabbix 등)를 통해 PostgreSQL 프로세스 상태를 지속적으로 감시하고, 비정상 종료 발생 시 즉시 알림을 받을 수 있도록 구성하세요.

2. 자동화된 상태 점검 스크립트 운영

서버 시작 스크립트에 postmaster.pid 존재 여부와 해당 PID의 실제 프로세스 생존 여부를 사전에 검증하는 로직을 포함시킵니다. 다음과 같은 간단한 점검 쿼리를 주기적으로 실행하여 서버 상태를 모니터링하세요.

-- 서버 상태 모니터링용 쿼리 (cron 또는 모니터링 도구에서 주기적 실행)
SELECT
    pg_postmaster_start_time() AS start_time,
    now() - pg_postmaster_start_time() AS uptime,
    pg_is_in_recovery() AS is_replica,
    current_setting('data_directory') AS data_dir;

관련 에러

  • 57P03 (cannot_connect_now): 서버가 시작 중이거나 복구 중일 때 클라이언트 연결을 거부하는 에러로, F0001과 함께 발생하는 경우가 많습니다.
  • 58P01 (undefined_file): 데이터 디렉터리 내 필수 파일이 누락되었을 때 발생하며, 잠금 파일 삭제 후 다른 파일 손상이 동반될 경우 함께 나타날 수 있습니다.
  • XX000 (internal_error): PostgreSQL 내부 오류로, 비정상 종료 이후 데이터 파일 손상이 있는 경우 F0001 해결 후 연쇄적으로 발생할 수 있으므로, 반드시 pg_dump를 통한 데이터 백업 상태를 점검하세요.

DBMS 에러 코드 시리즈

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

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

댓글 남기기