WordPressでローカル環境から本番環境へMySQLのデータをアップロードしようとしたところ、エラーが出ました。
Unknown collation: 'utf8mb4_unicode_ci'
記事執筆時のWordPress 4.3では推奨環境として
- PHP 5.6かそれ以上
- MySQL 5.5かそれ以上
を最低限必要な条件と指定しているが、レガシー環境しか提供できないホスティング会社を使用している人の為に以下の古いバージョンでも稼働するように設計されている。
- PHP 5.2.4+
- MySQL 5.0+
しかし、これらの古いバージョンは既にサポートが終了しており、これらの古い環境しか提供できないホスティング会社は基本的に裂けるべきである。
参考資料 Requirements
MySQL 5.5.3から使用できるutf8mb4とは?
簡単に言うと、utf8mb4はutf8の拡張版であり、今まで使われていた文字セットに追加の文字セットが使えるようになったことが最大の点である。つまり絵文字が使えるようになったのである。
参考資料 Emoji Unicode Tables
しかし、この追加の恩恵を受けるためには、MySQLのデータベースを5.5.3かそれ以上にアップデートしなければならない。また、既存のデータベースをMySQL 5.5.3にアップデートし、データベース内にストアするルール(collation)を変えなければならない。
このルールを変えるためにはデータベースの中でストアする箇所を今までのutf8からutf8mb4という形式に変更しなければならない。これにより知らずにutf8mb4を使用しているデータベースを前のutf8のデータベースに中身を入れようとすると、
Unknown collation: 'utf8mb4_unicode_ci'
っと、いうように「先輩(MySQL 5.5.3)!そのルールマジわからねーっす!」って後輩(MySQL5.5.3以下)に言われることになる。
エラーが起きる原因となる問題だが、普通のutf8の文字セットはBMP形式を使用しており、一文字に対して最大で3文字まで使える仕様になっている。変わって新しいutf8mb4はutf8のBMP形式も使えるが、追加の絵文字のセットを使えるために一文字当たり最大で4文字使えるようにしている。このため、utf8形式しか使えないMySQL 5.5.3以下のデータベースに無理やりutf8mb4形式のデータを入れた場合且つ絵文字等を使用している場合、MySQLを使用しているWordPressが動作しなくなったり壮大にバグったりする事になる。
参考資料 10.1.10.6 The utf8mb4 Character Set (4-Byte UTF-8 Unicode
Encoding)
WordPress 4.2から自動的に行われるutf8mb4へのアップグレードについて
WordPress 4.2はセキュリティー上の仕様から及び新しい文字セットを扱えるためにユーザーの許可なく、自動的に以下の条件を満たす場合MySQLのデータベースに格納されているテーブルをutf8mb4にするとのこと。
- 現在utf8の文字セットを使っている
- 使用しているMySQLサーバーのバージョンが5.5.3もしくはそれ以上の場合
- 使用しているMySQLのクライアントライブラリーが5.5.3もしくはそれ以上の場合 又は mysqlndを使用している場合は5.0.9かそれ以上の場合
この処理を知らないうちに勝手にやられてしまうとローカル環境(MySQL 5.5.3かそれ以上)で開発及びテストを行ってから本番環境(MySQL 5.5.3以下)へアップロード等するときにえらい大変な目に合ってしまう。
もし、WordPress 4.1など4.2以前のバージョンを使っており、WordPress 4.2にアップグレードしたときに上記条件を満たしていても、勝手にMySQLのルールをutf8からutf8mb4に変更させたくない場合は、wp-config.phpの中に「DO_NOT_UPGRADE_GLOBAL_TABLES」を記述すると良い。
define('DO_NOT_UPGRADE_GLOBAL_TABLES', true);
参考資料 Make WordPress Core #32154
参考資料 wp-config.php の編集
参考資料 The utf8mb4 Upgrade
utf8mb4のMySQLデータをutf8を使用しているMySQLサーバーへアップロードしたい場合(utf8mb4→utf8)
以下当たり前ですが自己責任です!
方法1:おそらく一番簡単
- utf8mb4が使われているローカル環境のphpMyAdminへログイン。
- 使用しているデータベース名をクリック
- エクスポートをクリック
- 「エクスポート方法」を「詳細 – 可能なオプションをすべて表示」にチェックを入れる
- 「フォーマット特有のオプション」にて「他のデータベースシステムまたは古い MySQL サーバとの互換性:NONE」となっているところを「MYSQL40」に変更。
- その他いじる事なく、一番したまで行き、「実行」をクリック。
これで前のバージョンと互換性のあるMySQLデータがダウンロードできます。
方法2:WPblogとローカルにXAMPPがあったりする場合
コメントでご指摘があったので、WPblogではphpMyAdminが提供されておらず、方法1のphpMyAdminを使用しての古いMySQLサーバーとの互換性を行うことができない。
- ローカル環境にXAMPPサーバーを建てる。
- phpMyAdminが使える事を確認しておく。
- WPblogのデータベースを「データベースのバックアップ(エクスポート・インポート)」→「エクスポート(バックアップ)」→「圧縮なし(SQLファイル)」→「エクスポート実行」でローカルへダウンロード。
- ローカルのMySQLへphpMyAdminにて先ほどダウンロードしたデータベースをインポート。
- その後、phpMyAdminで上記方法1にてMYSQL40へエクスポート。
この方法は別にローカルのXAMPPのデータベースでなくてもどこか別のphpMyAdminが使えるサーバーであれば問題ないが、ローカルで変換作業などを行った方が個人的にはセキュリティー上良いと思う。
WPblogにて「Migrate DB」を使っての方法はこのサイトにあります。
方法3:linuxユーザー専用
以下のスクリプトを実行する。
DB="your_database_name" USER="your_db_user" PASS="your_db_pass" ( echo 'ALTER DATABASE `'"$DB"'` CHARACTER SET utf8 COLLATE utf8_general_ci;' mysql -p$PASS -u $USER "$DB" -e "SHOW TABLES" --batch --skip-column-names \ | xargs -I{} echo 'ALTER TABLE `'{}'` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;' ) \ | mysql -p$PASS -u $USER "$DB"
参考資料 Script to convert MySQL collation from utf8mb4 to utf8
方法4:phpスクリプトを直接実行
以下のスクリプトを実行する。
<?php $dbname = 'your-database-name'; mysql_connect('your-database-hostname', 'your-database-username', 'your-database-password'); mysql_query("ALTER DATABASE `$dbname` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci"); $result = mysql_query("SHOW TABLES FROM `$dbname`"); while($row = mysql_fetch_row($result)) { $query = "ALTER TABLE {$dbname}.`{$row[0]}` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci"; mysql_query($query); $query = "ALTER TABLE {$dbname}.`{$row[0]}` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci"; mysql_query($query); } echo 'All the tables have been converted successfully'; ?>
- 上記PHPスクリプトのデータベース名、データベースユーザー名、データベースパスワードの部分を変更したいサーバーのに変更し “dbconversion.php”として保存。
- 上記ファイルをサーバーへ置く。
- 上記スクリプトを “anatano-domain.com/dbconversion.php”から実行。
- これでutf8mb4のデータベースをutf8に変換する事ができます。
参考資料 How to convert MySQL collation from utf8mb4 to utf8
方法5:これが出来ればね。
そもそも開発を行う際は本番環境と同じ環境を整備してから行う。はい、言うのは簡単です。
つまりは、本番環境のMySQLのバージョンが5.0.91だったら開発環境もMySQL5.0.91を使う。(※MySQL5.1以下は現在ではサポートが切れていますので次のバージョンのMySQL5.5以上のバージョンのレンタルサーバー会社を選ぶべきでしょう。できればMySQL5.6か5.7以上。)
そうすればもんだいない。
Windowsを使っている場合は、xamppで古いバージョンをダウンロードして使うとかね。
変更履歴:
- 2017/04/30 – 細かな修正
- 2017/07/25 – 追加のスクリプト
コメント