Edited at

docker-composeで手軽にgroup replicationの試験環境構築をしてみる

More than 1 year has passed since last update.

この記事はMySQL Casual Advent Calendar 2017の22日目です。


はじめに

huatoです。

MySQ 5.6のサポート期限が見えてきたので最近はMySQL5.7の動作試験を進めてます。

Group Replicationの検証目的で複数インスタンス立ち上げるのが面倒だったのでdocker-composeで手軽に

試験環境を構築してみました。

なおGroup Replication自体の説明はいろいろな方が記事を書かれているので除外してます。


docker周りの設定

https://docs.docker.com/engine/installation/linux/docker-ce/centos/#install-docker-ce-1

CentOS7.3をインストールしてdocker動作に必要な設定をぽちぽちとすすめます。

ubuntuの環境インストール方法などもマニュアルが用意されてます。

yum install -y yum-utils device-mapper-persistent-data lvm2

yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

yum-config-manager --disable docker-ce-edge
yum makecache fast

yum install docker-ce

cd /etc/

mkdir -p docker
vi daemon.json


{
"storage-driver": "devicemapper"
}

{
"dns": ["8.8.8.8", "8.8.4.4"]
}

dockerサービス起動

service docker restart


docker-compose

dockerコマンドでインスタンスごとに立ち上げていくこともできますが

複数環境を構築・管理するのであればdocker-composeが便利です。

https://docs.docker.com/compose/install/#install-compose

1ライナーでインストール自体は終わります。

sudo curl -L https://github.com/docker/compose/releases/download/1.17.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

chmod 755 /usr/local/bin/docker-compose

各設定ファイルを配置する場所を作成します。

cd /root/

mkdir compose

構成管理に必要となるdocker-compose.ymlを用意します。

公式イメージを使うとパスワード設定方法などの考慮をしなくてよいので楽です。

設定はreference manualを元にしています。

https://dev.mysql.com/doc/refman/5.7/en/group-replication-configuring-instances.html

性能試験に関しては考慮していないためGroup Replication動作に必要となる最低限の設定のみです。

docker-compose.yml

version: '2'

services:
node1:
restart: always
image: mysql:5.7
networks:
db:
ipv4_address: 192.168.2.1
expose:
- "6606"
volumes:
- /data/mysql1:/var/lib/mysql
- $PWD/node1.cnf:/etc/my.cnf
privileged: true
extra_hosts:
- "node1:192.168.2.1"
- "node2:192.168.2.2"
- "node3:192.168.2.3"
env_file: pass.env

node2:
restart: always
image: mysql:5.7
networks:
db:
ipv4_address: 192.168.2.2
expose:
- "6606"
volumes:
- /data/mysql2:/var/lib/mysql
- $PWD/node2.cnf:/etc/my.cnf
privileged: true
extra_hosts:
- "node1:192.168.2.1"
- "node2:192.168.2.2"
- "node3:192.168.2.3"
env_file: pass.env

node3:
restart: always
image: mysql:5.7
networks:
db:
ipv4_address: 192.168.2.3
expose:
- "6606"
volumes:
- /data/mysql3:/var/lib/mysql
- $PWD/node3.cnf:/etc/my.cnf
privileged: true
extra_hosts:
- "node1:192.168.2.1"
- "node2:192.168.2.2"
- "node3:192.168.2.3"
env_file: pass.env

node5:
restart: always
image: mysql:5.7
networks:
db:
ipv4_address: 192.168.2.5
volumes:
- /data/mysql5:/var/lib/mysql
- $PWD/node5.cnf:/etc/my.cnf
privileged: true
extra_hosts:
- "node1:192.168.2.1"
- "node2:192.168.2.2"
- "node3:192.168.2.3"
env_file: pass.env

networks:
db:
ipam:
config:
- subnet: 192.168.0.0/22

pass.env

MYSQL_RANDOM_ROOT_PASSWORD=yes

各ノードごとにmy.cnfを用意します。

