plusN コーディングとか育児とかの個人ブログ

WordPressのCustom Permalinksが壊れた時の復旧方法|DBから3000記事を一括修正した手順

PR

WordPressでプラグイン「Custom Permalinks」を使用しているサイトで、パーマリンク指定が壊れるトラブルが発生しました。DBを一括操作して復旧したため、作業ログとして残しておこうと思います。

※DBを操作する場合は、作業前に必ずDBバックアップを取得してから実行してください。

発生した問題

WordPressサイトのデータ移行後、記事URLが崩れてしまうトラブルが発生しました。
本来のURLは以下のような構造です。

example.com/column241201
example.com/book241202

しかし一部の記事で以下のようなURLに変わっていました。

example.com/on200123-123

調査したところ、Custom Permalinksプラグインが保存している custom_permalinkpostmetaが壊れていることが原因でした。

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を用いて以下の手順で復旧作業を行いました。

  1. postmetaからcustom_permalinkを抽出
  2. 対象期間の記事をCSV出力
  3. 正しいURLをCSVで作成
  4. 一時テーブルにインポート
  5. postmetaをJOIN UPDATE
  6. ランダムにURL確認

今回の作業を通して、

  • WordPress移行時は postmeta も必ず確認する
  • Custom Permalinks はDBに依存している
  • URLトラブルは slug / guid / meta を比較すると原因が見えやすい

という点を改めて実感しました。
Custom Permalinksで立て続けにトラブルに見舞われたため、プラグインを使ったパーマリンク変更は便利ですが、運用や移行時にはリスクになる可能性もあると改めて感じました。

PR