MySQLのマスター1台、スレーブ2台、mysql-master-haのマネージャ1台の計4台構成です。
4台すべてを起動するとトータルで3.5GBほどメモリを使用しますので、ご注意ください。
手順は全部Ansibleで自動化してもよかったのですが、それだとフェイルオーバーの動作がよくわからないかと思ったので、レプリケーション、HA構成の設定は手動です。
HA構成にはmysql-master-haを使用します。
準備
VirtualBox、Vagrant、Ansibleはあらかじめインストールしておき、ターミナル上でコマンドが実行できるようにしておいてください。
OSはCentOSを使用します。
以下のコマンドでCentOS6.5のボックスを追加します。
$ vagrant box add centos65 http://www.lyricalsoftware.com/downloads/centos65.box
適当なディレクトリで今回使うファイル一式をcloneします。
vagrant up
ですべてのサーバーが起動し、MySQL、mysql-master-haのインストールが行われます。
4台すべてのセットアップが終わるまで待ちます。
$ git clone https://github.com/hakuro/vagrant-mysql-ha.git
$ cd vagrant-mysql-ha
$ vagrant up
レプリケーション設定
my.cnfの設定
MySQL5.6には準同期のレプリケーションがありますが、今回は特に設定を行いません。
MySQLのマスター、スレーブ2台それぞれのmy.cnf
にserver_id
とlog-bin
の設定を追加します。
$ vagrant ssh mysql_master
$ sudo tee -a /etc/my.cnf <<EOT
[mysqld]
server_id=10
log-bin=mysql-bin
sync_binlog=1
EOT
$ sudo service mysqld restart
$ exit
$ vagrant ssh mysql_slave1
$ sudo tee -a /etc/my.cnf <<EOT
[mysqld]
server_id=11
log-bin=mysql-bin
sync_binlog=1
EOT
$ sudo service mysqld restart
$ exit
$ vagrant ssh mysql_slave2
$ sudo tee -a /etc/my.cnf <<EOT
[mysqld]
server_id=12
log-bin=mysql-bin
sync_binlog=1
EOT
$ sudo service mysqld restart
$ exit
(以降、vagrant ssh
は省略。マスター上の操作は「on master」、スレーブ上の操作は「on slave」、HAマネージャ上の操作は「on manager」と記載する)
レプリケーション用ユーザの作成
レプリケーション用のユーザを作成します。
on master and slave
$ mysql -u root -p
mysql> GRANT REPLICATION SLAVE ON *.* TO repl@'%' IDENTIFIED BY 'repl';
マスターのバイナリログのファイル名とポジションの確認
マスターのバイナリログのファイル名とポジションを表示させ、FileとPositionをメモしておきます。
通常はマスターをバックアップし、スレーブに適用する必要がありますが、セットアップ直後なので必要ないです。
on master
mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.XXXXXX | YYY | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
スレーブをマスターに接続
メモしたバイナリログのファイル名とポジションを以下の「mysql-bin.XXXXXX」、「YYY」に当てはめて実行する。
その後、レプリケーションを開始する。
on slave
$ mysql -u root -p
mysql> CHANGE MASTER TO MASTER_HOST='192.168.50.10', MASTER_USER='repl', MASTER_PASSWORD='repl', MASTER_LOG_FILE='mysql-bin.XXXXXX', MASTER_LOG_POS=YYY;
mysql> start slave;
mysql> show slave status\G
Slave_IO_Running、Slave_SQL_Runningが「YES」になっていること。
問題なければスレーブをread_onlyにしておきます。
on slave
mysql> SET GLOBAL read_only = 1;
マスターにVIPを付与する
マスターがフェイルオーバーした前後でアプリケーションがアクセスすべきIPは変化しない必要があります。
マスターのサーバーに仮想IPを付与することで、これを解決します。
フェイルオーバー時には新たなマスターになったスレーブにこの仮想IPが付与されます。
on master
$ sudo ifconfig eth1:1 192.168.50.100
$ ifconfig
mysql-master-haの設定
MySQLのrootユーザに他のサーバーからログインできるようにする
そのままの設定ではMySQLが動作しているサーバー以外からrootユーザにログインできないため、ログインできるように設定します。
ログイン元のIPを制限しないのはセキュリティ的に問題がありますが、今回は手元の仮想環境なので特に制限しません。
on master
$ mysql -u root -p
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION;
sshの公開鍵認証
各DBサーバー間で相互に公開鍵ログインできるようにし、mysqlユーザがパスワードなしでsudoできるようにします。
on master and slave
$ sudo usermod -G wheel mysql
$ sudo su - mysql
$ ssh-keygen -b 1024 -t rsa
$ cat ~/.ssh/id_rsa.pub | sudo tee -a /vagrant/authorized_keys
HAマネージャのサーバーにはmysqlユーザがいないのでvagrantユーザが公開鍵でログインできるようにします。
on manager
$ ssh-keygen -b 1024 -t rsa
$ cat ~/.ssh/id_rsa.pub | sudo tee -a /vagrant/authorized_keys
各サーバの公開鍵が/vagrant/authorized_keys
にそろったので、これを$HOME/.ssh
以下にコピーし、パーミッションの設定をします。
on master and slave
$ sudo cp /vagrant/authorized_keys /var/lib/mysql/.ssh/authorized_keys
$ sudo chown mysql:mysql /var/lib/mysql/.ssh/authorized_keys
$ sudo chmod 700 /var/lib/mysql/.ssh/authorized_keys
on manager
$ sudo cp /vagrant/authorized_keys /home/vagrant/.ssh/authorized_keys
$ sudo chown vagrant:vagrant /home/vagrant/.ssh/authorized_keys
$ sudo chmod 700 /home/vagrant/.ssh/authorized_keys
mysql-master-haの設定
DBサーバー上にmha用の作業ディレクトリも作っておきます。
on master and slave
$ sudo mkdir -p /var/log/masterha/app1
$ sudo chown -R mysql:mysql /var/log/masterha
HAマネージャのサーバーの設定をします。
mha用の作業ディレクトリを作成し、フェイルオーバー時にVIP等の張り替えをするperlスクリプトを配置し、mysql-master-haの設定ファイルも配置します。
on manager
$ sudo mkdir -p /var/log/masterha/app1
$ sudo chown -R vagrant:vagrant /var/log/masterha
$ sudo cp /vagrant/mha/master_ip_failover /usr/local/bin/master_ip_failover
$ sudo chmod 755 /usr/local/bin/master_ip_failover
$ sudo touch /etc/masterha_default.cnf
$ sudo mkdir -p /etc/masterha
$ sudo tee -a /etc/masterha/app1.cnf <<EOT
[server default]
user=root
password=root
ssh_user=mysql
manager_log=/var/log/masterha/app1/manager.log
manager_workdir=/var/log/masterha/app1
remote_workdir=/var/log/masterha/app1
repl_user=repl
repl_password=repl
master_ip_failover_script=/usr/local/bin/master_ip_failover
[server1]
hostname=192.168.50.10
[server2]
hostname=192.168.50.11
candidate_master=1
[server3]
hostname=192.168.50.12
no_master=1
EOT
動作チェッック
sshの疎通、レプリケーションをチェックします。
on manager
$ masterha_check_ssh --conf=/etc/masterha/app1.cnf
$ masterha_check_repl --conf=/etc/masterha/app1.cnf
マネージャの起動
バックグラウンドで起動します。
on manager
$ nohup masterha_manager --conf=/etc/masterha/app1.cnf < /dev/null >> /var/log/masterha/app1/console.log 2>&1 &
あとはマスター上のMySQLを落としてみるなりして、マスター、スレーブが切り替わるか試してみましょう。