T-CREATOR

バックアップ戦略の決定版:WordPress の世代管理/災害復旧の型

バックアップ戦略の決定版:WordPress の世代管理/災害復旧の型

WordPress サイトを運用していると、「もしもの時」への備えが気になりませんか。データ消失、サーバー障害、人的ミス——こうしたリスクから大切なサイトを守るには、体系的なバックアップ戦略が欠かせません。本記事では、世代管理と災害復旧(DR: Disaster Recovery)を軸にした WordPress バックアップの決定版をご紹介します。

初心者の方でもすぐに実践できるよう、具体的なコード例と図解を交えて解説していきますね。安心してサイト運用を続けられる環境を、一緒に構築していきましょう。

背景

WordPress におけるデータの重要性

WordPress サイトは、データベース(MySQL/MariaDB)とファイルシステム(テーマ、プラグイン、メディアファイル)の 2 つの要素から成り立っています。これらのデータは企業の資産であり、個人ブログであっても長年蓄積された貴重なコンテンツです。

データ消失の原因は多岐にわたります。ハードウェア障害、ソフトウェアの不具合、サイバー攻撃、そして人的ミス。特に WordPress の更新作業中のトラブルや、プラグインの競合によるデータ破損は頻繁に報告されているのです。

バックアップ戦略の必要性

単にバックアップを取るだけでは不十分です。いつ、何を、どのように保存し、どう復旧するか——この一連のプロセスを体系化した「戦略」が求められます。

以下の図は、WordPress サイトのデータフローとバックアップ対象の関係を示しています。

mermaidflowchart TB
  user["サイト訪問者"] -->|HTTP リクエスト| wp["WordPress<br/>コアシステム"]
  wp -->|クエリ| db[("MySQL/MariaDB<br/>データベース")]
  wp -->|読み込み| files["ファイルシステム<br/>(テーマ/プラグイン/メディア)"]

  db -->|バックアップ対象 1| backup1["DB バックアップ"]
  files -->|バックアップ対象 2| backup2["ファイルバックアップ"]

  backup1 --> storage["世代管理<br/>ストレージ"]
  backup2 --> storage

  storage -->|災害復旧| restore["復旧プロセス"]

図で理解できる要点:

  • WordPress は「データベース」と「ファイルシステム」の 2 つを持つ
  • それぞれ独立したバックアップが必要
  • 世代管理ストレージで複数世代を保持し、復旧に備える

データベースには投稿内容や設定が、ファイルシステムにはテーマやアップロードした画像が保存されています。両方を適切にバックアップすることで、完全な復旧が可能になるのです。

世代管理の概念

世代管理とは、複数の時点のバックアップを保持する手法です。最新のバックアップだけでは、データが壊れた状態でバックアップを取得してしまうリスクがあります。

たとえば、ウイルス感染に気づかずバックアップを上書きしてしまった場合、感染前の状態に戻せなくなってしまうでしょう。複数世代を保持することで、「いつの時点に戻すか」を選択できる柔軟性が生まれます。

課題

WordPress バックアップの一般的な問題点

多くの WordPress ユーザーが直面する課題を整理してみましょう。これらは実際の運用現場で頻繁に遭遇する問題です。

課題 1:バックアップの不完全性

WordPress のバックアップは、データベースとファイルシステムの両方を対象にする必要があります。しかし、多くのバックアッププラグインはどちらか一方しかカバーしていないケースもあるのです。

片方だけのバックアップでは、復旧時に「投稿は戻ったが画像が全て消えた」「テーマファイルは残っているがコンテンツが空っぽ」といった事態に陥ります。

課題 2:世代管理の欠如

最新のバックアップのみを保持している環境では、以下のような問題が発生しやすくなります。

#問題具体例影響度
1データ破損の見逃しマルウェア感染後のバックアップを上書き★★★
2復旧ポイントの選択不可誤削除に気づくのが遅れた場合★★★
3ストレージコストの最適化困難古いバックアップを手動削除★★☆

