11.7 복구 시나리오와 정기 복구 훈련
백업 자체보다 복구가 실제로 가능한지가 운영의 진짜 관문입니다. 자주 마주치는 사고는 실수한 DROP부터 데이터센터 장애까지 폭이 넓지만, 대응 패턴은 대체로 staging에서 복구한 뒤 필요한 부분만 운영에 되돌리는 형태로 수렴합니다.
시나리오 A — 실수로 테이블 DROP
가장 흔한 사고입니다. 누군가 DROP TABLE orders;를 운영에서 실행합니다.
대응 결정
| 옵션 | 메모 |
|---|---|
| 새 클러스터에 PITR 후 테이블만 dump → 운영에 import | 가장 안전. 약 1~2시간 |
| 운영 클러스터 자체 PITR | 그 사이 트랜잭션 모두 사라짐 — 거의 안 함 |
| dump가 있으면 그 dump의 테이블만 restore | 최근 dump 시점까지만 데이터 |
표준 절차
# 1. 새 호스트에 PITR (drop 1분 전으로)
sudo -u postgres pgbackrest --stanza=main restore \
--type=time --target='2026-05-23 09:54:00' \
--target-action=promote
# 2. 기동 후 테이블만 dump
pg_dump -h staging -t public.orders app_main > orders_recovered.sql
# 3. 운영에 재생
psql -h primary app_main < orders_recovered.sqlDROP 자체는 PITR로 되살리지만, 그 사이 진행된 다른 트랜잭션과의 충돌은 운영자가 판단합니다.
시나리오 B — UPDATE/DELETE 사고
UPDATE orders SET status = 'cancelled';를 WHERE 없이 실행한 경우.
절차
A와 동일 — staging PITR → 영향 받은 row만 export → 운영 patch.
# staging에서
psql -h staging -c "
COPY (SELECT * FROM orders WHERE updated_at > '2026-05-23 09:50:00')
TO '/tmp/before.csv' WITH CSV;
"
# 운영에서
\COPY orders_before FROM '/tmp/before.csv' WITH CSV;
UPDATE orders o SET status = b.status FROM orders_before b WHERE o.id = b.id;시나리오 C — 클러스터 전체 손실 (디스크 사고)
호스트 자체 + 디스크 사고입니다. 새 호스트에서 처음부터 복원.
절차
# 1. 새 호스트에 PostgreSQL 설치
sudo dnf install postgresql17-server pgbackrest
# 2. pgBackRest 설정 복사 (저장소 위치·인증)
sudo scp old_admin:/etc/pgbackrest.conf /etc/
# 3. 새 PGDATA 디렉토리 (비어 있어야)
sudo -u postgres mkdir -p /var/lib/pgsql/17/data
sudo chmod 0700 /var/lib/pgsql/17/data
# 4. 가장 최근 백업 복원
sudo -u postgres pgbackrest --stanza=main restore
# 5. 기동
sudo systemctl start postgresql-17
# 6. 검증
psql -c "SELECT count(*) FROM critical_table;"RTO 측정 — 운영 권장은 1시간 이내 전체 복원. 클러스터가 크면 미리 standby가 있어야 합니다.
시나리오 D — 운영 standby로 즉시 failover
primary 호스트 자체 사고입니다. 미리 운영하던 standby를 promote.
절차
# standby에서
sudo -u postgres pg_ctl -D /var/lib/pgsql/17/data promotepromote 후 standby가 새 timeline 시작 + read-write. 클라이언트 연결을 새 호스트로 전환 (DNS, HAProxy, pgBouncer 등).
자동화: Patroni·repmgr·pg_auto_failover (Part XII).
시나리오 E — 한 테이블이 corrupt
could not read block X in file ... 오류 발생합니다. data_checksums = on이면 잘 감지.
절차
# 1. corrupt 페이지 위치 확인
psql -c "SELECT ctid, * FROM bad_table LIMIT 1;" # 어디가 깨졌는지
# 2. 영향 받는 row 추출 (가능한 만큼)
SELECT * FROM bad_table WHERE ctid::text NOT LIKE '(<bad_page>,%)';
# 3. 최근 백업에서 같은 테이블 export
pgbackrest --stanza=main restore --tablespace-map=... --type=immediate ...
# 그 staging에서
pg_dump -t bad_table app_main > recover.sql
# 4. 운영의 corrupt 테이블 교체
DROP TABLE bad_table;
\i recover.sql데이터 디스크 자체 의심이면 OS 진단 (smartctl, dmesg)도 같이.
시나리오 F — 데이터센터 장애
전체 리전 사고입니다. 다른 리전·다른 클라우드로 복구합니다.
절차 — 오프사이트 백업이 있다면
# 1. 다른 리전·클라우드에 PostgreSQL 설치
# 2. S3 cross-region 또는 그 리전의 백업 저장소에서 pgBackRest restore
# 3. DNS·CDN·LB 전환RTO·RPO 모두 가장 큽니다. 3-2-1 원칙(11.1)이 지켜진 상황에서만 가능합니다.
정기 복구 훈련 — 자동화
백업의 90% 실패 사례는 훈련 부족입니다. 분기마다 자동 훈련:
#!/bin/bash
# 매분기 첫째 토요일 — staging 호스트에서
set -e
STAGING_PG=/var/lib/pgsql/staging/data
TARGET_TIME="$(date -d '1 hour ago' '+%Y-%m-%d %H:%M:%S')"
# 1. staging 정지·디렉토리 비움
sudo -u postgres pg_ctl -D $STAGING_PG stop -m fast || true
sudo -u postgres rm -rf $STAGING_PG/*
# 2. 최근 백업으로 PITR
sudo -u postgres pgbackrest --stanza=staging \
--pg1-path=$STAGING_PG --type=time --target="$TARGET_TIME" restore
# 3. 기동
sudo systemctl start postgresql@staging
# 4. 핵심 검증 쿼리
psql -p 5433 -c "SELECT count(*) FROM critical_table;" || {
echo "FAIL: 검증 쿼리 실패"
exit 1
}
# 5. 알람 발송 — 성공
curl -X POST https://alert/.../ -d "Recovery drill OK at $(date)"이렇게 자동화해 둬야 실제 사고 시 절차가 검증된 상태.
복구 시간 측정
매 훈련마다 측정 항목:
| 단계 | 측정 |
|---|---|
| 백업 다운로드 | MB/s |
| 페이지 풀기 | MB/s |
| WAL 재생 | LSN/s |
| 검증 쿼리 | ms |
| 총 RTO | 시간 |
추세를 그려 배포 클러스터가 커지면 RTO도 커진다는 사실을 인식합니다. RTO 목표를 못 맞추면 증분 백업·standby·다른 전략 검토합니다.
운영 체크리스트
| 항목 | 빈도 |
|---|---|
pg_stat_archiver 실패 알람 | 실시간 |
| 백업 완료·실패 알람 | 매 백업 |
verify(pgBackRest)·check(Barman) | 주 |
| 자동 PITR 훈련 | 분기 |
| DR 시나리오 시뮬레이션 (사람) | 반기 |
| 보존 정책 점검 | 분기 |
| 외부 저장소 무결성 | 매년 |
정리
- 자주 마주치는 6가지 시나리오: DROP, UPDATE 실수, 클러스터 손실, failover, corruption, 데이터센터 장애
- 운영의 표준 패턴 = staging PITR → 영향 받은 부분만 export → 운영 patch
- failover는 standby가 미리 있을 때만 가능
정기 복구 훈련이 있어야 백업이 실제 의미를 가집니다. 자동화된 PITR 훈련은 분기, 사람이 참여하는 DR 시뮬레이션은 반기로 돌리고, 절차서·도구·구성은 훈련 시점마다 함께 검증합니다.
Part XI 백업과 복구를 마칩니다. 이어지는 Part XII는 복제와 고가용성입니다.