CentOS7&MySQL5.7でクラッシュセーフな準同期レプリケーションを構築する

レプリケーションや高可用性構成の検証の為、MySQL5.7に準同期レプリケーションを構築した手順をまとめます。
MySQL5.7でデフォルトでONになっているロスレスレプリケーションの他、GTIDやクラッシュセーフスレーブもONにした手堅い設定になっています。いずれもMySQL5.7ではパフォーマンスを維持しながら可用性を高められるオプションなので、新規導入ならONにするのがお勧めです。

はじめに手順をまとめます。主要なオプション(パラメータ)については手順の後にまとめています。

前提

サーバーの用意

・マスター用:1台
・スレーブ用:1台以上
マスター・スレーブとも以下の記事の手順で新規インストールしています。
CentOS7にyumでMySQL5.7最新版をインストールする - tkn4416 Tech Blog

運用中のサーバをもとにスレーブを追加しレプリケーション構成にする場合、スレーブへのデータのコピーなどの作業も必要です。

サーバーの構成

全台とも以下の構成で確認しています。
・MySQL5.7.21
CentOS Linux release 7.4.1708 (Core)
・ESXi6.5仮想サーバー(RAM:2GB、HDD:16GB(シンプロビジョニング))
NIC:1枚(192.168.1.0/24に接続)

手順

rootで作業しています。必要に応じてsudoを付けて実行してください。
IPアドレスは第4オクテットを伏字(**)にしていますので、環境にあわせて変更してください。

1. ファイアウォールの設定

CentOS7のデフォルト設定ではMySQLレプリケーションの通信がブロックされてしまう為、publicゾーンにmysqlを追加します。

#publicゾーンにmysqlを追加
firewall-cmd --permanent --add-service=mysql --zone=public
#設定確認
firewall-cmd --permanent --list-services --zone=public
#設定反映
firewall-cmd --reload

2. 準同期レプリケーションプラグインのインストール

mysqlfailoverなどでスレーブのマスター昇格がある環境の場合、マスター用、スレーブ用双方導入してください。

マスター

mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';

スレーブ

mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';

3. レプリケーション用ユーザの作成

マスター昇格がある場合、スレーブにも設定が必要です。IPアドレスやパスワードなどは適宜変更してください。

マスター

mysql> create user repl@'192.168.1.%' identified by '*******';
mysql> grant replication slave on *.* to repl@'192.168.1.%';

4. オプションファイル(/etc/my.cnf)の編集

オプションファイル(/etc/my.cnf)の最後尾に以下を追加します。
関連する主要なオプション(パラメータ)については、手順の後で説明します。

マスター

1行目と23行目はレプリケーションの動作と関係ありませんが確認しやすい様に設定しています。

log_timestamps = SYSTEM                 # ログ出力のタイムゾーンをOS設定準拠

log_bin=mysql-bin
log_slave_updates = TRUE

## Replication
server_id = 1                           # Server毎に一意
report-host = DB01                      # Server毎に一意
report-port = 3306
gtid_mode = ON
enforce_gtid_consistency = ON

## Master
rpl_semi_sync_master_enabled = 1        # 準同期レプリケーションを有効にする(Masterのみ)
master-info-repository = TABLE

## Slave
#rpl_semi_sync_slave_enabled = 1        # 準同期レプリケーションを有効にする(Slaveのみ)
relay_log_recovery = TRUE
relay_log_info_repository = TABLE

[mysql]
show-warnings                           # Warningを即時表示

スレーブ

サーバー毎に一意にするオプションは適宜設定値を変更してください。
1行目と23行目はレプリケーションの動作と関係ありませんが確認しやすい様に設定しています。

log_timestamps = SYSTEM                 # ログ出力のタイムゾーンをOS設定準拠

log_bin=mysql-bin
log_slave_updates = TRUE

## Replication
server_id = 2                           # Server毎に一意
report-host = DB02                      # Server毎に一意
report-port = 3306
gtid_mode = ON
enforce_gtid_consistency = ON

## Master
#rpl_semi_sync_master_enabled = 1       # 準同期レプリケーションを有効にする(Masterのみ)
master-info-repository = TABLE

