mysqlを稼動させたまま、複数テーブルのレプリケーションを行う。
社内で運用中のRailsアプリケーションでは、データベースをShardingして一つのmysql上に複数DBがのっかっている状態になっている。
このデータベースはmasterとslaveで分散させているのですが、slaveの負荷が高くなってきた為にslaveの数を増やすことになりました。
その為にmasterのdumpをとってslaveに流してやります。--flush-logオプションをつければあるタイミングでbin-logを移動してくれるので、レプリケーション先でMASTER_FILE_LOGを新しいbin-logを指定してやればいいのです。
master-db
master-dbでのファイルの位置を確認し、dumpを取ります。
mysql> show master status;
+----------------+-----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +----------------+-----------+--------------+------------------+ | log-bin.000061 | 119120300 | | mysql | +----------------+-----------+--------------+------------------+
mysqldump --skip-lock-tables --flush-log --single-transaction --user=root --password --database database-1 database-2 database-3 | gzip -c > database_dump_`date +%Y%m%d_%H%M`.gz
で、log-binファイルを確認する。
sudo ls -l mysql/var/log-bin
(省略) -rw-rw---- 1 mysql staff 56193 2010-12-17 13:10 log-bin.000057 -rw-rw---- 1 mysql staff 109617173 2010-12-17 15:02 log-bin.000058 -rw-rw---- 1 mysql staff 26931166 2010-12-17 15:15 log-bin.000059 -rw-rw---- 1 mysql staff 135276244 2010-12-17 16:02 log-bin.000060 -rw-rw---- 1 mysql staff 120524056 2010-12-17 16:39 log-bin.000061 -rw-rw---- 1 mysql staff 5468112 2010-12-17 16:41 log-bin.000062 -rw-rw---- 1 mysql staff 137097 2010-12-17 16:41 log-bin.000063 -rw-rw---- 1 mysql staff 4438152 2010-12-17 16:42 log-bin.000064
なんと、log-binファイルが想定以上に移動している。
どうやら一緒に指定しても、dumpを取るdatabase毎にflushしちゃってるみたい。これだと、slaveのレプリケーションを64から開始しようとしても62に含まれるdatabase-1に対するクエリ、63に含まれるdatabase-1, 2に対するクエリが実行されていないことになってしまう。そこで、取ったdumpと共にlog-binファイルからもクエリを実行してやる必要がある。
以下のファイルをslaveにコピーする。
scp database_dump_YYYYmmdd_HHMM.gz slave-db:/tmp sudo cp mysql/var/log-bin/log-bin.000062 /tmp/ sudo cp mysql/var/log-bin/log-bin.000063 /tmp/ sudo chmod +r /tmp/log-bin.00006* for log in 62 63 scp /tmp/log-bin.0000${log} parkgree-db-slave-03:/tmp
slave-db
slaveを止めて、データベースを作り直す。
mysql> stop slave
for db in {1..3} mysql -uroot -p -e'drop database database-'$db for db in {1..3} mysql -uroot -p -e'create database database-'$db
masterの位置を設定しなおす。
mysql> CHANGE MASTER TO mysql> MASTER_LOG_FILE='log-bin.000064', mysql> MASTER_LOG_POS=0;
dumpファイルを実行する
gunzip -c /tmp/database_dump_YYYYmmdd_HHMM.gz | mysql -uroot -p
忘れずにbinlogファイルを読み込む
mysqlbinlog --database=database-1 log-bin.000062 | mysql -uroot -p database-1 mysqlbinlog --database=database-1 log-bin.000063 | mysql -uroot -p database-1 mysqlbinlog --database=database-2 log-bin.000063 | mysql -uroot -p database-2
で、slaveを再開する。
mysql> start slave
DBが同期されていることが確認出来ればOKです。