«前の日記(2011-10-13 (Thu)) 最新 次の日記(2011-10-20 (Thu))» 編集

雑記帳


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になっていれば、レプリケーションは問題なく動作している。