MovableTypeなblogを別サーバーに移行させる

投稿日:

自分用の備忘録ということで調査履歴を書き残しておきます。

自宅サーバーで稼動しているMovableTypeを他のサーバーへ移動させるんですが、基本的な流れは以下の通り。

(1) staticなデータ(画像ファイルとかPDFファイルとか)をtar.bz2で固めて新サーバーに転送、DocumentRoot以下に展開しておく
(2) MySQLに格納しているデータをmysqldumpで抜き、新サーバーに転送。
(3) 新サーバーのMySQLにデータをロードして、movableTypeで再構築をかける。

基本的にはこれでほぼ完了するはずけど、こまごまとした問題が出て来るのに違いないのでその辺は都度修正していくような感じ。


とりあえずMySQLにあるmovabletype用のテーブルのdumpを取ってみる。
mysqldumpの使い方はMySQLのマニュアルに詳しく書いてありますが、基本的には

mysqldump -u USERNAME -p DATABASENAME --no-create-db > ./dump.sql

でOK。特に難しいことは何も無くmysqlに接続する時のコマンドを「mysqldump」に置き換えてファイルにリダイレクトさせるだけ。
今回は新サーバーと旧サーバーでDB名が変わってしまうため(本当はDB名を揃えたかったがホスティングプランの都合でどうにもならず・・・)--no-create-dbオプションを付けていますが、無くても実行は可能です。

出力されたSQLを目でチェックして問題なさそうかどうかをチェックすると、どうやらデータ中に大量に旧FQDN(somethingnew.ddo.jp)が含まれている模様。自分が書いたコメントのURLとか、static filesへのリンクがhttp://から始まる絶対パスになっていたり、とか。somethingnew.ddo.jpへのアクセスをちゃんと新サーバーにリダイレクトしてやれば問題はなさそうだけど、どうせなら新サーバーで全部完結するように修正してしまいたい。

そこで全DBのデータをmysqlダンプで取得するのを止め、テーブル単位でバックアップすることにし、SQL上のデータを全部置換することで対応してしまう。

テーブル単位でdumpを取るには先ほどのmysqldumpコマンドの最後にテーブル名をつければいい。

mysqldump -u USERNAME --password=PASSWORD DATABASENAME --no-create-db TABLENAME > ./TABLENAME.sql

これを全テーブルを対象に一個ずつやるのは非常に面倒なので、まずMovableTypeで使っているテーブルの一覧をテキストファイルに書き出す。

適当な場所でtables.sqlというファイルを作成し、中身にこんな命令を書く。

use DATABASE_NAME; ← movable type用のDB名
show tables;

で、こんな感じでmysqlにこのファイルをリダイレクトして結果をファイルにリダイレクト。

mysql -USER_NAME yz -p DATABASE_NAME < ./tables.sql > targetTables

出て来たファイルはこんな感じ。

% cat ./targetTables
Tables_in_mt
mt_author
mt_blog
mt_category
mt_comment
mt_config
mt_entry
mt_fileinfo
mt_ipbanlist
mt_log
mt_notification
mt_objecttag
mt_permission
mt_placement
mt_plugindata
mt_session
mt_tag
mt_tbping
mt_template
mt_templatemap
mt_trackback

一行目は要らないのでviで開いてddで消しちゃう。

んで、先述のmysqldumpコマンドを一個のシェルスクリプトとしてファイルに記述。ここでのポイントはmysqlに接続するためのパスワードを書いてしまうこと。

% cat dump.sh
#!/bin/bash
mysqldump -u USER_NAME --password=PASSWORD DB_NAME --no-create-db $1 > ./$1.sql

後はforループで回してやるだけで全テーブルのデータを「テーブル名.sql」というファイル名でdumpできる。パスワードをdump.shに記述しておかないと(-pオプションにしてしまうと)テーブルごとにパスワードを聞かれてうざい。

#!/bin/bash
for i in `cat ./targetTables`
do ./dump.sh $i
done


で、テーブルごとに「どのテーブルにFQDNが記載されているか」を調査する。

% grep -H 'somethingnew.ddo.jp' ./*.sql | awk {'print $1'} | sort | uniq
/home/******/******/blog/200705_iko:
./mt_author.sql:INSERT
./mt_blog.sql:INSERT
./mt_comment.sql:INSERT
./mt_entry.sql:INSERT
./mt_tbping.sql:INSERT
./mt_template.sql:INSERT
./mt_trackback.sql:INSERT

対象テーブルはどうやらこの7つに絞られるようだ。
個別に見て行くと、mt_author中に含まれているのはプロフィール情報の一件のみ。これは移行後に管理ツールから修正すればOKなレベルなので放置しておこう。
mt_template表に含まれているのはjavascript関連がほとんど。テンプレートのデータはローカルディスク上でバージョン管理しているので、そっちを修正して移行先にインポートするのがよかろう。

ということでdump中に含まれるsomethingnew.ddo.jpという表記を直す対象テーブルはmt_comment、mt_entry、mt_trackbackの3つにすることにした。
# リハーサルしてみて、問題があったら他も直せばいいし。


なので次に修正まで含めたシェルスクリプトを書く。修正するついでに移行作業が楽になるよう、全部のダンプを一つのアーカイブファイルに固めてしまうところまで作成。

#!/bin/bash

for i in `cat ./targetTables`
do ./dump.sh $i
done


# change url (somethingnew.ddo.jp -> NEWDOMAIN.com)
# mt_comment
cat ./mt_comment.sql |\
sed 's/http:\/\/somethingnew.ddo.jp\/blog\/index.html/http:\/\/NEWDOMAIN\.com\//' |\
sed 's/http:\/\/somet hingnew.ddo.jp\/blog\//http:\/\/NEWDOMAIN\.com\//' |\
sed 's/http:\/\/somethingnew.ddo.jp\/blog/http:\/\/NEWDOMAIN\.com\//' |\
sed 's/http:\/\/somethingnew.ddo.jp\//http:\/\/NEWDOMAIN\.com\//' |\
sed 's/http:\/\/somethingnew.ddo.jp/http:\/\/NEWDOMAIN\ .com\//' \
>> ./mt_comment.sql.replaced


# mt_entry
cat ./mt_entry.sql |\
sed 's/http:\/\/somethingnew.ddo.jp\/blog//g' |\
sed 's/tag:somethingnew2.com/tag:NEWDOMAIN.com/g'\
>> ./mt_entry.sql.replaced


# mt_trackback
cat ./mt_trackback.sql |\
sed 's/http:\/\/somethingnew.ddo.jp\/blog\//http:\/\/NEWDOMAIN.com\//g' \
>> ./mt_trackback.sql.replaced


# mkdir and archive dumpfiles.
timestamp=`date +%Y%m%d-%H%M`
mkdir $timestamp
mv ./mt_*.sql* ./$timestamp/
tar cjf ./$timestamp.tar.bz2 ./$timestamp


ここまでを全部スクリプトにしておくと、これ一発叩くだけで移行元(somethingnew.ddo.jp)側での作業はほとんど終了。あと出来ることと言ったらdumpを入れた後の件数確認くらいかな。(それもスクリプトに組み込んでしまえば良いだけの話か。後でやってみよう)


こんな感じでお引っ越しの準備が着々と進行中。。
思ったよりも時間がかかっちゃいそうです。