WordPressのサーバー移行作業で、phpMyAdminからエクスポートしたSQLファイルを、ローカル環境(Local by Flywheel)にインポートしようとしたら、エラーが出て止まってしまいました。
同じ現象でハマっている方の参考になればと思い、原因と解決策をまとめておきます。
発生したエラー
ERROR 1062 (23000): Duplicate entry '0' for key 'wp_options.PRIMARY'
wp db importでSQLファイルを読み込んだときに、wp_optionsテーブルのPRIMARY KEYで重複エラーが発生しました。
なんだこれ?と、最初はかなり焦りました。
原因:phpMyAdminのエクスポート形式だった
調べてわかったのが、phpMyAdminの「簡易」モードでエクスポートすると、テーブルの定義が3段階に分かれて出力されるということです。
- CREATE TABLE — テーブル作成(AUTO_INCREMENTなし)
- ALTER TABLE — PRIMARY KEYやINDEXの追加
- MODIFY — AUTO_INCREMENTの設定
問題はこの順番なんですよね。CREATE TABLEの時点ではoption_idにAUTO_INCREMENTが付いていません。なので、INSERT文でoption_id = 0のレコードが複数あると、AUTO_INCREMENTによる自動採番が行われず、PRIMARY KEYの重複エラーになってしまいます。
通常のmysqldumpやwp db exportだと、CREATE TABLE文の中にPRIMARY KEYもAUTO_INCREMENTもまとめて定義されるので、この問題は起きません。つまり、phpMyAdminの「簡易」エクスポート特有のトラブルでした。
解決策:phpMyAdminのエクスポート設定を変更する
phpMyAdminでエクスポートするときに、**「簡易」ではなく「詳細」**を選びます。そして、以下の2つのオプションにチェックを入れます。
- 「IF NOT EXISTS」を追加 → チェック
- 「AUTO_INCREMENT値を追加する」 → チェック
この設定でエクスポートし直すと、CREATE TABLE文にAUTO_INCREMENTが含まれた状態でSQLファイルが生成されるので、インポート時のエラーが解消されます。
ここに気づくまでが長かった、、、
別の解決策:wp-cliやmysqldumpを使う
移行元のサーバーにSSHアクセスができるなら、phpMyAdminを使わずにコマンドラインからエクスポートするのが確実です。僕としては、こちらの方法をおすすめしたいです。
# wp-cliが使える場合
wp db export backup.sql
# mysqldumpを使う場合
mysqldump -u ユーザー名 -p データベース名 > backup.sql
これらのコマンドで出力されるSQLファイルは、CREATE TABLE文にPRIMARY KEYとAUTO_INCREMENTが最初から含まれているので、トラブルが起きにくいです。
SSHが使えるサーバーなら、こっちの方が安心感があります。
SQLファイルを手動修正する方法(参考)
すでにエクスポート済みのSQLファイルしか手元にない、、、という場合は、sedコマンドで修正することもできます。
# CREATE TABLE内のoption_idにAUTO_INCREMENTとPRIMARY KEYを追加
sed -i '' 's/`option_id` bigint(20) UNSIGNED NOT NULL,/`option_id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,/' backup.sql
# ALTER TABLEのPRIMARY KEY追加を削除(重複を避ける)
sed -i '' 's/ADD PRIMARY KEY (`option_id`),//' backup.sql
ただし、他のテーブルでも同様の問題が起きる可能性があるので、できればエクスポートし直す方が安全です。あくまで、どうしてもの時の手段として覚えておくと良いです。
まとめ
phpMyAdminの「簡易」エクスポートは手軽なんですけど、テーブル定義が分離されることで、インポート時にエラーが発生することがあります。
WordPress移行のときは「詳細」モードで適切なオプションを設定するか、可能であればwp db exportやmysqldumpを使うのがおすすめです。
僕自身、このトラブルで結構な時間を費やしたので、同じところでハマっている方の助けになれば嬉しいです。