これらの問題を解決するには、自動的に世代管理を行う仕組みが必要です。

課題 3:復旧手順の不明確さ

バックアップを取得していても、いざという時に「どうやって復旧するのか分からない」という状況では意味がありません。復旧手順が文書化されていない、あるいは定期的なテストが行われていないと、本番環境での復旧に失敗するリスクが高まるでしょう。

以下の図は、バックアップ戦略が不十分な場合に発生する問題の連鎖を示しています。

mermaidflowchart TD
  start["バックアップ戦略<br/>の不備"] --> incomplete["不完全な<br/>バックアップ"]
  start --> noversion["世代管理<br/>なし"]
  start --> notest["復旧テスト<br/>未実施"]

  incomplete --> loss1["データ消失<br/>(一部)"]
  noversion --> loss2["復旧ポイント<br/>選択不可"]
  notest --> loss3["復旧失敗"]

  loss1 --> impact["ビジネス<br/>インパクト"]
  loss2 --> impact
  loss3 --> impact

  impact --> result1["売上損失"]
  impact --> result2["信頼低下"]
  impact --> result3["SEO 順位<br/>低下"]

図で理解できる要点:

  • バックアップ戦略の不備は複数の問題を引き起こす
  • 各問題が独立してビジネスインパクトにつながる
  • 総合的な対策が必要

災害復旧における課題

災害復旧(DR)の観点では、さらに高度な課題があります。

RTO と RPO の理解不足

  • RTO(Recovery Time Objective):復旧目標時間——どれくらいの時間でサービスを復旧させるか
  • RPO(Recovery Point Objective):復旧目標時点——どの時点まで遡ってデータを復旧するか

これらの指標を定義せずにバックアップ戦略を立てると、「とりあえずバックアップを取っている」状態になりがちです。ビジネス要件に応じた適切な RTO/RPO の設定が求められます。

オフサイトバックアップの欠如

同じサーバー内、あるいは同じデータセンター内にのみバックアップを保存していると、物理的な災害(火災、地震、洪水)やデータセンター全体の障害に対応できません。

地理的に離れた場所へのバックアップ保存(オフサイトバックアップ)が、真の災害復旧には不可欠なのです。

解決策

包括的バックアップ戦略の設計

WordPress のバックアップ戦略は、以下の 3 つの柱で構成されます。

  1. 完全性の確保:データベースとファイルシステムの両方をバックアップ
  2. 世代管理の実装:GFS(Grandfather-Father-Son)方式などによる複数世代保持
  3. 災害復旧計画:RTO/RPO の定義とオフサイトバックアップの実施

それでは、具体的な実装方法を見ていきましょう。

バックアップ対象の明確化

WordPress サイトで保護すべきデータを明確にします。

データベースバックアップ対象

以下のテーブル群がバックアップの対象となります。

sql-- WordPress のコアテーブル一覧
-- wp_ はデフォルトのプレフィックス(環境により異なる場合あり)

-- 投稿・固定ページ
wp_posts

-- コメント
wp_comments
sql-- ユーザー情報
wp_users
wp_usermeta

-- オプション(サイト設定)
wp_options
sql-- タクソノミー(カテゴリー・タグ)
wp_terms
wp_term_taxonomy
wp_term_relationships

これらのテーブルには、サイトの全てのコンテンツと設定が含まれています。データベース全体をバックアップすることで、投稿、ページ、コメント、ユーザー情報、サイト設定を全て保護できるのです。

ファイルシステムバックアップ対象

ファイルシステムでは、以下のディレクトリが重要です。

#ディレクトリ内容優先度
1wp-content​/​uploads​/​メディアファイル(画像・動画)★★★
2wp-content​/​themes​/​テーマファイル★★★
3wp-content​/​plugins​/​プラグインファイル★★☆
4wp-config.phpWordPress 設定ファイル★★★
5.htaccessサーバー設定ファイル★★☆

