レプリケーション設定

やりたいこと

MasterサーバとSlaveサーバでそれぞれApache、MySQLが動いている状態。
Masterサーバ、SlaveサーバともにNLB配下に置かれている。
リクエストが来た場合、Masterサーバ、Slaveサーバで受けるが、DBはHAProxyでMaster側のDBのみ使用、マスター側ダウン時は読み取り専用のSlaveのDBを使用する。
これにより、Masterサーバが完全に停止してもサイトを閲覧可能の状態にできる、更新はできないが。
Slaveサーバダウン時は問題なく閲覧更新どちらも可能。
ここではHAProxyやMasterサーバ、Slaveサーバのコンテンツ同期などは置いておき、純粋にレプリケーション設定のみ記載しておく。
ほとんどMySQL5.7のマニュアルに従っている。
解説もほとんどマニュアルを和訳したものに若干わたしが言葉を足している。
また、Slaveのリードオンリー設定などは別サイトを参考にしている。
マニュアルの参考例だとSlave側をリードオンリーに設定していないようなので。

作業記録~マスター~

サーバーID付与、バイナリロギング有効化

バイナリログはマスターからスレーブへの変更をレプリケートするための基礎であるため、マスターでバイナリロギングを有効にする必要があります。
レプリケーショングループ内の各サーバーは、一意のサーバーIDで構成する必要があります。
server_idを設定しない場合(または明示的にデフォルト値の0に設定する場合)、マスターはスレーブからの接続を拒否します。

vi /etc/my.cnf
-----
[mysqld]
server-id=1
log-bin
-----
sudo systemctl restart mysqld.service

レプリケーション用アカウント作成

他のアカウントへの侵害の可能性を最小限に抑えるために、レプリケーションプロセス専用の特権を持つ別のアカウントを作成することができます。
そのアカウントに必要なのはREPLICATION SLAVE特権のみです。

mysql -u root -p
mysql> create user 'repl'@'%' identified by '************';
mysql> grant replication slave on *.* to 'repl'@'%';
mysql> select Host,User, authentication_string from mysql.user;

バイナリログの座標取得

マスターバイナリログの座標を取得するには、次の手順を実行します。
マスターの別のセッションで、SHOW MASTER STATUSステートメントを使用して、現在のバイナリログファイルの名前と位置を確認します。

mysql> flush tables with read lock;
mysql> show master status;
+-------------------------+----------+--------------+------------------+-------------------+
| File                    | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------------+----------+--------------+------------------+-------------------+
| ip-10-0-3-14-bin.000002 |      555 |              |                  |                   |
+-------------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

スレーブにデータコピー

masterデータベースに既存のデータが含まれている場合、このデータを各スレーブにコピーする必要があります。

mysqldump -u root -p --default-character-set=binary --single-transaction --all-databases > /efs/fulldump.sql

読み取りロックを取得したクライアントで、ロックを解除します。

mysql> unlock tables;

作業記録~スレーブ~

auto.cnfの削除

ここから先のコマンドはSlaveサーバで実施します。
念のため補足ですが、MasterサーバとSlaveサーバはディレクトリ/efs以下を共有しています。
そういう設定をしていないのであればrsyncなりftpなりでMasterサーバのダンプファイルをSlaveに移す必要があります。

Masterサーバを複製してSlaveサーバを作った場合、uuidが一緒はダメといわれて怒られるので下記コマンドを実行。

rm /var/lib/mysql/auto.cnf
sudo systemctl restart mysqld.service

データベースリストア

データベースのアーカイブまたはコピーを作成したら、スレーブレプリケーションプロセスを開始する前に、ファイルを各スレーブにコピーします。

mysql -u root -p --default-character-set=binary < /efs/fulldump.sql

サーバーID付与、読み取り専用設定

各レプリケーションスレーブには一意のサーバーIDが必要です。
レプリケーションをセットアップするために、スレーブでバイナリロギングを有効にする必要はありません。

vi /etc/my.cnf
-----
[mysqld]
server-id=2
#log-bin
read_only=1
super_read_only=1
-----
sudo systemctl restart mysqld.service

レプリケーションセットアップ

レプリケーションのためにマスターと通信するようにスレーブをセットアップするには、必要な接続情報でスレーブを構成します。これを行うには、スレーブで次のステートメントを実行し、オプション値をシステムに関連する実際の値に置き換えます。

mysql -u root -p
mysql> stop slave;
mysql> reset SLAVE;
mysql> change master to
    -> master_host='10.0.3.14',
    -> master_user='repl',
    -> master_password='************',
    -> master_log_file='ip-10-0-3-14-bin.000002',
    -> master_log_pos=555;

mysql> start slave;
mysql> show slave status\G
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

上記のように出力されれば問題ない。

テスト

テストコマンド※Master側で実行

mysql> CREATE DATABASE sampledb;

Slave側でSHOW DATABASES;を打ち、sampledbが作成されているか確認。