Skip to content

필사 모드: バックアップとリストア完全ガイド: 復旧シナリオから逆算して設計する

日本語
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.

はじめに

バックアップに関する最もよくある誤解は「バックアップをしているから安全だ」です。実際は違います。復旧してみたことのないバックアップは、バックアップではなくバックアップだと信じているファイルの山 です。実際の事故でバックアップが役に立たなくなる理由は、たいていバックアップをしていなかったからではなく、復旧手順を一度も実行してみたことがなかったからです。

このブログにはすでに オープンソースバックアップツール比較 があります。あの記事はツールごとの機能と長所短所を比較します。この記事はツール選択より前の問題を扱います。どの復旧シナリオに耐えなければならないのかを先に決め、そこから逆算してバックアップ方式を導く設計順序 がテーマです。

扱うツールはLinuxの標準環境にあるものが中心です。rsync、tar、LVMスナップショット、そしてデータベースのダンプです。ディストリビューションの基準はRHEL系8以上、Debian 12およびUbuntu 22.04以上であり、GNUツールを前提に説明します。BSDやmacOSの tarseddate はオプションが異なる ので、スクリプトを移すときは注意してください。


1. RPOとRTO — すべての決定の出発点

二つの数字が残りをすべて決めます。

  • RPO(Recovery Point Objective): 最大で何分、あるいは何時間分のデータを失ってよいか。バックアップの 周期 を決めます。
  • RTO(Recovery Time Objective): 障害発生からサービス再開まで何時間を許容するか。バックアップの 方式と保存場所 を決めます。

この二つの値を決めないままツールを選ぶと必ず食い違います。RPOが5分なのに1日1回ダンプを取っていたり、RTOが1時間なのにテープから8時間かかる復元をしなければならなかったりする状況がそれです。

RPO要求必要な方式
24時間日1回の全体または増分バックアップ
1時間時間ごとの増分 + スナップショット
5分継続的アーカイブ(WALなど)またはレプリケーション
0同期レプリケーション。バックアップだけでは不可能
RTO要求必要な構成
数日リモートアーカイブから復元
数時間ローカルディスクへのバックアップ + 文書化された手順
1時間未満待機系システム + 定期リハーサル
分単位自動フェイルオーバー。バックアップではなく冗長化

最後の行が重要です。バックアップと高可用性は、異なる問題を解く異なる道具です。レプリケーションは、誤って消したデータを即座に一緒に消します。ランサムウェアも一緒に複製されます。だからこそレプリケーションがあってもバックアップが必要です。


2. 3-2-1ルールとその現代的な補完

古典的な3-2-1ルールは コピー3個、媒体2種、リモート1個 です。ここに最近は二つが付け加わります。

  • 1個はオフラインまたは変更不可(immutable)にする — ランサムウェアがバックアップまで暗号化する事故があったためです。
  • 0個の検証されていないコピー — 復元検証を通過していないコピーは数えません。

実務でこれが意味することは明確です。バックアップサーバーに運用サーバーの資格情報があってはいけません。運用サーバーが侵害されるとバックアップまで削除されるからです。バックアップサーバーが運用サーバーに接続して引っ張ってくるpull方式のほうが、運用サーバーがバックアップサーバーに押し込むpush方式より安全な理由がこれです。

オブジェクトストレージを使うなら、バージョン管理とオブジェクトロックの機能をオンにするのが実質的な防御になります。正確な設定名と手順は、使っているストレージ製品のドキュメントで確認してください。

媒体2種という条件も現代的に解釈する必要があります。以前はディスクとテープでしたが、今は 異なる障害の現れ方を持つ二つのストア として読むほうが正確です。同じクラウドアカウントの二つのリージョンは媒体2種ではありません。アカウント自体がロックされたり支払いが止まったりすれば、どちらにもアクセスできなくなるからです。障害の原因が重ならないかどうかを基準に判断してください。

