WordPressのデータベースをmysqlを使って移行する

WordPressでWebサイトを運用していると、画像がアップロードできない、”http://…”でアクセスできないなどの不具合に遭遇することがあります。

不具合の原因特定と修復にはプラグインのインストールやスクリプトの改変などの試行錯誤を繰り返すことになりますが、この過程でWordPress自体が不安定になることがあります。この場合、WordPress自体を新規インストールし直し、元々のサイトのデータをインポートしてWordpress自体をリセットする方法が最も確実です。また、復旧手順が確立していれば何度もトライ&エラーができるので、修復した環境に意図しない設定が入り込むこともなくなります。

WordPressをリセットするにはUpdraftやWordPress All-in-One Migrationなどを利用し、データベース、テーマ、プラグインをバックアップし、WordPressを新規セットアップしてインポートする方法が最も簡単です。

ところが、プラグインを利用した場合はバックアップしたデータベースをインポートする際に処理が一向に進まず、丸一日たっても処理が終了しないことが多々あります。このような場合はデータベースの移行時にプラグインを利用しない形で対応する必要があります。

ここでは、Wordpressのリセット作業時にデータベースの移行をmysqlを利用して確実に行う手順を記載します。

1.UpdraftでWordpressのコンテンツ全体をバックアップする

はじめにWordpressのコンテンツをUpdraftを使ってバックアップします。

バックアップすると以下の5ファイルがWordpress内で生成されるので、これらをPCにダウンロードしておきます。

2.WordpressのデータベースをExportする

WordPressが動作しているPCのターミナル上で下記コマンドを実行し、データベースをExportします。

$ mysqldump -u <user id> -p<password> wordpress > wordpress_backup.sql
# -pとパスワードの間はスペースは入れないこと

Synology NASのDockerでWordpressを動かしている場合は、以下のコマンドでExportします。

$ sudo docker exec -it <dockerコンテナ名>_db sh -c 'mysqldump -u root -p"$MYSQL_ROOT_PASSWORD" wordpress' > wordpress_backup.sql

Dockerコンテナ名はContainer Managerに表示されている下記文字列になります。

3.Wordpressを新規セットアップする

WordPress環境を新規で再セットアップします。

Synology NASの場合はDockder ManagerでWordpressのDockerコンテナを停止した後、Dockerコンテナディレクトリをコピーしてバックアップしておきます。バックアップが完了したらwp/redis/dbの中身を削除してWordpressのDockerコンテナを再構築すれば新規セットアップできます。

WordPress起動後は下記設定をwp/wp-config.phpに書き込むか、バックアップコピーにあるwp/wp-config.phpを新規インストール先へコピーしておき、あらかじめredisの有効化とプラグインインストール時のFTPアカウント要求を抑止しておきます。

define( 'WP_REDIS_HOST', 'redis' );
define('FS_METHOD', 'direct');

新規インストールが完了した後はWordpressにログインして初期セットアップを行い、Wordpressのバージョンを最新のものにアップデートしておきます。合わせてUpdraftプラグインもインストールしておきます。

4.データベース以外のファイルをインポートする

Updraftを使って、バックアップからデータベース以外を復元します。

5.データベースをインポートする

下記コマンドでExportしたデータベースをインポートします。100MB程度のデータベースだと5分程度かかります。進行状況は表示されませんので反応がなくてもじっと待ちましょう。

$ cat memo_backup.sql | mysql -u <user id> -p<password> wordpress

Synology NASのDockerでWordpressを動かしている場合は、以下のコマンドでインポートします。

$ cat memo_backup.sql | sudo docker exec -i <Wordpressコンテナ名>_db mysql -u root -proot wordpress

6.【別URLで新規Wordpressを設定した場合】データベース内のURLを書き換える

WordPressのデータベースのイメージファイルへのパスはフルパスのURLで記述されています。このため、別URLで動作しているWordpressにデータベースインポートしただけでは、エクスポート元のURLが消えると画像が表示されなくなります。この問題は、データベース内のURLを新規URLに置き換えることで解決できます。

データベースのURLの置き換えは以下のコマンドを実行します。

# WP-CLIをコンテナ内にダウンロードする
$ sudo docker exec -it wordpress_recipe_sabalog_wp curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
Password: 
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 6975k  100 6975k    0     0  15.7M      0 --:--:-- --:--:-- --:--:-- 15.7M

# ダウンロードしたWP-CLIを使って置換を実行する
$ sudo docker exec -u www-data -it <Wordpressコンテナ名>_wp php wp-cli.phar search-replace '<検索文字列>' '<置換文字列>'
+------------------+-----------------------+--------------+------+
| Table            | Column                | Replacements | Type |
+------------------+-----------------------+--------------+------+
| wp_commentmeta   | meta_key              | 0            | SQL  |
| wp_commentmeta   | meta_value            | 46           | PHP  |
| wp_comments      | comment_author        | 0            | SQL  |
.....

下記は変換時の出力サンプルになります。変換には100M程度のデータベースで15分程度かかりましたので、置換実行時は終了まで気長に待ちましょう。

$ sudo docker exec -u www-data -it wordpress_simplelife_sabalog_wp php wp-cli.phar search-replace search-replace 'https://simplelife.sabalog.com' 'http://temp.sabalog.com' --skip-columns=guid --allow-root
+------------------+-----------------------+--------------+------+
| Table            | Column                | Replacements | Type |
+------------------+-----------------------+--------------+------+
| wp_commentmeta   | meta_key              | 0            | SQL  |
| wp_commentmeta   | meta_value            | 46           | PHP  |
| wp_comments      | comment_author        | 0            | SQL  |
| wp_comments      | comment_author_email  | 0            | SQL  |
...
| wp_options       | autoload              | 0            | SQL  |
| wp_postmeta      | meta_key              | 0            | SQL  |
| wp_postmeta      | meta_value            | 19           | PHP  |
| wp_posts         | post_content          | 2926         | SQL  |
| wp_posts         | post_title            | 0            | SQL  |
...
| wp_posts         | to_ping               | 0            | SQL  |
| wp_posts         | pinged                | 1            | SQL  |
| wp_posts         | post_content_filtered | 0            | PHP  |
...
Code language: JavaScript (javascript)

参考になれば幸いです。