이 문서를 통해 아래 질문들에 답할 수 있게 됩니다.

  • Restore Drill은 백업 성공 여부와 무엇이 다른가?
  • 복구 리허설에서 Spring 애플리케이션까지 확인해야 하는 이유는 무엇인가?
  • 복구 검증 결과를 운영 문서에 어떻게 남겨야 하는가?

개요

Restore Drill은 백업을 실제로 복원해 보는 리허설이다.

정기 백업이 성공했다는 로그만으로는 복구 가능성을 증명할 수 없다.

백업 파일이 손상되지 않았는지, 권한과 암호화 키가 준비되어 있는지, 복원된 DB로 애플리케이션이 정상 동작하는지 확인해야 한다.

운영 사고 중 처음으로 복구 명령을 실행하는 팀은 대부분 실수한다.

Restore Drill은 그 실수를 장애 이전에 발견하기 위한 절차다.

Drill의 목표

복구 리허설은 단순히 restore 명령이 성공하는지 보는 작업이 아니다.

  • RTO 안에 복구 절차가 끝나는지 측정한다.
  • 백업 기준 시각과 실제 복구 가능한 시각을 확인한다.
  • 복원된 데이터가 애플리케이션 규칙과 맞는지 확인한다.
  • 복구 권한, 암호화 키, 접근 경로가 문서대로 작동하는지 확인한다.
  • 복구 과정에서 사람이 판단해야 하는 지점을 찾는다.

Drill 결과는 다음 백업 정책을 조정하는 근거가 된다.

별도 환경 원칙

복구 리허설은 운영 DB에 직접 수행하지 않는다.

별도 DB, 별도 계정, 별도 네트워크 경로에서 실행해야 한다.

운영과 같은 이름의 연결 문자열을 사용하면 실수로 운영 데이터를 덮어쓸 수 있다.

리허설 환경에는 다음 표시가 필요하다.

  • DB 이름에 restore_drill 같은 식별자 포함
  • 쓰기 권한이 제한된 검증 계정
  • 외부 결제, 문자, 메일 발송 차단
  • 배치 자동 실행 비활성화
  • 검증 완료 후 폐기 절차

복구 검증은 운영과 비슷해야 하지만 운영을 위험하게 만들면 안 된다.

실행 예시

export DRILL_ID=restore-drill-2026-07-01
createdb "${DRILL_ID}"
 
pg_restore \
  --dbname "${DRILL_ID}" \
  --no-owner \
  order-service-2026-07-01.dump
 
psql "${DRILL_ID}" -c "select count(*) from orders;"
psql "${DRILL_ID}" -c "select max(created_at) from orders;"

복원 후에는 마이그레이션 상태도 확인한다.

SPRING_PROFILES_ACTIVE=restore-check \
DATABASE_URL="jdbc:postgresql://localhost:5432/restore-drill-2026-07-01" \
./gradlew flywayInfo

명령 출력은 성공/실패뿐 아니라 시작 시각, 종료 시각, 소요 시간, 사용한 백업 파일명과 함께 기록한다.

애플리케이션 검증

DB 복원이 성공해도 Spring 애플리케이션이 읽지 못하면 복구가 아니다.

복원된 DB로 최소한 다음을 확인한다.

  • 애플리케이션이 시작되는가?
  • 핵심 조회 API가 정상 응답하는가?
  • 최신 주문, 회원, 결제 상태가 기대한 범위 안에 있는가?
  • Flyway 또는 Liquibase migration 상태가 애플리케이션 버전과 맞는가?
  • 배치가 중복 실행되어도 안전한 상태인가?
  • 외부 시스템에 재전송하면 안 되는 이벤트가 분리되어 있는가?

특히 이벤트 발행 테이블, outbox 테이블, 스케줄 잡 상태는 복구 후 중복 처리 위험이 크다.

검증 SQL

검증 SQL은 서비스 도메인에 맞게 준비해야 한다.

select count(*) as order_count from orders;
select max(created_at) as newest_order from orders;
select status, count(*) from orders group by status;
select count(*) as pending_events from outbox_events where published_at is null;
select version, success from flyway_schema_history order by installed_rank desc limit 5;

이 SQL은 예시일 뿐이다.

