検証の三段階
一言でいうと
バックアップの検証は、存在するか → 読めるか → 復旧できるかの3段階です。前の2つは自動化できますが、最後は人が行う必要があります。
なぜ必要なのか
バックアップは毎日動いています。ログには成功と出力されます。ところが、いざ復旧が必要な日にファイルが開けません。この状況は珍しくありません。
どう動くのか
1段階目: 存在するか
最も基本的なことですが、意外とここで引っかかる問題が多くあります。
ls -lh /backup/prod/ | tail -5
find /backup/prod -type f -mtime -1 | wc -l
ファイルサイズが0ではないこと、そして最新の時刻であることを確認します。「最近の成功が24時間以内か」を監視に見張らせるほうが、ログを読むよりはるかに優れています。
2段階目: 読めるか
圧縮の整合性とアーカイブの一覧を確認します。
gzip -t /backup/etc-2026-08-20.tar.gz && echo 'gzip OK'
tar -tzf /backup/etc-2026-08-20.tar.gz > /dev/null && echo 'archive OK'
sha256sum -c /backup/checksums.sha256
3つはそれぞれ別のものを見ています。gzip -tは圧縮ストリームのCRC、tar -tはアーカイブの構造、sha256sum -cはファイル全体のハッシュです。圧縮は正常なのにtarの構造が壊れている場合もあれば、その逆もあります。
3段階目: 実際に復旧できるか
これだけが本当の検証です。 別のホストや一時的な環境に復元してサービスを立ち上げ、データが期待した時点のものかを確認します。
リハーサルのチェックリストです。
- バックアップの保存先にアクセスするための認証情報が、本番サーバーの外に保管されているか
- 復元手順のドキュメントが、復元担当者のノートパソコン以外の場所にあるか
- 復元に必要な暗号化キーが別に保管されているか
- リハーサルにかかった実際の時間が、RTOの範囲内に収まっているか
- 復元後にアプリケーションが起動し、整合性チェックを通過するか
暗号化キーの保管は、特に抜けやすいものです。 バックアップを暗号化しておきながら、キーをバックアップ対象のサーバーにだけ置いていると、そのサーバーが消えたとき、バックアップは意味のないバイナリファイルになります。
リハーサルの頻度は、四半期に1回が現実的な最低ラインです。 また、リハーサルはバックアップを作った人ではない別の人が、ドキュメントだけを見て行ってはじめて、手順の穴が見えてきます。
検証スクリプトの形
#!/usr/bin/env bash
set -euo pipefail
ARCHIVE="${1:?usage: verify.sh <archive>}"
[ -s "$ARCHIVE" ] || { echo "빈 파일이거나 없음: $ARCHIVE" >&2; exit 1; }
gzip -t "$ARCHIVE" || { echo "압축 스트림 손상" >&2; exit 2; }
tar -tzf "$ARCHIVE" > /dev/null || { echo "아카이브 구조 손상" >&2; exit 3; }
echo "OK $ARCHIVE"
終了コードをステップごとに変えるのがコツです。監視で、どの段階で失敗したのかがすぐにわかります。
現場での姿
ビット腐敗(bit rot)。 長く保管したアーカイブが静かに壊れます。ディスク自体は正常だと報告するのに、数バイトが反転しています。定期的なチェックサムの再検証がこれを捕まえます。バックアップの保存先にZFSやBtrfsを使う理由の1つが、自前のチェックサムです。
テープやオブジェクトストレージの静かな失敗。 書き込みは成功したと返ってきたのに、実際には保存されていない場合があります。書き込み直後に読み出して確認する手順が必要です。
3-2-1が今も有効な理由
古いルールですが、クラウドでもそのまま通用します。
사본 3개 · 매체 2종 · 오프사이트 1개
これに加えて、最近は2つが付け加わります。
- 1つはオフライン、または不変(immutable): ランサムウェアがバックアップまで暗号化するのが標準的な手口です。Object LockのCOMPLIANCEモードのように、管理者でも消せないコピーが1つ必要です。
- 検証されていないコピーは0個: 確認していないバックアップは、コピーに数えません。
2つ目がこのモジュールの要点です。バックアップの数を誇るよりも、復元してみたバックアップが1つでもあるかが重要です。
整合性の検証を自動化する
人が覚えていて行う検証は、いつか止まります。3つの層を自動で回します。
# 1) 파일이 온전한가 — 매일
sha256sum -c backup-2026-09-06.sha256
gzip -t backup-2026-09-06.sql.gz # 압축 무결성만 확인(빠르다)
# 2) 읽을 수 있는가 — 주마다
pg_restore --list backup.dump > /dev/null # 목록만 뽑아 본다
# 3) 복원되는가 — 분기마다
pg_restore -d verify_db backup.dump && psql verify_db -c "select count(*) from orders"
1つ目は数秒、2つ目は数分、3つ目は数時間かかります。コストに合わせて頻度を変えるのが実務の答えです。3つとも行わなければ、「バックアップがある」という思い込みだけが残ります。
検証結果をどこに残すか
検証が失敗したのに誰も気づかなければ、やっていないのと同じです。3つを揃えます。
- 指標: 最後に成功した時刻をゲージとして出力します。
time() - last_success > 2일ならアラートです(韓国語で「2日」を意味する語です)。失敗の件数よりも、最後の成功からの経過が正確なシグナルです。 - 記録: いつ、何を、どのように検証して、結果がどうだったかです。監査で求められます。
- アラート: バックアップ自体の失敗と、検証の失敗を別のアラートにします。原因も対応も違うからです。
# 백업이 돌지 않는다 (심각)
time() - backup_last_success_timestamp > 86400 * 2
# 백업은 도는데 검증이 실패한다 (더 심각 — 있다고 믿었던 것이 없다)
backup_verify_success == 0
2つ目のほうが深刻です。バックアップが動いていないことには気づきやすいですが、動いているのに使えない状態は、必要になる瞬間まで誰も気づきません。
次のラボですること
チェックサムのマニフェストを作り、わざと破損を作って検出し、段階ごとの終了コードを持つ検証スクリプトを作成します。採点ツールが、正常なアーカイブと破損したアーカイブの両方でそのスクリプトを実行します。