WordPressデータベースの復元の際、wp_commentmetaでエラーが出る件

Advertisement

wp-sql-import-error

WordPressのデータベースをライブ環境からバックアップして、MAMPを使ったローカル環境にインポートしようとしたらエラーが出てしまいました。ざっくり調べてみたので覚え書きとして記録しておきます。同じような問題で困っている方のお役に立てれば幸いです。

MySQLでエラーが発生

WordPressブログのライブ環境のphpMyAdminからダウンロードしたデータファイルをローカル環境のデータベースにインポートしようとすると、wp_commentmetaテーブルの作成部分で以下のエラーが出てしまいました。

#1071 - Specified key was too long; max key length is 1000 bytes

以下がSQL構文でエラーが出たところです。

DROP TABLE IF EXISTS `wp_commentmeta`;
CREATE TABLE IF NOT EXISTS `wp_commentmeta` (
  `meta_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `comment_id` bigint(20) unsigned NOT NULL DEFAULT '0',
  `meta_key` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `meta_value` longtext COLLATE utf8mb4_unicode_ci,
  PRIMARY KEY (`meta_id`),
  KEY `comment_id` (`comment_id`),
  KEY `disqus_dupecheck` (`meta_key`,`meta_value`(11)),
  KEY `meta_key` (`meta_key`(191))
) ENGINE=MyISAM  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci AUTO_INCREMENT=1122068;

問題は複合インデックスの合計バイト数?

ググってみたら、どうやら複合インデックス関連のエラーのようです。

MyISAM の場合、複合インデックスで全てのカラムの byte 数を合計した結果が 1000 bytes を超えるとダメで、(255 + 255 + 255) * 3 (utf8) で 1000 bytes 超えたから出たようだ。

sonots:blog より引用

さらに、utf8mb4の場合、複合インデックスの全てのカラムのバイト数 * 4になるとのことで、上のCREATE TABLEの構文では、KEYのどれかの合計が1000 byteを超えてしまっていることがわかりました。

disqus_dupecheckのバイト数が1,000を超える

問題が起こっているのはKEY `disqus_dupecheck`のところで、meta_keyとmeta_valueの合計バイト数が (255 + 11) * 4 = 1064で1000を超えてしまいます。64 ÷ 4 = 16なので255から16を引いてmeta_keyを239バイトにすれば、合計が1000を超えなくなります。

phpMyAdminでmeta_keyの値を確認してみると、「akismet_result」や「dsq_parent_post_id」といったもので、255バイトに及ぶものはないようです。meta_keyのバイト数を制限しても問題なさそうなので、以下の2つを試みました。結果、どちらでもデータベースのインポートは成功しました。

1. meta_key自体のバイト数を変える

前述のSQL構文の`meta_key` varchar(255)の部分を`meta_key` varchar(239)に変えてみた。

Before

  `meta_key` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,

After

  `meta_key` varchar(239) COLLATE utf8mb4_unicode_ci DEFAULT NULL,

2. 複合インデックスの方のmeta_keyのバイト数を指定する

KEY `disqus_dupecheck` (`meta_key`,`meta_value`(11))`meta_key`部分を`meta_key`(239)に変更してみた。

Before

  KEY `disqus_dupecheck` (`meta_key`,`meta_value`(11)),

After

  KEY `disqus_dupecheck` (`meta_key`(239),`meta_value`(11)),

上のどちらかを行うことで、SQLエラーが出ることなくデータをインポートでき、一応ローカル環境のWordPressは問題なく動いています。ただし、Akismetに関しては「APIキーの有効期限が切れています」というメッセージが表示されてしまって動作の確認ができていません。

disqus_dupecheckって何?

ところで、disqus_dupecheckはいったいなんなのかというと、どうやらDISQUSというコメントシステムのプラグインを入れた際にデータベースに追加されたもののようです。現在はそのプラグインを使っていませんが、アンインストールの際にデータが放置されたようです。

プラグインの変更履歴 の2.70のところに「Properly uninstall disqus_dupecheck index when uninstalling plugin.(プラグインをアンインストールする際にdisqus_dupecheckインデックスを適切にアンインストールする)」というのがあったので、たぶんこれが犯人でしょう。

たぶん、WordPressのアップデートの際に、meta_keyの文字コードがutf8mb4に変更されたことで問題が発生するようになった模様です。

バージョンのメモ

念のため、今回の問題がか起こったときのライブ環境とローカル環境のWordPressのバージョンやサーバやクライアントのバージョンを書き留めておきます。ちなみに、ローカル環境はMAMPを使っています。

ライブ環境 バージョン
WordPress 4.5.1
MySQL 5.5.38-log
MySQLクライアント 5.5.28
phpMyAdmin 3.3.10.5
ローカル環境 バージョン
WordPress 4.5.1
MySQL 5.5.38 – Source distribution
MySQLクライアント libmysql – 5.5.28
phpMyAdmin 4.2.5

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です