MySQLのレプリケーションテスト環境の構築方法


## 前提条件

* vagrantを利用して, CentOS環境を手に入れる
* MySQL::Sandboxを利用して, 1台のサーバでレプリケーションを高速に実現する

## Perl環境の構築

* ここではOS標準のPerlではなく, perlbrewを使う

<pre>
$ curl -kL http://install.perlbrew.pl | bash
$ LASTVERSION=$(perlbrew available | head -1)
$ perlbrew install $LASTVERSION
$ perlbrew switch $LASTVERSION
$ curl -L https://raw.github.com/miyagawa/cpanminus/master/cpanm | perl - App::cpanminus
$ perlbrew install-cpanm
$ cpanm local::lib
$ cpanm MySQL::Sandbox
</pre>

## MySQLのインストールと準備

* ここでは MySQL 5.5の最新版を利用する
** Linux - Generic 2.6 (x86, 64-bit), Compressed TAR Archive を Download する
* master 1台, slave 2台の合計 3台構成

<pre>
$ mkdir ~/mysql
$ cd ~/mysql
$ wget http://downloads.mysql.com/archives/get/file/mysql-5.5.47-linux2.6-x86_64.tar.gz
$ make_replication_sandbox --how_many_slaves=2 ~/mysql/mysql-5.5.47-linux2.6-x86_64.tar.gz
</pre>

## MySQL::Sandbox の使い方

* ~/sandboxes/rsandbox_mysql-5_5_47
	* 上記に必要なコマンドが揃っています
	* ./n1 を実行すると node1 (Master) サーバに接続できます
		* ./m でも同様
	* ./n2 を実行すると node2 (Slave1) サーバに接続できます
		* ./s1 でも同様
		* ./s2 は node3 (Slave2) に接続される
* ~/sandboxes
	* 上記にNode全体を管理するコマンドがあります
	* ./restart_all 全サーバを再起動します
	* ./stop_all 全サーバを停止します
	* ./start_all 全サーバをスタートさせます
	* ./use_all 全サーバに同じコマンドを投げます
	<pre>
./use_all "show variables like 'port'"
# master
Variable_name	Value
port	26002
# server: 1:
Variable_name	Value
port	26003
# server: 2:
Variable_name	Value
port	26004
	</pre>

## node1 を slaveにし, node3 を Masterに昇格させる

### 通常のmysqlコマンドを利用したい場合は以下の設定をしておくとOK
<pre>
$ echo "alias mysql=~/mysql/5.5.47/bin/mysql" >> ~/.bash_profile
$ echo "PATH=$PATH:~/sandboxes/rsandbox_mysql-5_5_47" >> ~/.bash_profile
$ source ~/.bash_profile
</pre>

### MySQLのノード情報
| -          | node 1      | node 2       | node 3     |
|:-----------|------------:|-------------:|-----------:|
| IP         |   127.0.0.1 |    127.0.0.1 |   127.0.0.1|
| port       |       26002 |        26003 |      26004 |
| root_passwd|   msandbox  |     msandbox |   msandbox |
| repl_user  |    rsandbox |     rsandbox |   rsandbox |
| repl_passwd|    rsandbox |     rsandbox |   rsandbox |


※ 上記の情報は以下のファイルを見ると一発で分かります

* ~/sandboxes/rsandbox_mysql-5_5_47/connection.json

### 実施作業

1. Master に更新が走らないように LOCKする
	<pre>$ mysql -uroot -h 127.0.0.1 -P 26002 -p</pre>
	or
	<pre>$ m</pre>
	1. 余計なプロセスが動いていないか確認をする
	<pre>
	> SHOW PROCESSLIST;
	</pre>
	1. 動いていなければ、LOCKをする
	<pre>
	> FLUSH TABLES WITH READ LOCK;
	</pre>
	※ LOCKが外れないように、このセッションを切らないこと
1. node2 と node3 に接続をし、Slaveを停止する
	<pre>
	$ echo "STOP SLAVE IO_THREAD" | s1
	$ echo "STOP SLAVE IO_THREAD" | s2
	</pre>
1. SHOW PROCESSLIST; を実行し、"Slave has read all relay log;" と表示されるまで待つ
	<pre>
	$ echo "SHOW PROCESSLIST" | s1 | grep --color 'Slave has read all relay log'
	$ echo "SHOW PROCESSLIST" | s2 | grep --color 'Slave has read all relay log'
	</pre>
1. 読み込んでいたbinlogを処理仕切ったので、slaveを停止する
	<pre>
	$ echo "STOP SLAVE" | s1
	$ echo "STOP SLAVE" | s2
	</pre>
1. master情報 | slave情報を削除する
	<pre>
	$ echo "RESET MASTER; RESET SLAVE;" | s1
	$ echo "RESET MASTER; RESET SLAVE;" | s2
	</pre>
1. node3(新Master)のREAD ONLYをOFFにする
	<pre>
	$ echo "SET GLOBAL read_only = OFF;" | s2
	</pre>
1. node2 と node1 を node3 の binlogを読むようにする
	<pre>
	$ s1
	> CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=26004, MASTER_USER='rsandbox', MASTER_PASSWORD='rsandbox';
	> START SLAVE;
	</pre>
	<pre>
	※ 止めていたnode1のセッションに戻る
	> UNLOCK TABLES;
	> RESET MASTER; RESET SLAVE;
	> CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_PORT=26004, MASTER_USER='rsandbox', MASTER_PASSWORD='rsandbox';
	> START SLAVE;
	</pre>
1. node1 は Slaveになったので, READ ONLYをONにする
	<pre>
	$ echo "SET GLOBAL read_only = ON" | m
	</pre>


これでめでたく node3 が Master になって、 node1 が slaveになりました。
ためしに node3に更新系のクエリを投げて、node1, node2 に反映されているか試してみてください。

※ my.cnf に直接 replication情報やREADONLY設定を書いている場合は、そこも編集してください。