MySQL5.7 group replication 異ノード編と注意事項

ローカルホストで3インスタンス構築する資料
http://dev.mysql.com/doc/refman/5.7/en/group-replication.html
が一番わかりやすいので
それをベースに1ノード1インスタンスで3ノードで組んでみました
**このURLの補足資料だと思って下さい**

#まず前提条件
1. MySQL5.7.17をインストール(group replicationは5.7独自の機能を使用してます)
2. グループレプリケーション用のポートを決めます(推奨ポートは33061らしい、net.ipv4.ip_local_port_rangeとは被らないのが理想)
3. FWは無効にしましょう
4. SELinuxは必要ないなら切りましょう
5. 各サーバのホストを名前解決できること
6. 各DBのテーブルにプライマリーキーないしはユニークキーが存在すること
7. GTID互換でないSQLをなくす

#コンフィグ
動作確認用にかなり絞ったコンフィグです。
起動時に設定していないと起動できなくなる設定も入れてます
・server_id
・loose-group_replication_local_address
・loose-group_replication_group_seeds
はホストごとに変更してください

```[client]
socket                  = /var/lib/mysql/mysqld.sock

[mysqld]
log_error               = /var/log/mysql/mysqld.log
log_bin                 = /var/lib/mysql/mysql-bin  #required
relay-log               = /var/lib/mysql/mysqld-relay-bin　　#required

# server configuration
datadir=/var/lib/mysql
basedir=/usr
user=mysql

port=3306
socket=/var/lib/mysql/mysqld.sock

innodb_log_file_size            = 128M
innodb_data_file_path           = ibdata1:10M:autoextend

server_id=98                  #required. namber freedom
gtid_mode=ON                  #required
enforce_gtid_consistency=ON   #required
master_info_repository=TABLE  #required
relay_log_info_repository=TABLE   #required
binlog_checksum=NONE          #required
log_slave_updates=ON          #required
binlog_format=ROW             #required
binlog-row-image = MINIMAL    #recommendation
innodb_undo_tablespaces = 2
log-timestamps = system       #5.7 recommendation

transaction_write_set_extraction=XXHASH64     #required
loose-group_replication_group_name=550fa9ee-a1f8-4b6d-9bfe-c03c12cd1c72   #required. name freedom
loose-group_replication_start_on_boot=off
loose-group_replication_local_address= "192.168.101.98:33061"      #required
loose-group_replication_group_seeds= "192.168.101.100:33061,192.168.101.99:33061"  #recommendation?
loose-group_replication_bootstrap_group= off  #required. group replication setup after
#loose-group_replication_ip_whitelist = 192.168.101.0/24  #NN I/F multiple recommendation
loose-group_replication_single_primary_mode= on
```

group_replication_single_primary_mode= off
でマルチマスターにする場合は
group_replication_enforce_update_everywhere_checks = ONが必須
transaction-isolation = READ-COMMITTED
が推奨されます。

#1台目
##MySQL初期化、起動
mysqld --initialize-insecure
/etc/init.d/mysql startなどで起動
mysql -uroot

mysqld --initializeでもいいですがrootパスワード設定が必要になります

```
cat /var/log/mysql/mysqld.log  | grep -i pass`
mysql -uroot -p
SET SQL_LOG_BIN=0;
set password for root@localhost=password('パスワード');
SET SQL_LOG_BIN=1;
```

##グループレプリケーションの準備

```
SET SQL_LOG_BIN=0;
CREATE USER rpl_user@'%';
GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%' IDENTIFIED BY 'rpl_pass';
FLUSH PRIVILEGES;
SET SQL_LOG_BIN=1;
CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='rpl_pass'
FOR CHANNEL 'group_replication_recovery';
INSTALL PLUGIN group_replication SONAME 'group_replication.so';
SHOW PLUGINS;
```

##グループレプリケーション1台目稼働
ここまでは一番上の参考資料通りに進むはずです。
**MEMBER_HOSTの名前解決が互いに出来ないとこけます。
MySQL起動時のホスト名を使用？**

```
SET GLOBAL group_replication_bootstrap_group=ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group=OFF;
SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+---------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE  |
+---------------------------+--------------------------------------+-------------+-------------+---------------+
| group_replication_applier | 395409e1-6dfa-11e6-970b-00212844f856 | hoge1       |       33061 | ONLINE        |
+---------------------------+--------------------------------------+-------------+-------------+---------------+
```

##テスト用のクエリ投入

```
CREATE DATABASE test;
use test
CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL);
INSERT INTO t1 VALUES (1, 'Luis');
SELECT * FROM t1;
SHOW BINLOG EVENTS;
```

SHOW BINLOG EVENTS;の結果ですが異なるホストだと数行しか出力されません。
参照URLと結果が異なりますが気にしなくて構いません

#2台目以降
##名前解決できることの確認
```
(2台目から)ping 1台目のホスト
(1台目から)ping 2台目のホスト
```

##MySQL初期化、起動
mysqld --initialize-insecure
mysql -uroot

##グループレプリケーションの準備

```
SET SQL_LOG_BIN=0;
CREATE USER rpl_user@'%';
GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%' IDENTIFIED BY 'rpl_pass';
FLUSH PRIVILEGES;
SET SQL_LOG_BIN=1;
CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='rpl_pass'
FOR CHANNEL 'group_replication_recovery';
INSTALL PLUGIN group_replication SONAME 'group_replication.so';
SHOW PLUGINS;
```

##グループレプリケーション2台目稼働
**当然一番エラーが多い場所**

FWでポートが塞がれている、お互いに名前解決できないというのが一番多いミスでしょう
MEMBER_STATEが数クエリなのにRECOVERINGが出てしまうのは失敗なので原因を調査しましょう

```
START GROUP_REPLICATION;
SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+---------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE  |
+---------------------------+--------------------------------------+-------------+-------------+---------------+
| group_replication_applier | 395409e1-6dfa-11e6-970b-00212844f856 | hoge1       |       33061 | ONLINE        |
| group_replication_applier | 7eb217ff-6df3-11e6-966c-00212844f856 | hoge2       |       33061 | ONLINE        |
+---------------------------+--------------------------------------+-------------+-------------+---------------+
3 rows in set (0,00 sec)
```

##クエリ同期を確認

```
SHOW DATABASES LIKE 'test';
SELECT * FROM test.t1;
```
##1台目のみがMasterになっていることの確認

```
(2台目以降) SHOW GLOBAL VARIABLES LIKE '%super_read_only';
```



以上。
2/1のMySQL Casualに間に合わせないと