雑記帳
2011-10-17 (Mon) [長年日記]
■ [MySQL] 稼働中のMySQLに無停止でスレーブを追加する
MySQLは簡単にレプリケーションすることができて便利。最初からレプリケーションを前提に構築するのは簡単にできる。しかし、実は運用が始まってしまって、なかなか停止できないMySQLにも、ほぼ無停止でスレーブサーバを追加できる。現在の設定状況にもよるが、再起動は必要になるかも。
マスターでバイナリログを出力するようにする
my.cnfで、binlog_do_dbの設定をする。レプリケーション対象となるデータベースを指定する。
[mysqld] binlog_do_db=your_db
マスタのserver_idを設定する
my.cnf で server_idの設定をする。レプリケーションする際に、個々のサーバを識別するのに使われる。任意のユニークな整数を指定すれば良い。
[mysqld] server_id=10
ここまでの設定ができたら設定を反映させて、mysqlのデータディレクトリに、バイナリログが出力されていることを確認する。
マスターに、スレーブからマスターに接続するためのアカウントを作成する
レプリケーションするために、スレーブからマスターに接続する専用のアカウントを作成する。ここでは、replというユーザで作成している。
CREATE USER 'repl'@'10.%' IDENTIFIED BY 'password'; GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'repl'@'10.%' IDENTIFIED BY 'password WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0;
マスターからデータをdumpする
$ mysqldump your_db --master-data --single-transaction > your_db.dump
mysqldumpに、--master-dataを付与するのがポイント。また、InnoDBであれば、--single-transactionを付与することで、ロックされることなくdumpを取得できる。MyISAMの場合は、--master-dataによって、自動的に--lock-all-tablesが有効になるので、すべてのテーブルがロックされてしまうので注意。また、データベース内にInnoDBとMyISAMのテーブルが混在している場合は、--single-transactionを付与すると、データの不整合が起こる可能性があるので、付与しないこと(すべてのテーブルがロックされる)。
スレーブのserver_idを設定する
マスターと同様に、server_idに任意の値を設定する。
[mysqld] server_id=20
スレーブに、マスターへ接続するためのアカウントを作成する
CHANGE MASTER TO MASTER_HOST='master_host_name',MASTER_USER='repl', MASTER_PASSWORD='password';
スレーブにdumpデータをロードする
スレーブにデータベースを作成して、dumpしたデータをロードする。
mysql> CREATE DATABASE your_db; mysql> \q $ mysql your_db < your_db.dump
スレーブにレプリケーションの設定をする
dumpしたファイルの先頭に、マスターのバイナリログのファイルとポジションが書かれているので、それを参照してCHANGE MASTERを実行する。
CHANGE MASTER TO MASTER_LOG_FILE='binlog_name', MASTER_LOG_POS=log_position;
マスターが正しく設定されているか確認
設定ができたら、SQLコマンドを実行して動作状況を確認する。
mysql> SHOW MASTER STATUS\G
スレーブでレプリケーションを開始
mysql> SLAVE START; mysql> SHOW SLAVE STATUS\G
動作確認
実際に、データを投入するなどしてから、SHOW MASTER STATUSでバイナリログのポジションに変化があるかどうか確認する。
mysql> SHOW MASTER STATUS\G
Slave_IO_Runningと、Slave_SQL_Runningが、両方共Yesになっていれば、レプリケーションは問題なく動作している。