とあるXOOPSサイトのサーバ引っ越しを機に、EUC-JPからUTF-8に文字コードを変更することにした。
近い将来 XOOPS Cube もデフォルトの文字コードがUTF-8に変更されるはずだし、現状でも環境は整っているので、今のうちに準備しておこうというわけである。
EUC-JPなXOOPSからUTF-8なXOOPSへの引っ越し。
というだけならば、さほど面倒なことはなく、巷に情報も溢れている。
特に同じサーバ内で文字コードを変更するだけなら、さしたる問題がないケースが多い。
しかしながら、今回は仕様の異なるサーバへの引っ越しのうえに、ひと筋縄でいかない非常にめんどくさい事情もろもろがあったので、ちょっと記しておきたい。
まずはデータベースのサイズ。
これがでかいのだ。
非圧縮で約330MBあり、tgz圧縮で約40MBある。
旧サーバは割り当てメモリが少なくまた非力なこともあって、一括バックアップをしようとしても、XOOPSのバックアップモジュールはもちろん、 phpMyAdminでもエラーが出る。
なので、シェルからコマンドラインで行うか、スクリプトで実行するしかない。
バックアップするだけならまだいいが、問題はリストア。
一括バックアップではファイルサイズが大きすぎてphpMyAdminでは書き戻しできないので、Bigdumpなどのツールを使うか、コマンドラインから行う必要がある。
それだけならちょっとの手間であるが、EUC→UTFに文字変換したした場合、そのなかに機種依存文字なんかがあると、リストアの途中でエラー終了してしまうのである。
(一般に掲示板なども公開しているサイトなので、ユーザによる書き込みには機種依存文字がけっこう多いのだ)
そのため、単に文字コードを変換するだけでではなく、SQLファイルをテキストエディタで編集する必要があるのだが、AMD最強マシンをもってしても 300MBものファイルを編集するのは重たすぎてめちゃくちゃたいへん。
以上のような理由でスカッと一括バックアップ&リストアは諦め、モジュール単位でテーブルをまとめてバックアップすることにする。
このほうがエラーが出た場合など原因となる箇所を突き止めやすいし、1箇所ダメだから全体がダメという自体にも陥らない。
人間横着しちゃいけないということか。
そもそも上述したように、旧サーバはマシン自体が非常に非力なうえに、チューニングが悪い。
バックアップやレストアしている間はWebページの表示ができなかったりする。
データベースだけでなくファイルのバックアップでも同様である。
なにかにつけエラーが出たりタイムアウトしたりで作業が中断する。
一括ではなく、ちまちまが似合っているのだ。
さて、これで問題が解決したかという序の口である。
最大の問題は文字コードである。
一般的な「EUC-JPなXOOPSからUTF-8なXOOPSへの引っ越しガイド」では、データベースの文字コードを変換し、DEFAULT CHARSET の設定をEUC-JPからUTF-8にすればよいというようなことが書いてある。
しかしそれは「お行儀のよい」サーバの話である。
もともと旧サーバは契約時にMySQL4系/PHP4系だったのが、途中でMySQL5系/PHP5系に移行しており、それに伴い MySQLの文字コードもUTFに変更されている。
しかし、UTFで統一されていればまだしも、こんな感じになっている。
mysql> show variables like “char%”;
+————————–+—————————-+
| Variable_name | Value |
+————————–+—————————-+
| character_set_client | binary |
| character_set_connection | binary |
| character_set_database | binary |
| character_set_filesystem | binary |
| character_set_results | binary |
| character_set_server | binary |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+————————–+—————————-+
対して新サーバはこんな感じ。
+————————–+—————————-+
| Variable_name | Value |
+————————–+—————————-+
| character_set_client | binary |
| character_set_connection | binary |
| character_set_database | binary |
| character_set_filesystem | binary |
| character_set_results | binary |
| character_set_server | binary |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+————————–+—————————-+
これが両方とも自サーバであればなんでもなるわけだが、両方ともレンタル・サーバであるから、MySQLの仕様を勝手に変更することはできない。
さらにややこしいことに、旧サーバの旧環境にインストールしたXOOPSのデータベースは、EUC-JPとlatin1が混在しているのである。
ひどいケースだと、同一テーブルでもフィールドによって文字コードが違っていたりする。
いろんなサイトのいろんな情報をもとに、コマンドラインからいろんな指定をして出力してみたり、さまざまな方法を試してみたが、どれもうまくいかない。
問題はバイナリの部分で、SQLのダンプファイルの文字コードを変換しても、バイナリで記録されている部分は、サイト表示で文字化けしてしまうのである。
試行錯誤の結果、シロートも眉をひそめるドシロートな方法(© hirasawa)で乗り切った。
01) phpMyAdminからモジュール単位でSQL形式でエクスポート
02) エクスポートされた文字列をテキストエディタにC&Pし、UTF-8で保存(*1)
03) 機種依存文字をエディタのマクロで置換(*2)
04) DEFAULT CHARSET でEUCやlatin1になっている部分をUTF8に置換
DEFAULT CHARSET=utf8
05) 新サーバのphpMyAdminでインポート
06) Web表示で文字化けする部分(バイナリ部分)はテーブル単位で、CSVデータ形式でエクスポート
07) エクスポートされた文字列をテキストエディタにC&Pし、UTF-8で保存(*2)
08) 新サーバのphpMyAdminで対応するテーブルをいったん空にする(*3)
09) 新サーバのphpMyAdminで対応するテーブル選択してからインポート
インポートするファイルの形式→LOAD DATA する CSV→テーブルデータを差し替えるファイル(チェック)
*1 ファイルに出力してから文字コードを変換するよりも、手っ取り早く、文字化けする可能性が低い
*2 「〜(波ダッシュ」や「−(全角マイナス)」は機種依存文字ではないが、文字コード変換時に全角チルダや全角ハイフンになったり文字化けしたりするのでこれも置換する。
いわゆる全角チルダ問題に関しては、まったくMSを呪い殺したくなります。
www.kab-studio.biz/Programing/JavaA2Z/Word/00000716.html
*3 やらなくてもいいが念のため。
以上がシロートも眉をひそめるドシロートな方法(© hirasawa)の実体である。
次回、ファイルの変更、設定その他について書く、かも。