2026年11月10日

2026年11月10日

WordPressの大規模データベースをエクスポートする方法

はじめに

数GB以上の大規模データベースをエクスポートする場合、phpMyAdminではタイムアウトやメモリ不足で失敗します。mysqldumpのオプションを適切に設定し、テーブルを分割してエクスポートすることで確実に完了させられます。

症状・原因

  • phpMyAdminでエクスポートがタイムアウトで失敗する
  • mysqldumpがメモリ不足でkillされる
  • エクスポートファイルが途中で壊れている
  • データベースが数GBあってダウンロードに時間がかかる

解決手順

ステップ1:データベースのサイズと構成を把握する

# データベース全体のサイズ確認
mysql -u wordpress_user -p -e "
SELECT
    table_schema AS 'Database',
    ROUND(SUM(data_length + index_length) / 1024 / 1024, 1) AS 'Size (MB)'
FROM information_schema.tables
WHERE table_schema = 'wordpress_db'
GROUP BY table_schema;"

# テーブルごとのサイズ(大きい順)
mysql -u wordpress_user -p -e "
SELECT table_name,
    ROUND(data_length / 1024 / 1024, 1) AS data_MB,
    ROUND(index_length / 1024 / 1024, 1) AS index_MB,
    table_rows
FROM information_schema.tables
WHERE table_schema = 'wordpress_db'
ORDER BY (data_length + index_length) DESC;" wordpress_db

# 大きなテーブルを特定(100MB超)
wp db query "SELECT table_name, ROUND((data_length+index_length)/1024/1024) AS mb
FROM information_schema.tables
WHERE table_schema=DATABASE() AND (data_length+index_length) > 104857600
ORDER BY mb DESC;"

ステップ2:mysqldump の最適化オプションで一括エクスポート

# 大規模DB向け最適化オプション
mysqldump \
    -u wordpress_user \
    -p \
    --single-transaction \
    --quick \
    --max_allowed_packet=512M \
    --net_buffer_length=32768 \
    --extended-insert \
    --compress \
    wordpress_db | gzip > wp_full_$(date +%Y%m%d).sql.gz

# オプション解説:
# --quick: 1行ずつ取得してメモリを節約
# --single-transaction: InnoDB でロックなし
# --max_allowed_packet=512M: 大きな行データに対応
# --net_buffer_length=32768: ネットワークバッファを拡張
# --extended-insert: 複数行を1つのINSERTにまとめて高速化
# --compress: MySQL接続の圧縮(リモートDBの場合に有効)

ステップ3:テーブルを分割してエクスポートする

#!/bin/bash
# 大きなテーブルを個別にエクスポート

DB_NAME="wordpress_db"
DB_USER="wordpress_user"
DB_PASS="password"
BACKUP_DIR="/home/user/db_backup_split"
mkdir -p "$BACKUP_DIR"

# テーブル一覧を取得
TABLES=$(mysql -u "$DB_USER" -p"$DB_PASS" -N -e \
    "SHOW TABLES;" "$DB_NAME")

for TABLE in $TABLES; do
    echo "Exporting: $TABLE"
    mysqldump \
        -u "$DB_USER" -p"$DB_PASS" \
        --single-transaction --quick \
        "$DB_NAME" "$TABLE" | \
        gzip > "$BACKUP_DIR/${TABLE}.sql.gz"
    echo "  Done: $(du -sh "$BACKUP_DIR/${TABLE}.sql.gz" | cut -f1)"
done

echo "All tables exported to $BACKUP_DIR"
ls -lh "$BACKUP_DIR"

# 全ファイルをまとめて tar.gz に圧縮
tar -czf "$BACKUP_DIR/../wp_db_split_$(date +%Y%m%d).tar.gz" \
    -C "$BACKUP_DIR" .

ステップ4:WP-CLI でテーブルを選択してエクスポートする

# wp_posts だけエクスポート(最大テーブルが多い場合)
wp db export --tables=wp_posts posts_$(date +%Y%m%d).sql

# メタデータを除外してエクスポート(容量削減)
wp db export --exclude-tables=wp_postmeta,wp_commentmeta \
    wp_without_meta_$(date +%Y%m%d).sql

# 特定の投稿タイプのみエクスポート(SQL直接実行)
wp db query "SELECT * FROM wp_posts WHERE post_type='post' AND post_status='publish'
INTO OUTFILE '/tmp/published_posts.sql'
FIELDS TERMINATED BY ','
ENCLOSED BY '\"'
LINES TERMINATED BY '\n';"

# CSV形式でエクスポート(データ分析用)
wp db export --result-file=wp_posts_$(date +%Y%m%d).sql \
    -- --tables=wp_posts --no-create-info

ステップ5:エクスポートファイルの転送と検証

# ファイルサイズと整合性を確認
ls -lh wp_full_$(date +%Y%m%d).sql.gz
gzip -l wp_full_$(date +%Y%m%d).sql.gz
gzip -t wp_full_$(date +%Y%m%d).sql.gz && echo "ファイル整合性OK"

# MD5チェックサムを生成(転送後の確認用)
md5sum wp_full_$(date +%Y%m%d).sql.gz > wp_full_$(date +%Y%m%d).sql.gz.md5
cat wp_full_$(date +%Y%m%d).sql.gz.md5

# SCP でリモートサーバーに転送
scp wp_full_$(date +%Y%m%d).sql.gz \
    user@new-server:/var/www/backups/

# 転送後に整合性確認
ssh user@new-server "md5sum /var/www/backups/wp_full_$(date +%Y%m%d).sql.gz"
# ← ローカルのMD5と一致すれば転送成功

# rsync で差分転送(再送時に便利)
rsync -avz --progress \
    wp_full_$(date +%Y%m%d).sql.gz \
    user@new-server:/var/www/backups/

注意事項

  • --quickオプションは1行ずつ取得するためメモリ使用量を抑えられますが、エクスポート速度がやや遅くなります。メモリに余裕がある場合は省略しても構いません
  • --single-transactionはInnoDBエンジン専用です。MyISAMテーブルが混在する場合は--lock-tablesを使用するか、MyISAMテーブルを先に個別にエクスポートしてください
  • phpMyAdminでのエクスポートはphp.iniのmax_execution_timeとmemory_limitに制限されます。大規模DBはコマンドラインのmysqldumpを使用することを強く推奨します

まとめ

大規模DBエクスポートは①information_schemaクエリで100MB超のテーブルを事前特定、②mysqldump --quick --single-transaction --max_allowed_packet=512M | gzipで一括エクスポート、③シェルスクリプトで全テーブルを個別ファイルに分割エクスポート、④wp db export --exclude-tablesで不要テーブルを除外してサイズ削減、⑤gzip -tで整合性確認・md5sumでチェックサム生成後にrsyncで転送します。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