復旧手順を設計する
一言でいうと
復旧は順序と検証がすべてです。そして、その順序を実際にたどって時間を測るまで、RTOは数字ではなく希望的観測です。
なぜ必要なのか
バックアップをきちんと作っておきながら復旧で失敗する理由は、たいてい手順の問題です。
- どのバックアップを使うべきかわからない(フルか、増分か、どの世代か)
- 復元の順序を間違える(増分を先に展開する、順序を逆にする)
- 復元先を間違えて、現在のシステムを上書きする
- 復元はできたのにサービスが起動しない(権限、SELinux、UIDのマッピング)
どう動くのか
安全な復元の順序
# 1. 임시 경로로 먼저 푼다 — 절대 바로 덮어쓰지 않는다
mkdir -p /restore/check
tar -xzf /backup/full-2026-08-20.tar.gz -C /restore/check
# 2. 내용을 확인한다
find /restore/check -type f | wc -l
diff -r /restore/check/etc/nginx /etc/nginx | head -40
# 3. 필요한 것만 옮긴다
rsync -aHAX --numeric-ids /restore/check/etc/nginx/ /etc/nginx/
一時的なパスを経由することが核心です。-C /でそのまま展開するのは、元に戻せない作業です。
増分復元の順序
フル → 増分0 → 増分1 → ... の順序を必ず守る必要があります。tarの--listed-incrementalで作った増分は削除の情報まで含んでいるので、順序を破ると、あるべきファイルが消えます。
tar --listed-incremental=/dev/null -xzf full.tar.gz -C /restore/
tar --listed-incremental=/dev/null -xzf inc0.tar.gz -C /restore/
tar --listed-incremental=/dev/null -xzf inc1.tar.gz -C /restore/
復元時は--listed-incremental=/dev/nullを使うのが慣例です。スナップショットファイルを更新しないという意味です。
選択的な復元
全体を展開する必要はなく、特定のファイルだけを取り出せます。
tar -tzf backup.tar.gz | grep nginx.conf
tar -xzf backup.tar.gz -C /restore/ src/conf/nginx.conf
tar -xzf backup.tar.gz -C /restore/ --strip-components=1 src/conf/
--strip-components=Nは、先頭のパス要素をN個取り除いて展開します。アーカイブの構造と復元先が違うときに使います。
時間を測る
RTOを確認するには、実際に測る必要があります。
START=$(date +%s)
# ... 복구 절차 전체 ...
END=$(date +%s)
echo "복구 소요: $((END - START))초"
ここに含めるべきなのは、アーカイブの展開時間だけではありません。バックアップの保存先からファイルを取得する時間、検証の時間、サービスの起動時間、整合性の確認時間がすべて入ってはじめて、実際のRTOになります。実務でRTOを守れない原因の1位は、展開が遅いことではなく、ネットワーク経由でバックアップを取得する時間です。
復元後の検証
- ファイルの数と合計サイズが期待と合っているか
- 権限と所有者が合っているか(
--numeric-idsを使ったか) - サービスが起動するか
- アプリケーションの整合性チェックを通過するか
バックアップがあることと、復旧できること
バックアップが成功したというログは、ファイルが作られたという意味にすぎません。3つを確認してはじめて「復旧できる」と言えます。
- 読めるか: 圧縮が壊れておらず、暗号鍵が生きているか。
- 完全か: 必要なものがすべて入っているか(スキーマ・データ・シーケンス・拡張)。
- 時間内にできるか: 実際に復元してみると、予想よりはるかに長くかかります。
3つ目がよく崩れます。500GBの復元に6時間かかるのにRTOが1時間なら、そのバックアップは災害復旧には使えません。RTOを守るにはレプリカやスナップショットが必要です。論理バックアップは最後の防衛線であり、最初の手段ではありません。
| 方式 | 復元時間 | 復旧ポイント | 使う場面 |
|---|---|---|---|
| 論理ダンプ(pg_dump) | 遅い(数時間) | ダンプの時点 | 移行、部分的な復元 |
| 物理バックアップ+WAL | 普通(数分から数時間) | 任意の時点 | 災害復旧 |
| ストレージのスナップショット | 速い(数分) | スナップショットの時点 | 素早い巻き戻し |
| 読み取りレプリカの昇格 | 最も速い(数秒) | ほぼリアルタイム | 高可用性 |
リハーサルで実際に測るもの
「復旧できた」で終わらせず、数字を残します。
## 복구 리허설 2026-09-06
- 대상: labhub-prod DB (실 용량 142GB)
- 백업 시각: 2026-09-05 12:30 KST
- 복원 목표 시점: 2026-09-05 18:00 KST (PITR)
| 단계 | 걸린 시간 |
|---|---|
| 백업 내려받기 | 21분 |
| 기본 백업 복원 | 47분 |
| WAL 재생 (5.5시간분) | 33분 |
| 서비스 기동·검증 | 9분 |
| **합계 (RTO 실측)** | **1시간 50분** |
- 검증: 행 수 대조 3개 표 일치, 최근 주문 10건 육안 확인, 애플리케이션 기동 성공
- 발견: WAL 아카이브에 12분 구멍(2026-09-05 14:02~14:14) — 아카이빙 재시도 설정 필요
- RPO 실측: 12분 (목표 5분 미달 — 개선 필요)
発見事項がないリハーサルは、リハーサルをしていないのと同じようなものです。初めてやってみると、ほとんどいつも何かが見つかります。
いつ行うか
- 四半期に1回が最低ラインです。その間にスキーマ・容量・インフラが変わります。
- バックアップ方式や保存先を変えた直後に必ず行います。
- 新しい人が来たときに、その人が手順書だけを見て試します。手順書に欠けているものが、このときに明らかになります。
また、リハーサルは本番から隔離された場所で行います。本番DBに復元した時点で、それはリハーサルではなく事故です。
現場での姿
「復元はできたのにサービスが起動しない」場合、原因の候補は決まっています。UID/GIDのマッピング、SELinuxコンテキスト、ファイルシステムの機能の違い(ACL非対応)、カーネルやライブラリのバージョンの違いです。--numeric-idsと--selinuxが、前の2つへの備えです。
復元のドキュメントが、復元担当者のノートパソコンにしかありません。 そのノートパソコンがない状況こそが、復旧が必要な状況かもしれません。
次のラボですること
前に作ったバックアップセットで、復旧リハーサルを行います。安全な順序で復元し、元のデータと比較し、選択的な復元と増分の順序どおりの復元まで行い、時間を測ってRTOを満たしているかを判定します。