데이터베이스 용어 사전
회복·백업Point-In-Time Recovery · 시점 복구 · WAL 아카이브

PITR

기준 백업과 이후 WAL을 합쳐 원하는 과거 시점으로 복원하는 것. WHERE 빠진 DELETE의 구원이다.

기준 백업 + 그 이후의 WAL 아카이브를 합쳐 원하는 과거 시점으로 되감는 복구 방식.

무엇을 구해 주나

오후 3시 05분  운영자가 WHERE 를 빠뜨린 DELETE 를 실행했다
     ↓
오후 3시 04분 상태로 되감는다

크래시 복구(WAL)는 크래시 직전 상태로만 돌아간다. 사람의 실수는 정상 커밋이므로 WAL로는 못 막는다. PITR만이 그 이전으로 되돌린다.

어떻게 동작하나

[기준 백업]           [연속 WAL 아카이브]
 2026-08-01 02:00  →  ─────────────────────────→ 지금
                              ↑
                        원하는 시점까지만 redo 를 적용한다

PostgreSQL 설정

# postgresql.conf — WAL 을 별도 보관소로 계속 복사해 둔다
wal_level = replica
archive_mode = on
archive_command = 'test ! -f /archive/%f && cp %p /archive/%f'
# 기준 백업
pg_basebackup -D /backup/base -Fp -Xs -P

# 복원 — 목표 시점을 지정한다
# recovery.signal 파일을 만들고 postgresql.conf 에
#   restore_command = 'cp /archive/%f %p'
#   recovery_target_time = '2026-08-01 15:04:00'

recovery_target_time 외에 recovery_target_lsn·recovery_target_xid 로도 지정할 수 있다. 사고 트랜잭션 ID를 알면 그 직전으로 정확히 되감을 수 있다.

MySQL의 방식

# 전체 백업 + 바이너리 로그를 시점까지 적용한다
mysqlbinlog --stop-datetime="2026-08-01 15:04:00" binlog.000123 | mysql

MySQL은 redo 로그가 아니라 바이너리 로그(binlog) 를 쓴다 — redo는 InnoDB 내부용이고 binlog는 복제·PITR용이라는 역할 분리가 있다.

실무에서 반드시 챙길 것

  • ① 아카이브가 실제로 쌓이는지 감시한다
    • archive_command 가 실패해도 조용히 넘어가면 PITR 이 불가능해진다
  • ② 복원을 정기적으로 실제로 해 본다
    • 복원해 본 적 없는 백업은 백업이 아니다
  • ③ 아카이브 보관 기간을 정한다
    • 무한히 쌓으면 디스크가 찬다
-- 아카이브가 밀리고 있지 않은지
SELECT archived_count, failed_count, last_failed_time FROM pg_stat_archiver;

failed_count가 늘고 있으면 PITR이 이미 불가능한 상태일 수 있다.

면접 함정

  • "복제본이 있으니 PITR은 필요 없다" → 실수한 DELETE는 복제본에도 즉시 전파된다.
  • "백업만 있으면 PITR이 된다" → 기준 백업 + 연속 WAL 아카이브가 둘 다 있어야 한다.

되감을 시점을 어떻게 정하나

-- 사고 트랜잭션의 ID 를 알면 그 직전으로 정확히 되감을 수 있다
-- postgresql.conf
--   recovery_target_xid = '123456'
--   recovery_target_inclusive = false      ← 그 트랜잭션은 제외한다

-- 시각을 모를 때는 로그에서 찾는다
-- log_statement = 'ddl' 이면 DROP/TRUNCATE 가 시각과 함께 남는다

복구 후 반드시 확인할 것

SELECT pg_is_in_recovery();        -- true 면 아직 복구 모드다
SELECT pg_wal_replay_resume();     -- 일시정지 상태면 재개
-- recovery_target_action = 'pause' 로 두면
-- 목표 시점에 멈춰서 데이터를 확인한 뒤 승격할 수 있다 (권장)

pause로 멈춰 확인한 뒤 승격하는 절차가 안전하다. 바로 승격해 버리면 시점이 잘못됐을 때 다시 처음부터 복구해야 한다.

함께 보면 좋은 용어

노트에서 맥락과 함께 보기 — 회복·WAL·백업 — 장애 복구·PITR·RPO/RTO