node1.cnf

[mysqld]

server_id=1
gtid_mode=ON
enforce_gtid_consistency=ON
binlog_checksum=NONE
log_slave_updates=ON
log-bin
binlog_format=ROW
binlog_error_action=IGNORE_ERROR
binlog_rows_query_log_events
binlog_row_image=minimal
character-set-server=utf8mb4
master_info_repository=TABLE
relay_log_info_repository=TABLE
innodb_buffer_pool_dump_at_shutdown=ON
innodb_buffer_pool_load_at_startup=OFF
innodb_strict_mode=0
innodb_checksum_algorithm=innodb
innodb_flush_method=O_DIRECT
log_timestamps=SYSTEM
log_error=/var/lib/mysql/mysql.err
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
loose-group_replication_start_on_boot=off
loose-group_replication_auto_increment_increment=1
loose-group_replication_local_address="192.168.2.1:6606"
loose-group_replication_group_seeds= "192.168.2.1:6606,192.168.2.2:6606,192.168.2.3:6606"
loose-group_replication_ip_whitelist="192.168.2.1,192.168.2.2,192.168.2.3,127.0.0.1"
loose-group_replication_bootstrap_group=off

node2.cnf,node3.cnfはnode1.cnfをコピー後

server_idの値の変更とloose-group_replication_local_addressを自身のIPに書き換えます。

my.cnfに明示的に記載していませんがauto_increment_offsetの値はgroup replication開始時にserver-idで上書きされていました。

回避策は現時点で無さそうですのでアプリケーションでauto_incrementを使っている場合は気にしたほうが良いかと。

参考:https://mysqlhighavailability.com/mysql-group-replication-auto-increment-configuration-handling/

起動

/usr/local/bin/docker-compose up -d

-dはバックグラウンド起動に必要となるオプションです。

各環境にログインします。

docker ps -a コマンドでインスタンスのNAMESを確認しましょう

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES

ba96f05116fa mysql:5.7 "docker-entrypoint..." 8 hours ago Up 8 hours 3306/tcp compose_node5_1
4eeef5032e12 mysql:5.7 "docker-entrypoint..." 8 hours ago Up 8 hours 3306/tcp, 6606/tcp compose_node3_1
c97ea26cc3a2 mysql:5.7 "docker-entrypoint..." 8 hours ago Up 8 hours 3306/tcp, 6606/tcp compose_node2_1
dd8c636252cb mysql:5.7 "docker-entrypoint..." 8 hours ago Up 8 hours 3306/tcp, 6606/tcp compose_node1_1

docker exec -it NAMES /bin/bash で各環境にログインできます。

デタッチはCtrl+p+qです。

Ctrl+Cすると環境が停止されますので気をつけてください。

各環境ごとに実行するクエリが異なります。

mysqlのログイン時のrootパスワードはランダム生成のためログから確認します。

docker-compose logs | grep PASS

node2_1  | GENERATED ROOT PASSWORD: caid0aochifaeshoo5zaizooYai0kaet

node3_1 | GENERATED ROOT PASSWORD: Phahbahzoz6gee2ied0Gii9eihei9xif
node1_1 | GENERATED ROOT PASSWORD: shoa2ohChoh6eicheiBohyooxe2ooJei
node5_1 | GENERATED ROOT PASSWORD: zi9neeng1mue8ni3Oongiu2Pee4yaech

ログイン

mysql -uroot -p

【node1】

reset master;

SET SQL_LOG_BIN=0;
CREATE USER 'rpl_user'@'%';
GRANT REPLICATION SLAVE ON *.* TO 'rpl_user'@'%' IDENTIFIED BY 'dummy2';
FLUSH PRIVILEGES;
CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='dummy2' FOR CHANNEL 'group_replication_recovery';
INSTALL PLUGIN group_replication SONAME 'group_replication.so';
SET SQL_LOG_BIN=1;
SET GLOBAL group_replication_bootstrap_group=ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group=OFF;