WordPress コア自体は公式サイトから再ダウンロード可能なため、通常はバックアップ対象外とします。ただし、コアファイルをカスタマイズしている場合は対象に含めましょう。

GFS 世代管理方式の実装

GFS(Grandfather-Father-Son)方式は、バックアップの世代管理で広く採用されている手法です。

mermaidflowchart LR
  daily["日次バックアップ<br/>(Son)<br/>7 世代保持"] --> weekly["週次バックアップ<br/>(Father)<br/>4 世代保持"]
  weekly --> monthly["月次バックアップ<br/>(Grandfather)<br/>12 世代保持"]

  daily -.->|古い世代を削除| delete1["自動削除<br/>(8 日前)"]
  weekly -.->|古い世代を削除| delete2["自動削除<br/>(5 週前)"]
  monthly -.->|古い世代を削除| delete3["自動削除<br/>(13 ヶ月前)"]

図で理解できる要点:

  • 3 つの階層で異なる保持期間を設定
  • 日次は短期復旧用、月次は長期保管用
  • 古い世代は自動的に削除されストレージを最適化

この方式により、以下のメリットが得られます。

  • 短期復旧:直近 7 日間の日次バックアップで、昨日・一昨日の状態に戻せる
  • 中期復旧:4 週間分の週次バックアップで、1〜4 週間前の状態に戻せる
  • 長期保管:12 ヶ月分の月次バックアップで、数ヶ月前の状態も保持
  • ストレージ効率:古いバックアップは自動削除され、無限に増え続けない

バックアップ自動化スクリプトの実装

それでは、実際のバックアップスクリプトを段階的に構築していきましょう。シェルスクリプトを使用して、データベースとファイルシステムの両方を自動バックアップします。

スクリプトの基本設定

まず、バックアップスクリプトの設定部分を定義します。

bash#!/bin/bash
# WordPress バックアップスクリプト
# 用途:データベースとファイルシステムの自動バックアップ

# 設定変数
BACKUP_DIR="/backup/wordpress"
WP_DIR="/var/www/html/wordpress"
DB_NAME="wordpress_db"
DB_USER="wp_user"
DB_PASS="your_secure_password"
bash# 世代管理の保持期間設定
DAILY_RETENTION=7      # 日次バックアップを 7 世代保持
WEEKLY_RETENTION=4     # 週次バックアップを 4 世代保持
MONTHLY_RETENTION=12   # 月次バックアップを 12 世代保持

# タイムスタンプ生成
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
DAY_OF_WEEK=$(date +%u)  # 1=月曜, 7=日曜
DAY_OF_MONTH=$(date +%d) # 1-31

これらの変数で、バックアップの保存先や対象データベース、保持期間を管理します。

データベースバックアップ処理

次に、データベースのバックアップ処理を実装しましょう。

bash# データベースバックアップ関数
backup_database() {
    local backup_type=$1  # daily, weekly, monthly
    local backup_file="${BACKUP_DIR}/db/${backup_type}/db_${TIMESTAMP}.sql.gz"

    # バックアップディレクトリの作成
    mkdir -p "${BACKUP_DIR}/db/${backup_type}"

    echo "データベースバックアップ開始: ${backup_type}"
bash    # mysqldump でデータベースをエクスポートし、gzip で圧縮
    mysqldump \
        --user="${DB_USER}" \
        --password="${DB_PASS}" \
        --single-transaction \
        --quick \
        --lock-tables=false \
        "${DB_NAME}" | gzip > "${backup_file}"

    # バックアップの成否を確認
    if [ $? -eq 0 ]; then
        echo "データベースバックアップ成功: ${backup_file}"
        return 0
    else
        echo "エラー: データベースバックアップ失敗"
        return 1
    fi
}

mysqldump コマンドのオプションについて解説します。

  • --single-transaction:トランザクションを使用し、バックアップ中もサイトの動作を妨げない
  • --quick:大規模データベースでもメモリ効率よく処理
  • --lock-tables=false:テーブルロックを避け、サービス継続性を確保