## Slave
rpl_semi_sync_slave_enabled = 1         # 準同期レプリケーションを有効にする(Slaveのみ)
relay_log_recovery = TRUE
relay_log_info_repository = TABLE

[mysql]
show-warnings                           # Warningを即時表示

5. MySQLサーバーの再起動

全サーバーでMySQLサーバーを再起動します。

systemctl restart mysqld.service

6. レプリケーションの開始

スレーブ

スレーブの全サーバで以下を実行します。

mysql> CHANGE MASTER TO
 MASTER_HOST = '192.168.1.**',
 MASTER_PORT = 3306,
 MASTER_AUTO_POSITION = 1;

mysql>START SLAVE USER='repl' PASSWORD='*********';

7. レプリケーションの確認

スレーブ

-- スレーブステータスの確認
mysql> SHOW SLAVE STATUS\G

以下の2項目がYesとなることを確認します。

mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
(中略)
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
(中略)
1 row in set (0.00 sec)

マスター

mysql> SHOW MASTER STATUS\G

設定したスレーブが表示されることを確認します。

mysql> SHOW SLAVE HOSTS;
+-----------+------+------+-----------+--------------------------------------+
| Server_id | Host | Port | Master_id | Slave_UUID                           |
+-----------+------+------+-----------+--------------------------------------+
|         2 | DB02 | 3306 |         1 | ********-****-****-****-************ |
+-----------+------+------+-----------+--------------------------------------+
1 row in set (0.00 sec)

レプリケーション、バイナリログ関連のオプション(サーバーシステム変数)

上の手順では暗黙のデフォルトで問題ないオプションは特に設定していませんが、大事なものは下表にまとめます。

サーバーシステム変数の詳細は以下のリンク先(公式マニュアル)をご覧ください。
https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html

オプション(システム変数)名 暗黙のデフォルト値 本手順設定値 説明
sync_binlog 1 1 クラッシュセーフなバイナリログ同期
expire_logs_days 0(無期限) 0 バイナリログの保持期間[単位:日]
log_slave_updates FALSE TRUE スレーブでレプリケーション起因の更新もバイナリログ出力する。マスター昇格の可能性のあるスレーブはTRUE必須。
server_id 0 サーバー毎 サーバー毎に一意な整数を設定
report-host サーバー毎 サーバー毎に一意な文字列。SHOWコマンドやMySQL Utilitiesで表示に使うホスト名、mysqlfailover使用時は設定必須。
report-port 3306 mysqlfailover使用時は設定必須
gtid_mode OFF ON GTIDの有効/無効、mysqlfailover使用時はON必須
enforce_gtid_consistency OFF ON GTIDの一貫性を担保できないSQLの発行を禁止
rpl_semi_sync_master_enabled 0(OFF) 1(ON) 準同期レプリケーションのマスターとしての動作を有効化
rpl_semi_sync_master_timeout 10000(10秒) 10000 スレーブからの応答のタイムアウト値[単位:ミリ秒]、超過した場合非同期レプリケーションでの動作に切り替える。
rpl_semi_sync_master_wait_for_slave_count 1 1 マスターのコミット時に応答を待つスレーブの台数
rpl_semi_sync_master_wait_point AFTER_SYNC AFTER_SYNC AFTER_SYNCにすることでロスレス準同期レプリケーションとして動作
master-info-repository FILE TABLE マスター情報リポジトリの格納先。mysqlfailover使用時はTABLEが必須。
rpl_semi_sync_slave_enabled 0(OFF) 1(ON) 準同期レプリケーションのスレーブとしての動作の有効化
relay_log_recovery FALSE TRUE MySQLサーバ起動時にリレーログとリレーログリポジトリを比較し、未適用のリレーログがあれば破棄する。クラッシュセーフスレーブはTRUE必須。
relay_log_purge TRUE TRUE 不要なリレーログを破棄する。クラッシュセーフスレーブではTRUE必須。
relay_log_info_repository FILE TABLE リレーログ情報リポジトリの格納先。TABLEの場合、トランザクションでデータの整合性が保証される。クラッシュセーフスレーブではTABLEが必須。