【node2,node3】

reset master;

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

5.7.19以前のMySQLバージョンから起動した場合、Group Replication起動時にエラーで失敗することがあります。

起動に失敗した場合はmysql_upgradeを実施することで解消されました。

mysql_upgrade -uroot -p

3インスタンスでの作業が終わったらマスターがどの環境になっているか確認してみます。

SHOW SLAVE STATUSでは確認できないためperformance_schemaの値を参照します。

select * from performance_schema.replication_group_members;

+---------------------------+--------------------------------------+--------------+-------------+--------------+

| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+--------------+-------------+--------------+
| group_replication_applier | d33b4161-d016-11e7-a59f-0242c0a80203 | 4eeef5032e12 | 3306 | ONLINE |
| group_replication_applier | d3dabd9c-d016-11e7-a6db-0242c0a80201 | dd8c636252cb | 3306 | ONLINE |
| group_replication_applier | d4c00f25-d016-11e7-a50d-0242c0a80202 | c97ea26cc3a2 | 3306 | ONLINE |
+---------------------------+--------------------------------------+--------------+-------------+--------------+
3 rows in set (0.00 sec)

select member_host from performance_schema.global_status inner join performance_schema.replication_group_members where variable_name='group_replication_primary_member' AND member_id=variable_value;

+--------------+

| member_host |
+--------------+
| dd8c636252cb |
+--------------+
1 row in set (0.00 sec)

最後にgroup replicationの構成をくみ上げたら各環境のmy.cnfを書き換えてください。

この設定を修正しないとサーバ再起動時にgroup replicationの設定が反映されずレプリケーショングループに自動的に戻りません。

loose-group_replication_start_on_boot=off

=>
group_replication_start_on_boot=on

Group Replicationが最大9インスタンスまでという制限があるため

Group Replicationの管理対象外のスレーブをGroup Replicationのマスターにぶら下げる場合についても書いておきます。

node5.cnf

[mysqld]

server_id=1
gtid_mode=ON
enforce_gtid_consistency=ON
binlog_checksum=NONE
log_slave_updates=ON
log-bin
binlog_format=ROW
binlog_error_action=IGNORE_ERROR
log_error=/var/lib/mysql/mysql.err
binlog_rows_query_log_events
binlog_row_image=minimal
character-set-server=utf8mb4
master_info_repository=TABLE
relay_log_info_repository=TABLE
innodb_buffer_pool_dump_at_shutdown=ON
innodb_buffer_pool_load_at_startup=OFF
innodb_strict_mode=0
innodb_checksum_algorithm=innodb
innodb_flush_method=O_DIRECT
log_timestamps=SYSTEM

【node5】

reset master;

CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='dummy2',MASTER_AUTO_POSITION = 1,MASTER_HOST='192.168.2.1';
START SLAVE;

通常のGTIDレプリケーションとして動作します。

mysql> show slave status\G;

*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.2.1
Master_User: rpl_user
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: dd8c636252cb-bin.000001
Read_Master_Log_Pos: 1082
Relay_Log_File: ba96f05116fa-relay-bin.000002
Relay_Log_Pos: 1301
Relay_Master_Log_File: dd8c636252cb-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 1082
Relay_Log_Space: 1507
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_UUID: d3dabd9c-d016-11e7-a6db-0242c0a80201
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set: aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee:1-3
Executed_Gtid_Set: aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee:1-3
Auto_Position: 1
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)

ERROR:
No query specified

docker-composeでのGroup Replication試験環境についての説明はこれで以上ですが

Group ReplicationだけではDB運用には不十分でアプリケーションからの接続をmysql routerやProxySQL等で管理しないといけません。

機会があればそちらも記事にしたいと思います。


参考にさせていただいた記事

http://datacharmer.blogspot.jp/2017/01/mysql-group-replication-installation.html

https://dev.mysql.com/doc/refman/5.7/en/group-replication-launching.html