これにより、サイトを停止せずにバックアップを取得できるのです。

ファイルシステムバックアップ処理

続いて、ファイルシステムのバックアップ処理を実装します。

bash# ファイルシステムバックアップ関数
backup_files() {
    local backup_type=$1  # daily, weekly, monthly
    local backup_file="${BACKUP_DIR}/files/${backup_type}/files_${TIMESTAMP}.tar.gz"

    # バックアップディレクトリの作成
    mkdir -p "${BACKUP_DIR}/files/${backup_type}"

    echo "ファイルバックアップ開始: ${backup_type}"
bash    # tar で圧縮アーカイブを作成
    # wp-content, wp-config.php, .htaccess を対象
    tar -czf "${backup_file}" \
        -C "${WP_DIR}" \
        wp-content \
        wp-config.php \
        .htaccess \
        2>/dev/null

    # バックアップの成否を確認
    if [ $? -eq 0 ]; then
        echo "ファイルバックアップ成功: ${backup_file}"
        return 0
    else
        echo "エラー: ファイルバックアップ失敗"
        return 1
    fi
}

tar コマンドで、必要なファイルとディレクトリを圧縮アーカイブにまとめます。-C オプションで WordPress のルートディレクトリに移動してから、相対パスでファイルを指定しているのがポイントです。

世代管理と古いバックアップの削除

GFS 方式に従って、古いバックアップを自動削除する処理を実装しましょう。

bash# 古いバックアップを削除する関数
cleanup_old_backups() {
    local backup_type=$1
    local retention=$2

    echo "古いバックアップを削除: ${backup_type} (保持世代: ${retention})"

    # データベースバックアップの削除
    find "${BACKUP_DIR}/db/${backup_type}" \
        -name "*.sql.gz" \
        -type f \
        -mtime +${retention} \
        -delete
bash    # ファイルバックアップの削除
    find "${BACKUP_DIR}/files/${backup_type}" \
        -name "*.tar.gz" \
        -type f \
        -mtime +${retention} \
        -delete

    echo "古いバックアップ削除完了"
}

find コマンドの -mtime +${retention} オプションで、指定した日数より古いファイルを検索し、-delete で削除します。これにより、自動的にストレージを管理できるのです。

メイン処理とスケジューリング

最後に、メイン処理を実装します。日次・週次・月次のバックアップを判定し、適切に実行する処理です。

bash# メイン処理
main() {
    echo "=========================================="
    echo "WordPress バックアップ開始: ${TIMESTAMP}"
    echo "=========================================="

    # 月初(1 日)の場合は月次バックアップ
    if [ "${DAY_OF_MONTH}" -eq 1 ]; then
        backup_database "monthly"
        backup_files "monthly"
        cleanup_old_backups "monthly" ${MONTHLY_RETENTION}
bash    # 日曜日の場合は週次バックアップ
    elif [ "${DAY_OF_WEEK}" -eq 7 ]; then
        backup_database "weekly"
        backup_files "weekly"
        cleanup_old_backups "weekly" ${WEEKLY_RETENTION}

    # それ以外は日次バックアップ
    else
        backup_database "daily"
        backup_files "daily"
        cleanup_old_backups "daily" ${DAILY_RETENTION}
    fi
bash    echo "=========================================="
    echo "WordPress バックアップ完了"
    echo "=========================================="
}

# スクリプト実行
main

このメイン処理により、実行日に応じて自動的に適切なバックアップタイプが選択されます。

cron で毎日自動実行するには、以下のように設定しましょう。

bash# crontab に追加
# 毎日午前 2 時に実行
0 2 * * * /usr/local/bin/wordpress_backup.sh >> /var/log/wordpress_backup.log 2>&1

これで、完全自動化されたバックアップシステムが完成します。

オフサイトバックアップの実装

災害復旧のためには、バックアップを地理的に離れた場所に保存する必要があります。AWS S3 を使用したオフサイトバックアップの実装例をご紹介しましょう。

