サーバー

MySQL 古いMTからMTOS(5.14)へのデータ移植について

古いMovable Typeのデータを新しいMovable Type(以下MT)へ移す作業で、サイトごと移すためにデータの引っ越し作業を実施しました。古い方にはデータのエクスポート機能がないようで、MySQLデータベースからデータを取り出し新しいサイトのデータベースに移す、という方法です。

古いサイトのMySQLはバージョンが3.23、新しい方は5.1で、文字コードがEUC-JPのデータをUTF-8に変換して取り込まないとなりません。この作業に時間が少し掛ったのでその備忘録です。

古いバージョンのデータを新しいMTへ持ち込む方法として助かったのは、新しいMTで利用するデータベース(mt-config.cgiで指定)のテーブルが古いバージョンだと、自動でテーブルをアップグレードしてくれる事でした。なので、テーブルの構造やデータをいじる必要がなかったのです。

手順

1.エクスポート

まずはデータをSQLテキストでエキスポートします。この方法は簡単で、phpMyAdminが利用できるなら「エクスポート」を利用します。エクスポートする際は、面倒臭くても各テーブルを別々にエクスポートしましょう。自分は一括でエクスポートして痛い目を見ました。

出力時は「DROP TABLE」を追加し、「ファイルで保存」出力する名前をテーブル名で指定してエンコーディングせずに「non」指定でダウンロードします。

今回は「mysqldump」が利用できなかったのでphpMyAdminを使いました。

2.EUC-JPをUTF-8へ変換

これはテキストエディタのTeraPadを利用しました。TeraPadの注意点は、8000文字以降は無視されてしまうことです。そのため別のMeryも利用しました。いずれもWindowsのフリーソフトです。

3.インポート

SSH接続でしたので、FTPでアップロードしたファイルをmysqlコマンドを利用してインポートしました。

mysqlコマンドを使う場合、コマンドでログオンしてからインポートする方法とログオンせずにmysqlコマンドにSQLデータをリダイレクトしてインポートする方法があります。

コマンドでログオンする場合

$>mysql -h localhost -u username -p databasename
Password:
>source SQLデータファイル名;

コマンドにリダイレクトする場合

$>mysql -h localhost -u username -p databasename < SQLデータファイル名

以上で、mt.cgiをブラウザから呼び出しアップグレードして、新しいMTに移す事ができました。

 躓いたところ

2ヶ所の落とし穴にはまりました。

最初の落とし穴はインポートしたデータが文字化けしてしまうことです。mysqlコマンドでデータを見る限りは正しく表示されるのに、MTでページを表示するととんでもない事に。

原因はmysqlコマンドを実行した際の文字コード設定変数にありました。

こんな状態で取り込んでいたのが原因のようです。そこで「set names utf8;」を実行して矯正します。

これで文字化けは解消しました。

次の落とし穴は肥大したテーブル「mt-comment」と「mt-log」です。山のようにスパムが送り込まれており、取り込まれたデータは表示できないようなデータも含まれているためです。

実際、SQLデータにデータを落とすとあちこちでデータフィールドの境が壊れ、取り込もうとしてもエラーになってしまうのです。

仕方ないのでphpMyAdminを利用してデータを抽出し、さらにテキストエディタで修正して取り込むようにしました。取り込み時にエラーが発生した場合はそれを修正して再投入です。しかしながら「mt-log」の方はきっぱりとあきらめました。ログなのでテーブル構造だけとしました。

抽出する際の方法は、繰返し実施している人ならきっとノウハウがあると思います。自分は初めてでしたので、以下の2つの方法を考えてみました。

1つはcomment_author項目がアルファベットのみのデータをはじく方法です。where句に以下の指定をします。

WHERE comment_author not REGEXP '[0-9a-zA-Z[:blank:] @\.-]'

この方法だと、文字化けしたデータをはじく事が上手くできませんでした。もう1つはcomment_junk_log内の「Filter (0)」に目を付けた方法です。

WHERE comment_junk_log not like '%Filter (0)%'
AND comment_junk_log not like '%Filter (-1)%'

この方法は結構効きました。comment_idでソートしたらスパムデータが後の方にかたまったので、テキストエディタで削除して取り込みました。

もっと複雑なSQLを組めればさらに精度が上がるでしょうが、今回はここまでで止めました。