インフラ・運用 2026.07.16

本番DBのバックアップ、「取れているつもり」になっていませんか?

約14分で読めます

バックアップは「取得すること」ではなく「復元できること」が目的です。復元テストで発覚しやすい落とし穴と、実際に機能するバックアップ運用の構築方法を解説します。

こんな状況、心当たりはありませんか?

サーバーのバックアップ設定は済んでいる。cronも動いている。ログを見れば毎日ファイルが生成されている——それなのに、いざというとき「復元できなかった」という事態が、実際の現場では想像以上に多く起きています。

バックアップに関する最も危険な思い込みは、「ファイルが存在すること」と「データが復元できること」を同一視してしまうことです。圧縮ファイルが壊れていた、文字コードが崩れた、外部キー制約でインポートが止まった——こうした問題は、復元を試みるまで表面化しません。

「万が一のとき」に初めて動作確認するのでは、完全に手遅れです。この記事では、Fivenineが実案件で遭遇したバックアップ運用の落とし穴と、「本当に使えるバックアップ」を構築するための具体的な手順をお伝えします。


なぜ「取れているつもり」が生まれるのか

バックアップが形骸化する背景には、いくつかの共通したパターンがあります。

取得と検証が分離されている

バックアップの取得を自動化した時点で「完了」と認識し、その後の検証フローが設計されていないケースが大半です。cronでスクリプトを仕込んで満足してしまう——エンジニアとしてよく陥りがちな状態です。

バックアップ対象の抜け漏れ

DBのダンプだけ取得して、アップロードファイル(storage/app配下など)やenvファイルを対象外にしているケースがあります。アプリケーションの復元にはコードだけでなく、設定ファイルや静的リソースも不可欠です。

ストレージ容量の枯渇

毎日フルダンプを取得していると、数週間後にはディスクが満杯になり、以降のバックアップが無音で失敗し続けることがあります。アラートが設定されていなければ、誰も気づきません。

保存先が本番サーバーと同一

バックアップを本番サーバー内に保存するだけでは、サーバーそのものが落ちたときに共倒れになります。オフサイトへの転送が必須です。


サーバー・インフラでお困りですか?

障害対応・移行・パフォーマンスチューニングなど、ご相談ください

無料で相談する

実案件での失敗事例:EC系サービスのDBが復元不能に

あるECサイトのリニューアル案件を受託した際、前担当会社が構築したバックアップの引き継ぎ確認を行いました。毎日.sql.gzファイルが生成されているように見えたのですが、実際にステージング環境で復元を試みたところ、インポートが途中で止まりました。

エラーログを確認すると、原因はシンプルなものでした。

ERROR 1215 (HY000): Cannot add foreign key constraint

ダンプ取得時に--single-transaction--routinesは指定されていたものの、外部キー制約の無効化が考慮されていなかったため、テーブルの挿入順序によってはエラーが発生する状態でした。長期間、「バックアップが取れている」と信じられていたファイルが、実際には使い物にならなかったのです。

この経験から、Fivenineではすべての案件でバックアップスクリプトに復元テストの手順書を添付することをルール化しています。


本当に使えるバックアップスクリプトの実装

MySQLを対象に、実際に使えるバックアップと復元テストのスクリプト例を示します。

#!/bin/bash

# 設定
DB_NAME="your_database"
DB_USER="your_user"
DB_PASS="your_password"
BACKUP_DIR="/var/backups/mysql"
DATE=$(date +%Y%m%d_%H%M%S)
FILE="${BACKUP_DIR}/${DB_NAME}_${DATE}.sql.gz"
RETENTION_DAYS=14

# バックアップ先ディレクトリの確認
mkdir -p "$BACKUP_DIR"

# ダンプ取得(外部キー制約・ルーティン含む)
mysqldump \
  --user="$DB_USER" \
  --password="$DB_PASS" \
  --single-transaction \
  --routines \
  --triggers \
  --set-gtid-purged=OFF \
  "$DB_NAME" \
  | gzip > "$FILE"

# 取得成否の確認
if [ $? -ne 0 ] || [ ! -s "$FILE" ]; then
  echo "[ERROR] バックアップ失敗: $FILE" | mail -s "DB Backup FAILED" [email protected]
  exit 1
fi

# 古いバックアップを削除
find "$BACKUP_DIR" -name "*.sql.gz" -mtime +$RETENTION_DAYS -delete

