WordPressのCustom Permalinksが壊れた時の復旧方法|DBから3000記事を一括修正した手順
WordPressでプラグイン「Custom Permalinks」を使用しているサイトで、パーマリンク指定が壊れるトラブルが発生しました。DBを一括操作して復旧したため、作業ログとして残しておこうと思います。
※DBを操作する場合は、作業前に必ずDBバックアップを取得してから実行してください。
発生した問題
WordPressサイトのデータ移行後、記事URLが崩れてしまうトラブルが発生しました。
本来のURLは以下のような構造です。
example.com/column241201 example.com/book241202
しかし一部の記事で以下のようなURLに変わっていました。
example.com/on200123-123
調査したところ、Custom Permalinksプラグインが保存している
custom_permalink のpostmetaが壊れていることが原因でした。
DBから該当記事を特定する
Custom PermalinksはURLをpostmetaのmeta_keycustom_permalinkに保存しています。
そのため、まず対象期間の記事とmeta値をDBから取得しました。
以下は、2019/01/01〜2019/12/31の記事でcustom_permalinkを持つ投稿(ID,投稿タイトル,custom_permalink)を取得・出力する構文です。
SELECT p.ID,
p.post_title,
pm.meta_value AS custom_permalink
FROM wp_posts p
LEFT JOIN wp_postmeta pm
ON p.ID = pm.post_id
AND pm.meta_key = 'custom_permalink'
WHERE p.post_type = 'post'
AND p.post_date
BETWEEN '2019-01-01 00:00:00' AND '2019-12-31 23:59:59'
ORDER BY p.ID;
年単位で、本番データとテスト環境のデータをそれぞれCSVで出力・差分抽出を行いました。
テスト環境のデータはあっていたため、テスト環境のデータを正として新たにCSVを作成することにしました。
CSVをインポート・特定の値をアップデートする
作成したCSVをDBにインポートし、上書きするため、以下の手順で作業を行いました。
一時テーブルを作成
今回の修正対象は約3000件ありました。
直接UPDATEすると誤更新のリスクが高いため、一時テーブルを作成して作業しました。
テーブルの中身は、投稿IDと差し替える予定のcustom_permalink(meta_value)です。
CREATE TEMPORARY TABLE test_restore ( post_id BIGINT, custom_permalink VARCHAR(255) );
CSVインポート
作成したCSVをtest_restoreにインポートします。
念の為、アップしたデータに相違ないか確認します。
差し替えたいpostmetaをupdate
test_restoreのデータを本番のテーブルに反映します。
UPDATE wp_postmeta pm JOIN test_restore t ON pm.post_id = t.post_id AND pm.meta_key = 'custom_permalink' SET pm.meta_value = t.custom_permalink;
反映後は、内容が間違っていないか実際のページも確認しておくと安全です。
また、DB上で重複データがないか念の為確認しておくと良いかもしれません。
以下の構文は、重複を確認する構文です。
SELECT meta_value, COUNT(*) FROM wp_postmeta WHERE meta_key='custom_permalink' GROUP BY meta_value HAVING COUNT(*) > 1;
また、ランダムで出力・実際のページ確認も行なっておくとより安全だと思います。
SELECT p.ID, pm.meta_value FROM wp_posts p JOIN wp_postmeta pm ON p.ID = pm.post_id WHERE pm.meta_key='custom_permalink' ORDER BY RAND() LIMIT 20;
記事数が多かったため、各月から無作為に1〜2件ずつチェックし、リンクが以下の状態になっていないか確認しました。
- 404にならない
- 301ループしない
- 記事表示される
手間はかかりますがやっておくと、自分自身も安心できます。
作業環境
対応したサーバー(移行サイト、テスト環境)は以下の環境でした。
- WordPress バージョン:6.9.1
- PHP:8.3
- MySQL:8.0
- 対象プラグイン:Custom Permalinks
今回の作業手順まとめ
今回はデータ移行後の確認で404が発生したため、テスト環境(移行サイトと同環境)のDBを用いて以下の手順で復旧作業を行いました。
- postmetaからcustom_permalinkを抽出
- 対象期間の記事をCSV出力
- 正しいURLをCSVで作成
- 一時テーブルにインポート
- postmetaをJOIN UPDATE
- ランダムにURL確認
今回の作業を通して、
- WordPress移行時は postmeta も必ず確認する
- Custom Permalinks はDBに依存している
- URLトラブルは slug / guid / meta を比較すると原因が見えやすい
という点を改めて実感しました。
Custom Permalinksで立て続けにトラブルに見舞われたため、プラグインを使ったパーマリンク変更は便利ですが、運用や移行時にはリスクになる可能性もあると改めて感じました。