そしてバックアップの一覧には、データだけでなく そのデータを復活させるために必要なすべて が入っていなければなりません。設定ファイル、証明書と秘密鍵、データベースのスキーマ、デプロイ成果物、そして復元手順の文書です。データだけをバックアップしてサービスを立てる方法をバックアップしておらず、復旧が何日も長引いた事例は実際に多くあります。


3. rsync — 最も多く使い、最も多く間違える道具

rsync -aHAX --numeric-ids --delete --dry-run /srv/data/ backup@10.0.9.2:/backup/prod/data/
rsync -aHAX --numeric-ids --delete /srv/data/ backup@10.0.9.2:/backup/prod/data/

オプションの正確な意味です。

  • -a(--archive)は文書上 -rlptgoD と同じです。再帰、シンボリックリンクの保存、権限、時刻、グループ、所有者、特殊ファイルを含みます。
  • -a に含まれないものがあります。ACL(-A)、拡張属性(-X)、ハードリンク(-H)は別に指定しなければなりません。これを知らないと復元後に権限が微妙に変わります。
  • --numeric-ids は名前の代わりに数値のUID/GIDを使います。別のシステムへ復元するときに所有者がおかしくマッピングされるのを防ぎます
  • --delete は元にないファイルを対象から消します。
  • -n(--dry-run)は実際の変更なしにシミュレーションします。
  • -i(--itemize-changes)はどんな変更が起きるのかを1行ずつ見せてくれます。

破壊的コマンドの警告: --delete は、元が空だったりマウントが外れていたりする状態で実行されると対象のデータを全部消します。実務で実際によく起きる事故です。まず --dry-run で確認し、スクリプトには元が空でないかを確認するガードを入れてください

#!/usr/bin/env bash
set -euo pipefail
SRC=/srv/data
DST=backup@10.0.9.2:/backup/prod/data/

mountpoint -q "$SRC" || { echo "source not mounted, abort" >&2; exit 1; }
[ "$(ls -A "$SRC" | wc -l)" -gt 0 ] || { echo "source empty, abort" >&2; exit 1; }

rsync -aHAX --numeric-ids --delete "$SRC/" "$DST"

もう一つよく間違えるのが 末尾のスラッシュ です。文書の表現どおり、元のパスの末尾のスラッシュは「このディレクトリの中身をコピーする」という意味で、スラッシュがなければ「このディレクトリ自体をコピーする」という意味です。

rsync -a /srv/data  /backup/    # /backup/data/... が作られる
rsync -a /srv/data/ /backup/    # /backup/... に中身が直接入る

世代管理はハードリンクで安く実装できます。

rsync -aHAX --numeric-ids --delete \
  --link-dest=/backup/prod/daily.1 \
  /srv/data/ /backup/prod/daily.0/

--link-dest は変更されていないファイルをコピーする代わりに、指定したディレクトリのファイルへハードリンクを張ります。結果として各世代が全体スナップショットのように見えますが、ディスクは変更分だけを占めます


4. tar — アーカイブの基本

tar -czf /backup/etc-2026-08-15.tar.gz -C / etc
tar -tzf /backup/etc-2026-08-15.tar.gz | head
tar -xzf /backup/etc-2026-08-15.tar.gz -C /restore/

オプションは文書を基準にすると次のとおりです。

  • -c(--create)、-x(--extract)、-t(--list)、-f(--file)が基本の組み合わせです。
  • 圧縮は -z(gzip)、-j(bzip2)、-J(xz)、--zstd(zstd)です。
  • -C(--directory)は作業の前にディレクトリを変えます。絶対パスをアーカイブに入れないために必ず使ってください
  • -p(--preserve-permissions)と --numeric-owner は復元時に権限と所有者を正確に復活させます。
  • --acls--xattrs--selinux はそれぞれACL、拡張属性、SELinuxコンテキストを含めます。SELinuxを使うシステムでこのオプションなしに復元すると、サービスが起動しません
  • --one-file-system は他のファイルシステムに移りません。マウントされたネットワークストレージまでバックアップに付いてくる事故を防ぎます。
  • --exclude--exclude-from で除外パターンを指定します。
  • --listed-incremental は増分バックアップのためのスナップショットファイルを管理します。
  • --strip-components は復元時に前方のパス要素を取り除きます。

