PostgreSQL PITR과 베이스 백업 — 복구 시점 제어

pg_basebackup으로 베이스 백업을 만들고 WAL 아카이브를 활용해 특정 시점으로 되돌리는 PITR(Point-In-Time Recovery)의 동작 원리, archive_command 설정, recovery_target_time 지정까지 실전 순서로 다룹니다.

· 5 min read · PALDYN Team

지난 글에서 논리 복제를 통해 테이블 단위로 변경을 전파하는 방법을 살펴봤습니다. 이번에는 장애나 실수로 데이터가 손상됐을 때 원하는 시점의 스냅샷으로 정밀하게 되돌리는 PITR(Point-In-Time Recovery)을 다룹니다.

PITR의 핵심 아이디어

PostgreSQL은 모든 변경을 WAL에 기록합니다. 어느 시점의 베이스 백업(Base Backup) 과 그 이후의 WAL 파일만 있으면, 두 데이터를 합산해 원하는 시점의 데이터베이스 상태를 재현할 수 있습니다.

PITR — 특정 시점으로 되돌리기

장애가 화요일 14:00에 발생했다면, 일요일 베이스 백업 + WAL 1~6을 재생해 13:30 상태로 복구합니다. WAL 7(장애 발생 구간)은 적용하지 않으므로 손상된 상태가 재현되지 않습니다.

베이스 백업 생성

# 운영 서버 데이터를 백업 서버로 복사
pg_basebackup \
  -h localhost \
  -U postgres \
  -D /backup/base_$(date +%Y%m%d) \
  --format=tar \       # 압축 전송
  --gzip \
  --checkpoint=fast \  # 즉시 체크포인트 수행
  -P                   # 진행 표시

# 백업 완료 확인
ls -lh /backup/base_20260516/

pg_basebackup은 실행 중인 서버에서 온라인 백업을 수행합니다. 백업 중에도 쓰기가 계속될 수 있습니다.

WAL 아카이브 설정

PITR 설정 — archive_command와 복구

-- postgresql.conf 설정 후 서버 재시작 필요
-- archive_mode = on
-- archive_command = 'cp %p /mnt/wal/%f'

-- 아카이브 상태 모니터링
SELECT archived_count, last_archived_wal,
       last_archived_time, failed_count
FROM   pg_stat_archiver;

archive_command가 0이 아닌 종료 코드를 반환하면 PostgreSQL은 재시도합니다. 따라서 명령이 멱등성(idempotent)을 가져야 합니다. S3에 업로드하는 경우 aws s3 cp --no-progress를 사용해 기존 파일을 덮어쓸 수 있게 합니다.

PITR 복구 절차

# 1. 복구 서버에 베이스 백업 복원
mkdir /var/lib/postgresql/data_recovery
tar -xzf /backup/base_20260510/base.tar.gz \
    -C /var/lib/postgresql/data_recovery

# 2. WAL 아카이브 위치 접근 가능하게 준비
# (NFS 마운트 또는 S3 설정)

# 3. postgresql.conf 수정 (복구 설정)
cat >> /var/lib/postgresql/data_recovery/postgresql.conf <<'EOF'
restore_command = 'cp /mnt/wal/%f %p'
recovery_target_time = '2026-05-13 13:30:00+09'
recovery_target_action = 'promote'
EOF

# 4. 복구 모드 트리거 파일 생성
touch /var/lib/postgresql/data_recovery/recovery.signal

# 5. 서버 기동 → WAL 재생 자동 시작
pg_ctl start -D /var/lib/postgresql/data_recovery

서버가 시작되면 restore_command로 WAL 파일을 가져오면서 recovery_target_time에 도달할 때까지 재생합니다. 목표 시점에 도달하면 promote 액션에 따라 정상 운영 모드로 전환합니다.

복구 대상 옵션

-- 특정 시각으로 복구 (가장 일반적)
recovery_target_time = '2026-05-13 13:30:00+09'

-- 특정 트랜잭션 ID 직전까지
recovery_target_xid = '12345678'

-- 특정 LSN 위치까지
recovery_target_lsn = '0/15000000'

-- 가능한 한 최근으로 (default)
recovery_target = 'immediate'   -- WAL 끝까지

운영 환경에서는 삭제 실수 직전 시각recovery_target_time으로 지정하는 경우가 가장 많습니다.

백업 주기와 보존 전략

백업 유형주기보존 기간도구
베이스 백업주 1회 이상4주pg_basebackup, pgBackRest
WAL 아카이브지속적베이스 백업 이후 전체파일 시스템, S3
논리 백업일 1회7일pg_dump

WAL 아카이브는 베이스 백업보다 최신인 것을 모두 보존해야 PITR이 가능합니다. 베이스 백업을 삭제할 때 그것보다 오래된 WAL 파일도 함께 정리합니다.


지난 글: PostgreSQL 논리 복제 — 선택적 복제와 버전 업그레이드

다음 글: pgBackRest와 Barman — PostgreSQL 백업 솔루션


읽어주셔서 감사합니다. 😊