중요한 것은 장애 중 운영자가 “정상처럼 보인다”가 아니라 “핵심 데이터가 기준과 맞다”라고 말할 수 있게 만드는 것이다.

운영 체크리스트

  • 복구 대상 백업 파일과 기준 시각을 명시한다.
  • 리허설 DB가 운영 DB와 분리되어 있는지 확인한다.
  • 복원 시작/종료 시각과 전체 소요 시간을 기록한다.
  • 복원 후 데이터 건수와 최신 데이터 시각을 확인한다.
  • 애플리케이션 시작과 핵심 API 응답을 확인한다.
  • 외부 발송과 결제 호출이 차단되어 있는지 확인한다.
  • 실패 지점을 다음 리허설 전에 수정할 작업으로 남긴다.

장애 신호

  • 백업 복원은 성공했지만 애플리케이션이 migration 오류로 시작하지 못한다.
  • 복구 계정 권한이 부족해 리허설이 중간에 멈춘다.
  • 백업 파일은 존재하지만 암호화 키를 찾지 못한다.
  • 복원 시간이 RTO를 크게 넘는다.
  • 복원된 DB의 최신 데이터 시각이 RPO 기준보다 오래됐다.
  • 외부 API 호출을 차단하지 않아 리허설 중 실제 알림이 발송된다.

이런 신호는 리허설 실패이며, 백업 정책이 운영 요구를 충족하지 못한다는 증거다.

안전한 완화 조치

  • 리허설 실패 원인이 권한이면 필요한 최소 권한을 문서화하고 계정 만료 정책을 확인한다.
  • 복원 시간이 길면 백업 방식, 압축 방식, 네트워크 위치, 사전 준비된 standby를 검토한다.
  • migration 오류가 나면 애플리케이션 버전과 DB 스키마 버전의 조합을 다시 정리한다.
  • 외부 발송 위험이 있으면 복구 프로필에서 발송 adapter를 비활성화한다.
  • 검증 SQL이 부족하면 장애 시나리오별로 핵심 불변 조건을 추가한다.

완화 조치는 복구 절차 자체를 더 예측 가능하게 만드는 방향이어야 한다.

하지 말아야 할 대응

  • 리허설을 운영 DB에서 실행하지 않는다.
  • 복원 명령 성공만 보고 Drill을 통과 처리하지 않는다.
  • 실패 원인을 기록하지 않고 다음 리허설로 미루지 않는다.
  • 복구 프로필에서 외부 발송 차단을 생략하지 않는다.
  • 복원된 데이터를 운영 데이터와 수동으로 섞지 않는다.

인프라 담당자와 공유할 자료

  • 사용한 백업 파일명, 생성 시각, 저장 위치
  • 리허설 DB 이름, 계정, 접근 경로
  • 시작/종료 시각과 총 복원 시간
  • 실패 단계와 에러 메시지
  • 검증 SQL 결과와 핵심 API 결과
  • RTO/RPO 충족 여부
  • 다음 리허설 전 수정해야 할 항목

공유 자료는 사고 중 그대로 따라 할 수 있는 복구 runbook으로 축적되어야 한다.

확인 질문

확인 질문

  • Restore Drill이 백업 작업 성공 로그보다 강한 증거인 이유는 무엇인가?
    • 실제 복원, 권한, 키, 데이터 검증, 애플리케이션 기동까지 확인하기 때문이다.
  • 복원된 DB로 애플리케이션을 실행해야 하는 이유는 무엇인가?
    • 스키마 버전, 도메인 규칙, 외부 부작용 차단 여부가 DB 복원만으로는 드러나지 않기 때문이다.
  • Drill 실패를 운영 문서에 남길 때 필요한 정보는 무엇인가?
    • 실패 단계, 에러, 소요 시간, 사용한 백업, 검증 결과, 다음 조치다.

리뷰 체크포인트

  • 리허설 환경이 운영과 명확히 분리되어 있는가?
  • RTO/RPO 충족 여부가 숫자로 남아 있는가?
  • 애플리케이션 검증 항목이 포함되어 있는가?
  • 외부 발송과 배치 실행 차단이 확인되었는가?
  • 실패 결과가 다음 개선 작업으로 연결되는가?