システム設定のバックアップの実用的な形はこうです。

sudo tar -czf /backup/etc-$(date +%F).tar.gz \
  --acls --xattrs --selinux --numeric-owner \
  --exclude='/etc/shadow-' \
  -C / etc

復元のときはパスを必ず確認してください-C / でそのまま展開すると現在のシステム設定を上書きします。安全な手順は、一時パスに展開して中身を確認したうえで必要なファイルだけを移すことです。

mkdir -p /restore/etc-check
sudo tar -xzf /backup/etc-2026-08-15.tar.gz -C /restore/etc-check
diff -r /restore/etc-check/etc/nginx /etc/nginx | head -40

GNU tarとBSD tar(bsdtar)はオプションの扱いと一部の動作が異なります。macOSで作ったアーカイブをLinuxで展開するときに拡張属性関連のファイルが一緒に出てくる問題が代表的です。バックアップスクリプトは実際に運用するディストリビューションで検証してください


5. 一貫性 — バックアップ中に変更されるデータ

ファイルをコピーしている間にアプリケーションがそのファイルに書いていると、バックアップはどの時点の状態でもない寄せ集めになります。特にデータベースでは致命的です。

解法には三つの層があります。

層1 — アプリケーションレベルのダンプ。最も確実で移植性が良い方法です。

pg_dump -Fc -d appdb -f /backup/appdb-2026-08-15.dump
mysqldump --single-transaction --routines --triggers appdb > /backup/appdb.sql

--single-transaction はトランザクション分離によって一貫したスナップショットを得ます。各データベースの正確なオプションと制約は、該当製品のドキュメントで確認してください。

層2 — ファイルシステムのスナップショット。LVM、Btrfs、ZFSが対応しています。スナップショットを取ってそれをバックアップすれば、停止時点が固定されます。

sudo lvcreate --size 10G --snapshot --name snap_data /dev/vg0/data
sudo mount -o ro /dev/vg0/snap_data /mnt/snap
sudo tar -czf /backup/data.tar.gz -C /mnt/snap .
sudo umount /mnt/snap
sudo lvremove -y /dev/vg0/snap_data

重要な限界があります。LVMスナップショットはブロックレベルの時点固定でしかなく、アプリケーションがメモリに持っていたデータまでは反映しません。データベースであれば、スナップショットの直前にチェックポイントを強制するか、書き込みを少し止める手順が必要です。また スナップショットボリュームがいっぱいになるとスナップショットは無効化される ので、サイズは余裕を持って取ってください。

sudo lvs -o lv_name,lv_size,data_percent,snap_percent

層3 — 継続的アーカイブ。RPOを分単位まで縮めなければならないときに使います。データベースのWALやバイナリログをずっとアーカイブしておき、任意の時点へ復旧します。設定と復旧の手順は製品ごとに異なるので、該当ドキュメントに従ってください。


6. 検証 — 復旧リハーサルなしにバックアップとは呼べない

検証は三段階に分けて考えると漏れなくできます。

段階1 — バックアップが存在するか。ファイルサイズが0でなく、最新の時刻かどうかを確認します。意外にこの段階で引っかかる問題が多いです。

ls -lh /backup/prod/ | tail -5
find /backup/prod -type f -mtime -1 | wc -l

段階2 — バックアップが読めるか。圧縮の整合性とアーカイブの一覧を確認します。

gzip -t /backup/etc-2026-08-15.tar.gz && echo 'gzip OK'
tar -tzf /backup/etc-2026-08-15.tar.gz > /dev/null && echo 'archive OK'
sha256sum -c /backup/checksums.sha256

段階3 — 実際に復旧できるか。これだけが本当の検証です。別のホストや一時環境に復元してサービスを起動してみて、データが期待した時点のものかを確認します。