# S3へオフサイト転送
aws s3 cp "$FILE" s3://your-bucket/db-backups/

echo "[OK] バックアップ完了: $FILE"

Laravelプロジェクトでの統合

Laravelを使ったプロジェクトでは、spatie/laravel-backupパッケージを活用すると、DB・ファイルシステム・通知を一元管理できます。

// config/backup.php の主要設定
'backup' => [
    'source' => [
        'databases' => ['mysql'],
        'files' => [
            'include' => [base_path()],
            'exclude' => [
                base_path('vendor'),
                base_path('node_modules'),
            ],
        ],
    ],
    'destination' => [
        'disks' => ['s3'],  // S3等のオフサイトストレージ
    ],
],

// kernel.php でスケジュール設定
$schedule->command('backup:run')->dailyAt('02:00');
$schedule->command('backup:monitor')->dailyAt('09:00');

backup:monitorコマンドは、バックアップの最終取得日時やファイルサイズを自動チェックし、異常があればSlackやメールで通知してくれます。こういったモニタリングの自動化が、「知らないうちに失敗していた」状況を防ぐ鍵です。


バックアップ品質チェック:よくある落とし穴

mysqldumpはコマンド自体が成功終了コード(0)を返しても、認証エラー等でファイルが空になることがあります。スクリプト内で`[ ! -s "$FILE" ]`(ファイルサイズが0でないこと)を明示的に確認する処理を必ず入れてください。
バックアップ取得時にディスク容量が不足すると、gzipファイルが途中で切れた状態で保存されます。取得後に`gzip -t $FILE`でファイルの整合性テストを行うことを推奨します。
utf8mb4を使っているDBを、文字コード指定なしでダンプ・インポートすると絵文字や一部文字が化けます。mysqldumpのオプションに`--default-character-set=utf8mb4`を追加し、インポート先DBの照合順序も統一してください。
`--routines`と`--triggers`オプションを省略すると、DB構造の一部しかバックアップされません。ビューや定期バッチが依存している場合、サイレントに機能不全が発生します。
サーバーの物理障害・ランサムウェア被害では、本番サーバーと同じディスク上のバックアップも失われます。S3・GCS・Cloudflare R2などへのオフサイト転送を必ず組み合わせてください。

バックアップ運用の健全度チェック

特に「復元テスト」の項目は、多くの現場で著しく低い水準にとどまっています。月次で5〜10分の復元確認を行うだけで、このスコアは劇的に改善します。


サーバー・インフラでお困りですか?

障害対応・移行・パフォーマンスチューニングなど、ご相談ください

無料で相談する

サーバー管理、丸ごとお任せください

サーバー保守・運用

監視・障害対応・パフォーマンス改善まで、安定稼働をサポートします

200件以上の制作実績 顧客満足度97% 初回相談無料

※ 通常1営業日以内にご返信します

まとめ:今日から始める3つのアクション

バックアップは「取得」ではなく「復元」まで含めて初めて機能します。完璧な仕組みを一度に構築する必要はありません。まず以下の3点から着手してください。

1. 既存バックアップの復元テストを今すぐ実施する 最新のバックアップファイルを使い、ステージング環境でrestore_test.shを走らせてください。ここで問題が見つかれば、対処のタイミングとしては今が最善です。

2. バックアップスクリプトにアラートを組み込む 失敗時に通知が飛ばない運用は、問題の発見が常に手遅れになります。メール・Slack・PagerDutyなど、チームが確実に気づける通知先を設定してください。

3. 月1回の復元テストをカレンダーに入れる 自動化できれば理想ですが、まずは手動でも構いません。毎月第1営業日に復元確認を行うことをスケジュールに組み込んでください。


バックアップ運用の見直しは、地味ながらもサービスの信頼性を支える重要な基盤整備です。「うちの設定、本当に大丈夫?」と少しでも不安を感じた方は、ぜひFivenine Designにご相談ください。現在の運用状況を確認し、実際に復元テストを交えた診断から対応しています。

この記事をシェア

サーバー・インフラの課題を解決します

構築・移行・監視・障害対応まで、安定した運用環境をご提供します。 初回相談は無料です。

※ 1営業日以内にご返信いたします

この技術でお困りなら

無料でプロに相談できます

相談する
AIに無料相談