AWS CLI のインストールと設定

まず、AWS CLI をインストールします。

bash# AWS CLI のインストール(Ubuntu/Debian の場合)
apt-get update
apt-get install -y awscli

# AWS CLI の設定
aws configure
# AWS Access Key ID: your_access_key
# AWS Secret Access Key: your_secret_key
# Default region name: ap-northeast-1
# Default output format: json

認証情報は、IAM ユーザーで適切な権限(S3 への書き込み権限)を持つものを使用してください。

S3 へのバックアップ同期スクリプト

バックアップを S3 にアップロードするスクリプトを作成します。

bash#!/bin/bash
# S3 オフサイトバックアップスクリプト

# 設定
BACKUP_DIR="/backup/wordpress"
S3_BUCKET="s3://your-backup-bucket/wordpress"
AWS_PROFILE="default"

echo "S3 へのバックアップ同期開始"
bash# バックアップディレクトリを S3 に同期
# --delete オプションでローカルで削除されたファイルを S3 からも削除
aws s3 sync \
    "${BACKUP_DIR}" \
    "${S3_BUCKET}" \
    --profile "${AWS_PROFILE}" \
    --storage-class STANDARD_IA \
    --delete

if [ $? -eq 0 ]; then
    echo "S3 同期成功"
else
    echo "エラー: S3 同期失敗"
    exit 1
fi

--storage-class STANDARD_IA オプションで、低頻度アクセス用のストレージクラスを指定し、コストを削減しています。バックアップは読み込みが少ないため、このストレージクラスが適しているのです。

S3 ライフサイクルポリシーの設定

S3 側でライフサイクルポリシーを設定し、さらに古いバックアップを Glacier に移行したり削除したりできます。

json{
  "Rules": [
    {
      "Id": "ArchiveOldBackups",
      "Status": "Enabled",
      "Filter": {
        "Prefix": "wordpress/"
      },
      "Transitions": [
        {
          "Days": 90,
          "StorageClass": "GLACIER"
        }
      ],
json      "Expiration": {
        "Days": 365
      }
    }
  ]
}

このポリシーにより、90 日経過したバックアップは Glacier に移行され、365 日経過すると自動削除されます。長期保管が必要な場合は、Expiration の日数を調整しましょう。

復旧手順の確立

バックアップを取得するだけでなく、復旧手順を明確にし、定期的にテストすることが重要です。

データベース復旧スクリプト

データベースを復旧するスクリプトを作成します。

bash#!/bin/bash
# データベース復旧スクリプト