リハーサルのチェックリストは次のように置いておくとよいです。

  • バックアップストアにアクセスする資格情報が 運用サーバーの外に 保管されているか
  • 復元手順の文書が 復元担当者のノートパソコン以外の場所に あるか
  • 復元に必要な暗号鍵が別に保管されているか
  • リハーサルにかかった実際の時間がRTOの中に収まるか
  • 復元後にアプリケーションが起動し、整合性チェックを通過するか

暗号鍵の保管は特によく抜けます。バックアップを暗号化しておいて鍵をバックアップ対象のサーバーにだけ置くと、そのサーバーが消えたときバックアップは無意味なバイナリファイルになります。

リハーサルの周期は四半期に1回が現実的な最低線です。そして リハーサルはバックアップを作った人ではない別の人が、文書だけを見て実施 しなければ手順の穴は見えてきません。


7. バックアップが静かに壊れる五つの方式

方式1 — バックアップ対象から抜けています。新しいボリュームを追加したのにバックアップスクリプトには入れていない場合です。対象の一覧をインフラ定義と一緒に管理して、自動的に反映されるようにしてください。

方式2 — 成功ログだけを見て失敗に気づけません。cronは基本的に静かです。終了コードを確認して失敗を知らせる仕掛けが必要です。

#!/usr/bin/env bash
set -euo pipefail
trap 'echo "backup FAILED at line $LINENO" >&2; exit 1' ERR

rsync -aHAX --numeric-ids --delete /srv/data/ /backup/prod/data/
echo "backup OK $(date -Is)"

set -euo pipefailtrap ... ERR の組み合わせが最低限の防御線です。成功時刻をファイルやモニタリングに記録し、直近の成功が24時間以内かどうかを監視する ほうがはるかに良いです。

方式3 — バックアップ対象にランサムウェアが一緒に複製されます。世代管理と変更不可ストレージが防御策です。最新のバックアップだけを保持する構成は、この状況で無力です。

方式4 — 復元先システムの環境が異なります。UID/GIDのマッピング、SELinuxコンテキスト、カーネルのバージョン、ファイルシステムの機能が異なると、復元はできてもサービスが起動しません。--numeric-ids--selinux がこれに対する備えです。

方式5 — バックアップが運用性能を損ない、バックアップの窓が狭くなります。そのうち結局は周期を延ばし、あるときRPOを満たせなくなります。負荷を下げて実行してください。

ionice -c 3 nice -n 19 rsync -aHAX --numeric-ids --bwlimit=50M /srv/data/ /backup/prod/data/

--bwlimit はネットワーク帯域を、ionice -c 3 はディスクの優先度を下げます。バックアップが運用を妨げなくなれば、周期を縮める余裕が生まれます。


クイズ: 理解度を確認しましょう

クイズ1: リアルタイムレプリケーションをしているのでバックアップは要らない、という主張にどう答えますか

答え: レプリケーションはミスと悪意ある変更をそのまま伝播するので、バックアップの代わりにはなりません

解説: レプリケーションはハードウェア障害と可用性の問題を解決します。一方バックアップは 時間を巻き戻す問題 を解決します。テーブルを誤って消せばレプリカでも即座に消え、ランサムウェアの暗号化もそのまま複製されます。

二つは互いに異なるリスクに対応する別々の装置であり、RTOが分単位で要求されるならレプリケーションが、巻き戻しが必要ならバックアップが答えです。ほとんどのサービスは両方とも必要です。

クイズ2: rsyncのバックアップスクリプトで最も危険なオプションの組み合わせと防御策は何でしょうか

答え: --deleteと元が未マウントの状態の組み合わせであり、事前ガードとdry-runが防御策です

解説: 元がマウントされておらず空のディレクトリになっている状態で --delete が実行されると、対象のすべてのファイルが削除されます。

mountpoint -q /srv/data || exit 1
[ "$(ls -A /srv/data | wc -l)" -gt 0 ] || exit 1
rsync -aHAX --numeric-ids --delete --dry-run /srv/data/ /backup/prod/data/

