うまいぼうぶろぐ

linuxとhttpdとperlのメモ

mysqlで既存の状態からレプリケーション構築 - innodb編

webの情報を見てると、まずデータディレクトリをtarで固めて・・・というのを良くみかける。MyISAMのみならそれでもいいと思うけど、InnoDBを使用してるとちょっと不都合かなと思って調べた。
というのもInnoDBのデータ領域は設定した分だけ最初にディスクに作成されるので、数GByteに設定している場合、実際に使ってる実データは少なくてもtarで時間がかかってしまうから。


調べながら試行錯誤したら、mysqldumpを使うだけで出来た。ただし、この方法の場合、dumpを取る間に全テーブルにREAD LOCKを掛ける。master dataの取得さえ先にしとけば、--lock-all-tablesしなくてもいけそうだけど。

masterでの作業

全データのdumpを取得する。

$ mysqldump \
 --all-databases \
 --add-drop-database \
 --add-drop-table \
 --master-data \
 --lock-all-tables \
 > dumpdata

オプションの意味。

--master-data

mysqldumpコマンド実行時の、マスターの状態(binary log filename, log position)をdumpdataに保存する。show master statusを手動で記録する手間が省けるので、ここで取得しとく。--master-dataを指定すると--lock-all-tablesは自動でオンになる。

--add-drop-database --add-drop-table

create database,tableをする前にdropする。

--lock-all-tables

(古いバージョンの場合は--first-slave)
mysqldump中、全tableにREAD LOCKする。--single-transactionと--lock-tablesは自動でオフになる。--master-dataを指定すれば--lock-all-tablesは自動でオンになるので、実は指定しなくても良い。けど解りやすいので明示的に指定してみた。

  • --add-locksとの違い

--add-locksは各tableをdumpする前後にlock tables、unlock tablesを掛ける。なので普通にdumpするだけなら--add-locksのほうが良い。ただし、--master-dataを使ってレプリケーションのためのdumpを取る場合はダメなはず。なぜなら、--master-dataの結果はdumpの初めに書き込まれるため、mysqldump中に他のtableが更新されるとlog positionがずれてしまうから。たぶん。
追記:あれ?master dataはdumpの先頭に記録されるから、その後tableが更新されても実は問題ないのではないだろうか。slaveはbinlog positionから追いかければいいわけだし。うーんよくわからない。まぁ、--master-dataを指定すれば自動で付くオプションなので、--lock-all-tablesで間違いはない、ということで良しにしよう。

slaveでの作業

my.cnfにskip-slaveを入れてmysqld起動。あとはdumpdataを流すだけ。

$ mysql < dumpdata
$ mysql -e 'start slave'

これで完了。後はmy.cnfのskip-slaveをコメントしておく。