以前使っていたサーバから新しいサーバへ引越する手順で結構めんどくさいのがMySQLのデータ引越。
DNSも外にあるのでAレコードの変更だけで済むし、コンテンツファイルはまぁサイズが大きくてもtarしてftpで転送するだけなので大した時間はかからない。
mysqlもmysqldumpでファイルを付くって、新しいサーバでコマンドラインから投入すれば数分で済むと思っていた。
ところが、やってみるとこれが非常に時間がかかる。遅い。遅すぎる・・・
私のサイトのテーブルは20Mくらいのサイズしかないのだが、試しに移行してみると1時間かかっても終了しなかった。1テーブルだけ(1.4メガくらい)を移行テストしてみたところ、10分かかった。
とんでもなく遅い。なんでこんなに時間がかかるんだ。
でネットでいろいろ調べてみた方法を試してみた。
・mysqldumpにオプションを付加する方法
--disable-keys をつけると、インサートのたびにキー更新せず、insertが全部完了してからテーブルのインデックスを作るので早くなる。
ただ、私の環境では --opt を付加してmysqldumpを実行しているので、これはもともとそうなっていた。
--extended-insert をつけると1行で複数のinsert文を作るので早くなる。これも同様に私の環境では既にそうなっていた。
--no-autocommit をつけるとまとめてコミットするので早くなる、とのことだったので試してみたが、結局前よりも遅くなった。
・移行先のmysql設定を見直してみる
net_buffer_lengthのサイズを大きくしてみたが効果なし。
key_buffer=256M
query_cache_size=32M
こんな設定も試してみたが変化なし。関係ないらしい。
myisam_max_sort_file_size=2G
tmpdir=/home/tmp
これも変化がなかった。このmyisam_max_sort_file_sizeをべらぼうにデカイ値にするという記事もあったが、試してみたところshow variables;でエラーになってしまったのでやめた。
で、最終的にはmysqlのデータファイルをまんまコピーするという荒技を試してみた。
・mysqlのデータを単純にコピーする方法
こんな感じで。
このファイルを移行先のサーバにFTPで転送し、
これで解凍・展開する。展開するとopt、frm、MYD、MYIなどの拡張子のファイルが沢山できるので、同じようにmysqlのデータ格納ディレクトリを調べて、db名のディレクトリに丸ごとコピーする。
データが更新されていたらうまくいかないのでテーブルをロックする、などの注意書きもあったのだが、私の場合は特にそういうことをしなくてもうまくいった。
割とDB更新が多いサイトを運営しているが、3回試して3回ともうまくいった。しかも移行元と移行先でmysqlのバージョンが違っているにもかかわらず。
単純にコピーしたいだけの引越ならこれが一番簡単ではないだろうか。ていうかmysqlはそういうたぐいの方法を用意するべきじゃない?
ちなみにデータベース名やデータベースユーザ名は移行元と先で統一して実験した。
DNSも外にあるのでAレコードの変更だけで済むし、コンテンツファイルはまぁサイズが大きくてもtarしてftpで転送するだけなので大した時間はかからない。
mysqlもmysqldumpでファイルを付くって、新しいサーバでコマンドラインから投入すれば数分で済むと思っていた。
ところが、やってみるとこれが非常に時間がかかる。遅い。遅すぎる・・・
私のサイトのテーブルは20Mくらいのサイズしかないのだが、試しに移行してみると1時間かかっても終了しなかった。1テーブルだけ(1.4メガくらい)を移行テストしてみたところ、10分かかった。
とんでもなく遅い。なんでこんなに時間がかかるんだ。
でネットでいろいろ調べてみた方法を試してみた。
・mysqldumpにオプションを付加する方法
--disable-keys をつけると、インサートのたびにキー更新せず、insertが全部完了してからテーブルのインデックスを作るので早くなる。
ただ、私の環境では --opt を付加してmysqldumpを実行しているので、これはもともとそうなっていた。
--extended-insert をつけると1行で複数のinsert文を作るので早くなる。これも同様に私の環境では既にそうなっていた。
--no-autocommit をつけるとまとめてコミットするので早くなる、とのことだったので試してみたが、結局前よりも遅くなった。
・移行先のmysql設定を見直してみる
net_buffer_lengthのサイズを大きくしてみたが効果なし。
key_buffer=256M
query_cache_size=32M
こんな設定も試してみたが変化なし。関係ないらしい。
myisam_max_sort_file_size=2G
tmpdir=/home/tmp
これも変化がなかった。このmyisam_max_sort_file_sizeをべらぼうにデカイ値にするという記事もあったが、試してみたところshow variables;でエラーになってしまったのでやめた。
で、最終的にはmysqlのデータファイルをまんまコピーするという荒技を試してみた。
・mysqlのデータを単純にコピーする方法
mysqladmin variables | grep datadir
これを実行するとmysqlのデータがどこに格納されているかが分かる。そのディレクトリにあるDB名のディレクトリを丸ごと圧縮する。tar zcvf db_backup.tar.gz dbname
こんな感じで。
このファイルを移行先のサーバにFTPで転送し、
zip -dc db_backup.tar.gz | tar xvf -
これで解凍・展開する。展開するとopt、frm、MYD、MYIなどの拡張子のファイルが沢山できるので、同じようにmysqlのデータ格納ディレクトリを調べて、db名のディレクトリに丸ごとコピーする。
データが更新されていたらうまくいかないのでテーブルをロックする、などの注意書きもあったのだが、私の場合は特にそういうことをしなくてもうまくいった。
割とDB更新が多いサイトを運営しているが、3回試して3回ともうまくいった。しかも移行元と移行先でmysqlのバージョンが違っているにもかかわらず。
単純にコピーしたいだけの引越ならこれが一番簡単ではないだろうか。ていうかmysqlはそういうたぐいの方法を用意するべきじゃない?
ちなみにデータベース名やデータベースユーザ名は移行元と先で統一して実験した。