ガードを先に置き、スクリプトを変えるたびに --dry-run で確認する習慣が必要です。-i オプションを一緒に使えば、どんな変更が起きるのかを1行ずつ確認できます。

クイズ3: rsync -aだけを使うと何が抜け、それがなぜ問題になりますか

答え: ACL、拡張属性、ハードリンクが抜け、復元後に権限とセキュリティコンテキストが変わります

解説: 文書によると -a-rlptgoD と同じであり、ACL(-A)、拡張属性(-X)、ハードリンク(-H)は含みません。

rsync -aHAX --numeric-ids /srv/data/ /backup/prod/data/

SELinuxコンテキストは拡張属性として保存されるので、-X なしに復元するとRHEL系でサービスがアクセスを拒否されます。ハードリンクの多いバックアップストアをコピーするとき -H がないと、容量が何倍にも膨らみます。

クイズ4: データベースのファイルをrsyncでコピーしたバックアップがあります。信頼できるでしょうか

答え: 信頼できません。コピーの途中で変更が起きて一貫性が崩れます

解説: ファイルを順に読んでいる間に、前の部分と後ろの部分が互いに異なる時点の状態になります。データベースはこうしたアーカイブから起動できないか、もっと悪い場合は起動したうえで壊れたデータを露出します。

正しい方法はアプリケーションレベルのダンプか、停止時点を固定したスナップショットです。

pg_dump -Fc -d appdb -f /backup/appdb.dump
mysqldump --single-transaction appdb > /backup/appdb.sql

スナップショットを使うなら、スナップショットの直前にチェックポイントや書き込み停止の手順が必要です。

クイズ5: バックアップは毎日成功していたのに復旧に12時間かかり、RTOを超えました。何が間違っていたのでしょうか

答え: RTOを基準にバックアップの方式と保存場所を設計していませんでした

解説: RPOは周期を、RTOは方式と場所を決めます。リモートアーカイブから数百ギガバイトをダウンロードして復元する構成は、RPOは満たしてもRTOは満たせません。

対応は階層化です。直近の数日分はローカルディスクに置いて速く復元し、長期保管分だけをリモートに置きます。そしてリハーサルで実際の所要時間を測定しなければなりません。測定していないRTOは希望にすぎません。

クイズ6: 運用サーバーが侵害されたときにバックアップまで削除されないようにするには、構造をどう組みますか

答え: バックアップサーバーが運用サーバーから引っ張ってくるpull方式にして、最低1つのコピーを変更不可ストレージに置きます

解説: 運用サーバーがバックアップストアへの書き込み権限を持っていれば、そのサーバーを掌握した攻撃者も同じ権限を持ちます。pull方式では運用サーバーにバックアップストアの資格情報がそもそもありません。

追加でオブジェクトストレージのバージョン管理とオブジェクトロック、あるいはオフラインのコピーを組み合わせます。世代管理も必須です。最新版だけを保持する構成では、暗号化されたデータがそのままバックアップを上書きします。


おわりに

バックアップの設計は、道具から始めると必ず食い違います。どの事故で何をどれだけ速く巻き戻さなければならないのか から始めるべきです。その答えがRPOとRTOであり、残りはそこから導かれます。

そして最後の一行だけ覚えておけば十分です。復旧してみたことのないバックアップはバックアップではありません。今期のうちに復旧リハーサルの日程を入れてください。バックアップを作った人ではない別の人が、文書だけを見て、時間を計りながら行うリハーサルでなければなりません。その一度が、実際の事故で何時間も節約してくれます。


参考資料


関連記事

현재 단락 (1/155)

バックアップに関する最もよくある誤解は「バックアップをしているから安全だ」です。実際は違います。**復旧してみたことのないバックアップは、バックアップではなくバックアップだと信じているファイルの山**...

작성 글자: 0원문 글자: 10,677작성 단락: 0/155