2026年5月21日
2026年5月21日
WP Migrate DBのエラーを解決する方法
はじめに
WP Migrate DB(旧WP Migrate DB Pro)でデータベースのエクスポート中に「接続エラー」「タイムアウト」が発生する・URLの置換が不完全でシリアライズデータが壊れる・移行後にサイトが真っ白になる・大容量DBのエクスポートが途中で止まるといった問題は、PHPのタイムアウト設定・シリアライズデータの不正置換・サーバーのアップロードサイズ制限が原因です。
症状・原因
- 「Migration failed: Could not connect to the remote server」エラーが出る
- エクスポートしたSQLをインポートすると一部のオプションやメタデータが壊れる
- 移行後にサイトにアクセスすると管理画面・フロントエンドともに白画面になる
- 500MBを超えるDBのエクスポートが50〜60%で止まる
解決手順
ステップ1:移行前の状態確認とDB最適化
# DBサイズとテーブル状況を確認
wp eval "
global \$wpdb;
// テーブルサイズを確認
\$tables = \$wpdb->get_results('
SELECT table_name,
ROUND(data_length/1024/1024, 2) AS data_mb,
ROUND(index_length/1024/1024, 2) AS index_mb,
table_rows
FROM information_schema.tables
WHERE table_schema = DATABASE()
ORDER BY data_length DESC
LIMIT 15
');
echo 'DB Tables (by size):' . PHP_EOL;
foreach (\$tables as \$t) {
printf(' %-40s %6.2f MB (%d rows)' . PHP_EOL,
\$t->table_name, \$t->data_mb, \$t->table_rows);
}
// 総サイズ
\$total = \$wpdb->get_var('
SELECT ROUND(SUM(data_length + index_length) / 1024 / 1024, 2)
FROM information_schema.tables
WHERE table_schema = DATABASE()
');
echo 'Total DB size: ' . \$total . ' MB' . PHP_EOL;
"
# DB最適化(移行前に実行推奨)
wp db optimize
wp db repair
# WP Migrate DBのバージョン確認
wp eval "
if (class_exists('WPMDB_Base')) {
echo 'WP Migrate version: ' . WPMDB_BASE_VERSION . PHP_EOL;
}
"
ステップ2:WP-CLIを使ったURL置換(シリアライズ対応)
# WP-CLIのsearch-replaceコマンドでURL置換(シリアライズデータに対応)
wp search-replace 'https://staging.example.com' 'https://example.com' \
--all-tables \
--precise \
--skip-columns=guid \
--report-changed-only
# プレビューのみ(実際には変更しない)
wp search-replace 'https://staging.example.com' 'https://example.com' \
--all-tables \
--precise \
--dry-run
# 特定テーブルのみ置換
wp search-replace 'http://localhost:8080' 'https://example.com' \
wp_options wp_postmeta wp_usermeta \
--precise \
--report-changed-only
# 置換結果を確認
wp eval "
// siteurl と home が正しく設定されているか確認
echo 'siteurl: ' . get_option('siteurl') . PHP_EOL;
echo 'home: ' . get_option('home') . PHP_EOL;
echo 'upload_path: ' . get_option('upload_path') . PHP_EOL;
"
ステップ3:シリアライズデータを安全に修復する
// functions.php: シリアライズデータ修復ユーティリティ
// ① 壊れたシリアライズデータを検出・修復
function fix_serialized_option(string $option_name, string $old_url, string $new_url): bool {
$value = get_option($option_name);
if (!is_string($value)) return false;
// シリアライズされているか確認
if (!is_serialized($value)) {
// 通常の文字列置換
$new_value = str_replace($old_url, $new_url, $value);
return update_option($option_name, $new_value);
}
// アンシリアライズして置換
$unserialized = @unserialize($value);
if ($unserialized === false) {
// シリアライズが壊れている場合はバイト数修正を試みる
$fixed = preg_replace_callback(
'/s:(\d+):"(.*?)"/s',
function(array $matches): string {
$str = $matches[2];
return 's:' . strlen($str) . ':"' . $str . '"';
},
$value
);
update_option($option_name . '_broken_backup', $value);
return update_option($option_name, $fixed);
}
// 再帰的にURL置換
$replaced = replace_in_value($unserialized, $old_url, $new_url);
return update_option($option_name, $replaced);
}
// ② 再帰的な値置換
function replace_in_value(mixed $value, string $old, string $new): mixed {
if (is_string($value)) {
return str_replace($old, $new, $value);
}
if (is_array($value)) {
return array_map(fn($v) => replace_in_value($v, $old, $new), $value);
}
if (is_object($value)) {
foreach (get_object_vars($value) as $prop => $val) {
$value->$prop = replace_in_value($val, $old, $new);
}
}
return $value;
}
ステップ4:大容量DBの移行をタイムアウトなしで実行する
# WP-CLIで大容量DBをエクスポート(タイムアウトなし)
wp db export backup-$(date +%Y%m%d).sql --add-drop-table
# 圧縮してエクスポート
wp db export - | gzip > backup-$(date +%Y%m%d).sql.gz
# テーブル別に分割エクスポート(大容量DB対策)
for table in $(wp db tables --all-tables --format=csv | tr ',' '\n'); do
wp db export --tables=$table ${table}.sql
echo "Exported: $table"
done
# MySQLコマンドで直接インポート(phpMyAdminのタイムアウト回避)
mysql -u DB_USER -p DB_NAME < backup.sql
# gzip圧縮ファイルのインポート
gunzip < backup.sql.gz | mysql -u DB_USER -p DB_NAME
// functions.php: 移行後の確認・修復
// ① 移行後のURLを一括確認
function audit_site_urls(): array {
$issues = [];
$old_url = 'https://staging.example.com'; // 移行前のURL
// wp_options の主要オプションを確認
$options_to_check = ['siteurl', 'home', 'blogdescription', 'upload_path', 'upload_url_path'];
foreach ($options_to_check as $opt) {
$value = get_option($opt, '');
if (str_contains($value, $old_url)) {
$issues[] = "Option '{$opt}' still contains old URL: {$value}";
}
}
// アクティブなプラグインの設定を確認
$active_plugins = get_option('active_plugins', []);
foreach ($active_plugins as $plugin) {
$plugin_option = str_replace(['.php', '/'], ['', '_'], $plugin) . '_settings';
$value = maybe_serialize(get_option($plugin_option, ''));
if (str_contains($value, $old_url)) {
$issues[] = "Plugin option '{$plugin_option}' contains old URL";
}
}
return $issues;
}
ステップ5:移行後のチェックリスト
# 移行後の動作確認チェックリスト
wp eval "
echo '=== 移行後チェックリスト ===' . PHP_EOL;
// ① URL設定
echo '① URL設定' . PHP_EOL;
echo ' siteurl: ' . get_option('siteurl') . PHP_EOL;
echo ' home: ' . get_option('home') . PHP_EOL;
// ② パーマリンクリセット
\$result = flush_rewrite_rules(true);
echo '② パーマリンク: ' . (empty(\$result) ? 'OK(リセット済み)' : 'NG') . PHP_EOL;
// ③ アップロードディレクトリ
\$upload = wp_upload_dir();
echo '③ アップロードDir: ' . (\$upload['error'] ? 'ERROR: ' . \$upload['error'] : 'OK') . PHP_EOL;
// ④ DBテーブル整合性
global \$wpdb;
\$errors = \$wpdb->get_results('CHECK TABLE ' . \$wpdb->options . ', ' . \$wpdb->posts . ', ' . \$wpdb->postmeta);
\$ok = true;
foreach (\$errors as \$e) {
if (\$e->Msg_type === 'error') { \$ok = false; echo ' ERROR: ' . \$e->Msg_text . PHP_EOL; }
}
echo '④ DBテーブル: ' . (\$ok ? 'OK' : 'ERROR(要修復)') . PHP_EOL;
// ⑤ キャッシュクリア
wp_cache_flush();
echo '⑤ キャッシュ: クリア完了' . PHP_EOL;
"
注意事項
- WP Migrate DBでURL置換を行う際、シリアライズされたデータ(Elementorのページデータ・ACFのフィールド設定など)は単純な文字列置換では壊れます。WP Migrate DB ProまたはWP-CLIの
wp search-replace --preciseオプションを使用してください。--preciseオプションはシリアライズデータを一度展開してから置換します - 大容量DB(300MB以上)の移行はphpMyAdminではなく、WP-CLIやMySQLコマンドを直接使用することを強く推奨します。phpMyAdminはサーバーのPHP実行時間(
max_execution_time)の制限を受けるため、途中でタイムアウトします - 移行後に必ずパーマリンクの再保存(「設定 → パーマリンク → 変更を保存」)を行ってください。リライトルールがリセットされないと、固定ページや投稿URLが404になります
まとめ
WP Migrate DB修復は①information_schemaでDBサイズ・テーブルサイズを確認・wp db optimizeで最適化、②wp search-replace --all-tables --preciseでシリアライズデータに対応したURL置換、③is_serialized()→unserialize()→再帰置換→update_option()でシリアライズデータを安全に修復・バイト数ズレをregex修正、④wp db exportとmysqlコマンドで大容量DBをタイムアウトなしで移行・gzip圧縮で転送サイズ削減、⑤移行後のsiteurl/home確認・パーマリンクリセット・DBテーブルCHECK・キャッシュクリアで動作を検証する手順で解決します。