# 引数チェック
if [ $# -ne 1 ]; then
    echo "使用方法: $0 <backup_file.sql.gz>"
    exit 1
fi

BACKUP_FILE=$1
DB_NAME="wordpress_db"
DB_USER="wp_user"
DB_PASS="your_secure_password"
bashecho "データベース復旧開始: ${BACKUP_FILE}"
echo "警告: 既存のデータベースは上書きされます"
read -p "続行しますか? (yes/no): " confirm

if [ "$confirm" != "yes" ]; then
    echo "復旧をキャンセルしました"
    exit 0
fi
bash# バックアップファイルを解凍してデータベースにインポート
gunzip < "${BACKUP_FILE}" | mysql \
    --user="${DB_USER}" \
    --password="${DB_PASS}" \
    "${DB_NAME}"

if [ $? -eq 0 ]; then
    echo "データベース復旧成功"
else
    echo "エラー: データベース復旧失敗"
    exit 1
fi

このスクリプトでは、誤操作を防ぐために確認プロンプトを表示しています。本番環境での復旧は慎重に行いましょう。

ファイルシステム復旧スクリプト

ファイルシステムを復旧するスクリプトも作成します。

bash#!/bin/bash
# ファイルシステム復旧スクリプト

# 引数チェック
if [ $# -ne 1 ]; then
    echo "使用方法: $0 <backup_file.tar.gz>"
    exit 1
fi

BACKUP_FILE=$1
WP_DIR="/var/www/html/wordpress"
bashecho "ファイルシステム復旧開始: ${BACKUP_FILE}"
echo "警告: 既存のファイルは上書きされます"
read -p "続行しますか? (yes/no): " confirm

if [ "$confirm" != "yes" ]; then
    echo "復旧をキャンセルしました"
    exit 0
fi
bash# バックアップファイルを展開
tar -xzf "${BACKUP_FILE}" -C "${WP_DIR}"

if [ $? -eq 0 ]; then
    echo "ファイルシステム復旧成功"
    # パーミッションとオーナーを修正
    chown -R www-data:www-data "${WP_DIR}/wp-content"
    echo "パーミッション修正完了"
else
    echo "エラー: ファイルシステム復旧失敗"
    exit 1
fi

復旧後は、Web サーバー(Apache や Nginx)のユーザーがファイルにアクセスできるよう、適切なパーミッションとオーナーを設定することが重要です。

具体例

実際の運用シナリオ

ここでは、具体的な運用シナリオを通じて、バックアップ戦略がどのように機能するかを見ていきましょう。

シナリオ 1:プラグイン更新後の不具合

状況:人気の SEO プラグインを更新したところ、サイトが真っ白になり表示されなくなった。

発生時刻:2025 年 11 月 24 日 14:30

対応手順

  1. 問題の特定:プラグイン更新が原因と判明
  2. 復旧ポイントの選択:前日(11 月 23 日)の日次バックアップを使用
  3. データベース復旧:前日のデータベースバックアップから復元
  4. ファイル復旧:前日のファイルバックアップから復元
  5. 動作確認:サイトが正常に表示されることを確認
  6. 原因調査:プラグインの更新ログを確認し、既知の不具合であることを特定
bash# 実際の復旧コマンド例
./restore_database.sh /backup/wordpress/db/daily/db_20251123_020000.sql.gz
./restore_files.sh /backup/wordpress/files/daily/files_20251123_020000.tar.gz

RTO(復旧目標時間):30 分以内に復旧完了

RPO(復旧目標時点):前日 02:00 時点(データ損失:約 12 時間分の投稿・コメント)

このケースでは、日次バックアップにより迅速に復旧できました。更新前の状態に戻すことで、サービスの停止時間を最小限に抑えられたのです。

シナリオ 2:マルウェア感染

状況:サイトがマルウェアに感染し、訪問者に不正な広告が表示されるようになった。感染に気づくまで 3 日間経過していた。

発生時刻:感染は 2025 年 11 月 20 日頃、発見は 11 月 23 日

対応手順

  1. 感染範囲の調査:ファイルシステムとデータベースを確認
  2. 復旧ポイントの選択:感染前の 11 月 19 日(週次バックアップ)を使用
  3. クリーンな環境の構築:別サーバーで復旧テストを実施
  4. データベース復旧:11 月 19 日のバックアップから復元
  5. ファイル復旧:11 月 19 日のバックアップから復元
  6. セキュリティ対策:WordPress コア、プラグイン、テーマを最新版に更新
  7. 本番環境への適用:クリーンな環境を本番に反映
bash# 復旧コマンド例(週次バックアップを使用)
./restore_database.sh /backup/wordpress/db/weekly/db_20251119_020000.sql.gz
./restore_files.sh /backup/wordpress/files/weekly/files_20251119_020000.tar.gz

RTO(復旧目標時間):2 時間以内に復旧完了

RPO(復旧目標時点):11 月 19 日 02:00 時点(データ損失:4 日間分の投稿・コメント)

このケースでは、世代管理により感染前のクリーンな状態に戻すことができました。最新のバックアップだけでは、感染済みのデータで復旧してしまうところでしたね。

シナリオ 3:データセンター障害

状況:データセンター全体で火災が発生し、サーバーが完全に消失した。

発生時刻:2025 年 11 月 24 日 03:00

対応手順

以下の図は、災害復旧プロセスの全体像を示しています。

mermaidsequenceDiagram
    participant DC as 旧データセンター<br/>(消失)
    participant S3 as AWS S3<br/>(オフサイト)
    participant New as 新サーバー
    participant DNS as DNS サーバー

    Note over DC: 火災発生<br/>03:00
    DC->>S3: 最終バックアップ<br/>(02:00 完了済み)

    Note over New: 新サーバー構築<br/>開始
    New->>New: WordPress 環境<br/>セットアップ
    New->>S3: バックアップ<br/>ダウンロード
    S3-->>New: DB + ファイル
    New->>New: データベース<br/>復旧
    New->>New: ファイルシステム<br/>復旧
    New->>New: 動作確認<br/>テスト

    New->>DNS: IP アドレス<br/>更新依頼
    DNS-->>New: DNS 更新完了

    Note over New: サービス再開<br/>06:30

図で理解できる要点:

  • オフサイトバックアップ(S3)が災害時の唯一のデータソース
  • 新サーバー構築と並行してバックアップを取得
  • DNS 更新でトラフィックを新サーバーに誘導

具体的な手順は以下の通りです。

  1. 新サーバーの構築:別のクラウドプロバイダーで新規サーバーを立ち上げ(30 分)
  2. WordPress 環境のセットアップ:LAMP スタック(Linux, Apache, MySQL, PHP)をインストール(30 分)
  3. S3 からバックアップをダウンロード:最新の日次バックアップを取得(20 分)
  4. データベース復旧:ダウンロードしたバックアップから復元(15 分)
  5. ファイルシステム復旧:ダウンロードしたバックアップから復元(15 分)
  6. 動作確認:全ての機能が正常に動作するかテスト(30 分)
  7. DNS 切り替え:ドメインの DNS レコードを新サーバーの IP に変更(30 分〜数時間で伝播)
bash# S3 からバックアップをダウンロード
aws s3 cp s3://your-backup-bucket/wordpress/db/daily/db_20251124_020000.sql.gz ./
aws s3 cp s3://your-backup-bucket/wordpress/files/daily/files_20251124_020000.tar.gz ./

# 復旧実行
./restore_database.sh db_20251124_020000.sql.gz
./restore_files.sh files_20251124_020000.tar.gz

RTO(復旧目標時間):3〜4 時間以内にサービス再開

RPO(復旧目標時点):前日 02:00 時点(データ損失:約 1 時間分)

この重大な災害シナリオでも、オフサイトバックアップにより完全な復旧が可能でした。同じデータセンター内にのみバックアップを保存していたら、全てのデータが失われていたでしょう。

運用コストの試算

実際の運用において、バックアップ戦略にかかるコストを試算してみましょう。

ストレージコスト

中規模 WordPress サイト(データベース 500MB、ファイル 10GB)の場合を想定します。

#バックアップタイプ世代数1 世代あたり合計サイズ
1日次(圧縮後)72GB14GB
2週次(圧縮後)42GB8GB
3月次(圧縮後)122GB24GB
-合計--46GB

AWS S3 の料金(東京リージョン、STANDARD_IA ストレージクラス):

  • ストレージ:$0.0138/GB/月 × 46GB = 約 $0.64/月(約 90 円/月)
  • データ転送(アップロード):無料
  • データ転送(ダウンロード、復旧時のみ):$0.114/GB(最初の 10TB まで)

運用工数

自動化により、定常的な運用工数はほぼゼロになります。

  • バックアップ作業:完全自動化(0 時間/月)
  • 監視とログ確認:週 1 回、10 分程度(0.7 時間/月)
  • 復旧テスト:四半期に 1 回、2 時間程度(0.7 時間/月)
  • 合計:約 1.4 時間/月

バックアップ戦略の導入により、万が一の際の復旧時間を大幅に短縮できます。ダウンタイムによる損失を考えれば、この投資は十分に価値があるでしょう。

監視とアラート

バックアップが正常に実行されているか、継続的に監視することも重要です。

バックアップ成功の確認スクリプト

バックアップの実行状況を確認し、失敗時にアラートを送信するスクリプトを作成しましょう。

bash#!/bin/bash
# バックアップ監視スクリプト

BACKUP_DIR="/backup/wordpress"
LOG_FILE="/var/log/wordpress_backup.log"
ALERT_EMAIL="admin@example.com"
ALERT_THRESHOLD_HOURS=26  # 26 時間以上バックアップがなければアラート

echo "バックアップ監視開始"
bash# 最新のバックアップファイルを検索
latest_db=$(find "${BACKUP_DIR}/db" -name "*.sql.gz" -type f -printf '%T@ %p\n' | sort -n | tail -1)
latest_files=$(find "${BACKUP_DIR}/files" -name "*.tar.gz" -type f -printf '%T@ %p\n' | sort -n | tail -1)

# 最新バックアップの作成時刻を取得(エポック秒)
db_timestamp=$(echo "$latest_db" | awk '{print $1}' | cut -d. -f1)
files_timestamp=$(echo "$latest_files" | awk '{print $1}' | cut -d. -f1)
current_timestamp=$(date +%s)
bash# 経過時間を計算(時間単位)
db_hours_ago=$(( (current_timestamp - db_timestamp) / 3600 ))
files_hours_ago=$(( (current_timestamp - files_timestamp) / 3600 ))

# アラート判定
if [ $db_hours_ago -gt $ALERT_THRESHOLD_HOURS ] || [ $files_hours_ago -gt $ALERT_THRESHOLD_HOURS ]; then
    # アラートメール送信
    echo "警告: バックアップが ${ALERT_THRESHOLD_HOURS} 時間以上実行されていません" | \
        mail -s "WordPress バックアップアラート" "${ALERT_EMAIL}"
    echo "アラート送信: バックアップ遅延検出"
else
    echo "正常: バックアップは正常に実行されています"
fi

このスクリプトを cron で定期的(たとえば毎時)実行することで、バックアップの失敗を早期に検出できます。

まとめ

WordPress サイトのバックアップ戦略は、単なる「データのコピー」ではなく、ビジネス継続性を支える重要な基盤です。本記事でご紹介した内容を振り返りましょう。

実装した 3 つの柱

  1. 完全性の確保:データベースとファイルシステムの両方を漏れなくバックアップすることで、完全な復旧を可能にしました。

  2. 世代管理の実装:GFS(Grandfather-Father-Son)方式により、日次・週次・月次の複数世代を自動的に保持します。これにより、マルウェア感染や誤操作など、問題発生に気づくのが遅れた場合でも、クリーンな状態に復旧できるのです。

  3. 災害復旧計画:オフサイトバックアップ(AWS S3)の活用により、物理的な災害やデータセンター全体の障害にも対応できる体制を構築しました。

具体的な成果

この戦略を導入することで、以下の成果が得られます。

  • RTO の短縮:30 分〜4 時間以内での復旧が可能に
  • RPO の明確化:最大 24 時間以内のデータ損失に制限
  • 運用の自動化:定常的な人的作業をほぼゼロに
  • コストの最適化:月額 100 円程度のストレージコストで実現

継続的な改善

バックアップ戦略は一度構築したら終わりではありません。以下の活動を定期的に実施しましょう。

  • 復旧テスト:四半期に一度、実際にバックアップから復旧できるか確認
  • 容量の見直し:サイトの成長に応じてストレージ容量を調整
  • 手順の更新:WordPress のバージョンアップや環境変更に合わせて手順を更新

WordPress サイトを安心して運用するために、今日からバックアップ戦略を見直してみませんか。最初は小さく始めて、段階的に改善していけば良いのです。

この記事が、皆さまのサイト運用の一助となれば幸いです。

関連リンク

公式ドキュメント

AWS リソース

バックアップ関連

セキュリティ