MySQLには、5.7.17からGroup Replicationという機能が追加されています。
Changes in MySQL 5.7.17 (2016-12-12, General Availability)
5.7系のGAリリース後に追加された機能だったはずですが、そのまま試さずに8.0まできてしまったので、ここで1回
触ってみておこうかなぁと思いまして。
Group Replicationとは?
先に書いたように、MySQL 5.7.17で追加された新機能です。
参考)
MySQL Group Replication - MySQL Casual Talk vol.10
OSC 2017 Okinawa MySQL の高可用性構成比較 と新機能 Group Replication
mita2 DB メモ: Group Replication を試す(1) 導入編
ざっくり言うと、こんな感じのものみたいです。
- MySQLでの高可用性ソリューション
- ※性能向上は目的ではない
- 自動リカバリ
- 障害Nodeの切り離しと復旧時のリカバリ
- Nodeの追加、削除が可能
- 更新可能なNodeをひとつにすることも、複数にすることも可能(マルチマスター)
InnoDB Clusterの基盤にもなっており、ちょっと気になっていた機能なのです。
Group Replicationの要求事項は、こちらを参照。
Group Replication Requirements
あとは、バイナリログやGTIDなどについてが書かれています。
制限事項やよくある質問は、こちらを参照。
ロックに関する注意事項や、Group Replicationは最大9 Nodeであることが書かれていたりします。
とりあえず今回は、環境を構成して軽く動かしてみることを目標にしてみます。
環境
確認環境は、次の通り。
- Ubuntu Linux 18.04 LTS
- MySQL 8.0.11(Docker上で動かす)
MySQLは、APT Repositoryから、インストールしたものを使用しています。
Group Replicationは、全部で3 NodeのMySQLを使って構成することとしましょう。
Group Replication構成
ドキュメントに沿って設定、手順を踏んでいくと、だいたいOKです。
Deploying Group Replication in Single-Primary Mode
だいたい、と書いたのは、まあハマったこともあるわけですが…。
ドキュメントはSingle Primary Mode(更新可能なNodeがひとつだけ)で書かれていますが、マルチマスターは設定をひとつ変えることで実現できます。
というわけで、まずはSingle Primary Modeで構成してみます。
マルチマスター(Multi Primary Mode)については、また後で。
手順は、最初に起動するNodeと、あとからGroup Replicationに参加するNodeで異なります。
今回は3 Nodeなので、次のようなNode構成でいきます。
- 初期Node … 172.17.0.2
- 追加Node 2つ … 172.17.0.2〜3
初期Node
では、まずは最初に起動するNodeから見ていきましょう。
参照するドキュメントは、以下になります。
Configuring an Instance for Group Replication
Group Replicationを構成するのに、最低限必要な情報は以下です(report-host除く)。
## gtid gtid_mode = on enforce_gtid_consistency = on ## binary log binlog_checksum=NONE ## replication server_id = 1 ## group replication transaction_write_set_extraction = XXHASH64 loose-group_replication_group_name = "5f0e506a-58f3-4256-ba8b-78101b3b3b39" loose-group_replication_start_on_boot = off loose-group_replication_local_address = "172.17.0.2:24901" loose-group_replication_group_seeds = "172.17.0.2:24901" loose-group_replication_bootstrap_group = off report-host = "172.17.0.2"
以下の設定も必要なのですが、MySQL 8.0.3以降はデフォルト値となっているそうな。
log_bin=binlog log_slave_updates=ON binlog_format=ROW master_info_repository=TABLE relay_log_info_repository=TABLE
いくつかの設定項目に「loose-」というprefixが付与されていますが、これはGroup Replicationのプラグインがロードされていなくても、エラーにならず起動するための
ものです。
The loose- prefix used for the group_replication variables above instructs the server to continue to start if the Group Replication plugin has not been loaded at the time the server is started.
https://dev.mysql.com/doc/refman/8.0/en/group-replication-configuring-instances.html
Group Replication関連の設定は、こちらを参照。
Group Replication System Variables
「group_replication_group_name」は、UUIDで設定する必要があります。今回は、uuidgenコマンドで作ったものを使用しました。この値は、Group Replicatonを
構成するNodeで同じにしておく必要があります。
loose-group_replication_group_name = "5f0e506a-58f3-4256-ba8b-78101b3b3b39"
「group_replication_start_on_boot」はサーバーの起動時にGroup Replicationのプラグインが自動的にレプリケーションを開始するかどうかなのですが、
これは今回は「off」にしています。最初にGroup Replicationの設定をする際には、offにしておく必要があるからです。
loose-group_replication_start_on_boot = off
Group Replicationの設定が済んでいれば、「group_replication_start_on_boot」をonにしておくと自動的にGroup Replicationが開始されます。
「group_replication_local_address」では、Group Replicationが使うアドレスとポートを指定します。ここでのアドレス/ポートの組み合わせは、
SQLアクセスと異なるもの(ポートは通例、3306)以外に設定する必要があります。
loose-group_replication_local_address = "172.17.0.2:24901"
「group_replication_group_seeds」では、Group Replicationのシードなるアドレス/ポートのペアを、「,」区切りで設定します。今回は最初のNode分なので、
自分自身のみにしておきました…。
loose-group_replication_group_seeds = "172.17.0.2:24901"
この設定は起動後にテーブルで管理され、Nodeの追加、削除に合わせて変えられていくので、あくまでGroup Replicationの初期Nodeです。
「group_replication_bootstrap_group」は、Groupの起動有無を設定します。
loose-group_replication_bootstrap_group = off
なんのこと?的な感じですが、Group Replicationのグループ自体を作る時や、Groupに参加しているNodeを全部停止してバックアップを取る時などに使うものの
ようです。Groupを起動するということはGroupを作るということであり、これを複数回実行すると、同じ名前の異なるGroupが複数個できてしまう、という
状態になるようです。
なので、最初の1 Nodeの時に有効化しておき、Groupが起動したらoffにします。この操作は、Group Replication構成時に行います。
「report-host」というのは、必須設定ではありません。performance_schema.replication_group_membersというテーブルでGroup Replicationに参加している
メンバーを確認する際に、デフォルトではホスト名なのですが、これを変更したい場合に使います。
report-host = "172.17.0.2"
今回は、ホスト名がうまく解決できない環境なので、IPアドレスを明示することとしました。
この状態で、MySQLを起動しておきます。
これで、ドキュメントのここまで来たことになります。
Configuring an Instance for Group Replication
続いて、こちら。
レプリケーション用のユーザーを作成。レプリケーション用のユーザーは「rpl_user」、パスワードは「password」とします。
mysql> SET SQL_LOG_BIN=0; Query OK, 0 rows affected (0.01 sec) mysql> CREATE USER rpl_user@'%' IDENTIFIED BY 'password'; Query OK, 0 rows affected (0.54 sec) mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%'; Query OK, 0 rows affected (0.12 sec) mysql> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.00 sec) mysql> SET SQL_LOG_BIN=1; Query OK, 0 rows affected (0.00 sec)
CHANGE MASTER。
mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='password' FOR CHANNEL 'group_replication_recovery'; Query OK, 0 rows affected, 2 warnings (0.28 sec) Note (Code 1759): Sending passwords in plain text without SSL/TLS is extremely insecure. Note (Code 1760): Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
SSL/TLSを有効にしていないので、ちょっと怒られてますが…ここは、そのままで。
Group Replicationの開始へ。
プラグインのロード。
mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so'; Query OK, 0 rows affected (0.17 sec)
SHOW PLUGINSで、「group_replication」が追加されていることを確認します。
mysql> SHOW PLUGINS; +----------------------------+----------+--------------------+----------------------+---------+ | Name | Status | Type | Library | License | +----------------------------+----------+--------------------+----------------------+---------+ | binlog | ACTIVE | STORAGE ENGINE | NULL | GPL | | mysql_native_password | ACTIVE | AUTHENTICATION | NULL | GPL | | sha256_password | ACTIVE | AUTHENTICATION | NULL | GPL | | caching_sha2_password | ACTIVE | AUTHENTICATION | NULL | GPL | | sha2_cache_cleaner | ACTIVE | AUDIT | NULL | GPL | | CSV | ACTIVE | STORAGE ENGINE | NULL | GPL | | MEMORY | ACTIVE | STORAGE ENGINE | NULL | GPL | | InnoDB | ACTIVE | STORAGE ENGINE | NULL | GPL | | INNODB_TRX | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_CMP | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_CMP_RESET | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_CMPMEM | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_CMPMEM_RESET | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_CMP_PER_INDEX | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_CMP_PER_INDEX_RESET | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_BUFFER_PAGE | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_BUFFER_PAGE_LRU | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_BUFFER_POOL_STATS | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_TEMP_TABLE_INFO | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_METRICS | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_FT_DEFAULT_STOPWORD | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_FT_DELETED | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_FT_BEING_DELETED | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_FT_CONFIG | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_FT_INDEX_CACHE | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_FT_INDEX_TABLE | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_TABLES | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_TABLESTATS | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_INDEXES | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_TABLESPACES | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_COLUMNS | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_VIRTUAL | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | INNODB_CACHED_INDEXES | ACTIVE | INFORMATION SCHEMA | NULL | GPL | | MyISAM | ACTIVE | STORAGE ENGINE | NULL | GPL | | MRG_MYISAM | ACTIVE | STORAGE ENGINE | NULL | GPL | | PERFORMANCE_SCHEMA | ACTIVE | STORAGE ENGINE | NULL | GPL | | TempTable | ACTIVE | STORAGE ENGINE | NULL | GPL | | ARCHIVE | ACTIVE | STORAGE ENGINE | NULL | GPL | | BLACKHOLE | ACTIVE | STORAGE ENGINE | NULL | GPL | | FEDERATED | DISABLED | STORAGE ENGINE | NULL | GPL | | ngram | ACTIVE | FTPARSER | NULL | GPL | | mysqlx | ACTIVE | DAEMON | NULL | GPL | | mysqlx_cache_cleaner | ACTIVE | AUDIT | NULL | GPL | | auth_socket | ACTIVE | AUTHENTICATION | auth_socket.so | GPL | | group_replication | ACTIVE | GROUP REPLICATION | group_replication.so | GPL | +----------------------------+----------+--------------------+----------------------+---------+ 45 rows in set (0.00 sec)
Group Replicationの開始。
mysql> SET GLOBAL group_replication_bootstrap_group=ON; Query OK, 0 rows affected (0.00 sec) mysql> START GROUP_REPLICATION; Query OK, 0 rows affected (3.33 sec) mysql> SET GLOBAL group_replication_bootstrap_group=OFF; Query OK, 0 rows affected (0.00 sec)
「group_replication_bootstrap_group」は最初に「ON」にして、「START GROUP_REPLICATION」後はすぐ「OFF」にします。
現在のGroup Replication参加Nodeを確認。
mysql> SELECT * FROM performance_schema.replication_group_members; +---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | +---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+ | group_replication_applier | c1cfe8f2-8737-11e8-b092-0242ac110002 | 172.17.0.2 | 3306 | ONLINE | PRIMARY | 8.0.11 | +---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+ 1 row in set (0.00 sec)
これで、Group Replicationが開始されました。
あとは、Nodeを足していけばいいのですが…なぜか、Group Replication用のユーザーで1度ログインしないと、この後のNode追加時に、追加されたNode側が
うまくGroup Replicationに参加できませんでした(「MEMBER_STATE」が「ONLINE」にならず、「RECOVERING」のまま進まない)。
追加Node
続いて、起動したGroup Replicationに対して、Nodeを追加していってみます。
参照するドキュメントは、以下になります。
追加するNode、ひとつめ。
## gtid gtid_mode = on enforce_gtid_consistency = on ## binary log binlog_checksum=NONE ## replication server_id = 2 ## group replication transaction_write_set_extraction = XXHASH64 loose-group_replication_group_name = "5f0e506a-58f3-4256-ba8b-78101b3b3b39" loose-group_replication_start_on_boot = off loose-group_replication_local_address = "172.17.0.3:24901" loose-group_replication_group_seeds = "172.17.0.2:24901,172.17.0.3:24901,172.17.0.4:24901" loose-group_replication_bootstrap_group = off report-host = "172.17.0.3"
2つ目。
## gtid gtid_mode = on enforce_gtid_consistency = on ## binary log binlog_checksum=NONE ## replication server_id = 3 ## group replication transaction_write_set_extraction = XXHASH64 loose-group_replication_group_name = "5f0e506a-58f3-4256-ba8b-78101b3b3b39" loose-group_replication_start_on_boot = off loose-group_replication_local_address = "172.17.0.4:24901" loose-group_replication_group_seeds = "172.17.0.2:24901,172.17.0.3:24901,172.17.0.4:24901" loose-group_replication_bootstrap_group = off report-host = "172.17.0.4"
違いは、server_id、それから「loose-group_replication_local_address」と「report-host」。
loose-group_replication_local_address = "172.17.0.3:24901" report-host = "172.17.0.3" loose-group_replication_local_address = "172.17.0.4:24901" report-host = "172.17.0.4"
「loose-group_replication_group_seeds」については、同じにしました。
loose-group_replication_group_seeds = "172.17.0.2:24901,172.17.0.3:24901,172.17.0.4:24901"
レプリケーション用のユーザー、「rpl_user」の作成から、CHANGE MASTERまで。
mysql> SET SQL_LOG_BIN=0; Query OK, 0 rows affected (0.00 sec) mysql> CREATE USER rpl_user@'%' IDENTIFIED BY 'password'; Query OK, 0 rows affected (0.06 sec) mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%'; Query OK, 0 rows affected (0.02 sec) mysql> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.00 sec) mysql> SET SQL_LOG_BIN=1; Query OK, 0 rows affected (0.00 sec) mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='password' FOR CHANNEL 'group_replication_recovery'; Query OK, 0 rows affected, 2 warnings (0.19 sec) Note (Code 1759): Sending passwords in plain text without SSL/TLS is extremely insecure. Note (Code 1760): Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
プラグインのロードと、Group Replicationの開始。
mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so'; Query OK, 0 rows affected (0.10 sec) mysql> START GROUP_REPLICATION; Query OK, 0 rows affected (4.26 sec)
ひとつ、Nodeを追加後。
mysql> SELECT * FROM performance_schema.replication_group_members; +---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | +---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+ | group_replication_applier | a3f74d6a-8c27-11e8-ac1c-0242ac110003 | 172.17.0.3 | 3306 | ONLINE | SECONDARY | 8.0.11 | | group_replication_applier | c1cfe8f2-8737-11e8-b092-0242ac110002 | 172.17.0.2 | 3306 | ONLINE | PRIMARY | 8.0.11 | +---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+ 2 rows in set (0.00 sec)
2つ目のNodeを追加後。
mysql> SELECT * FROM performance_schema.replication_group_members; +---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | +---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+ | group_replication_applier | a3f74d6a-8c27-11e8-ac1c-0242ac110003 | 172.17.0.3 | 3306 | ONLINE | SECONDARY | 8.0.11 | | group_replication_applier | a5f1669f-8c27-11e8-8910-0242ac110004 | 172.17.0.4 | 3306 | ONLINE | SECONDARY | 8.0.11 | | group_replication_applier | c1cfe8f2-8737-11e8-b092-0242ac110002 | 172.17.0.2 | 3306 | ONLINE | PRIMARY | 8.0.11 | +---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+ 3 rows in set (0.00 sec)
3 NodeでのGroup Replicationとなりました。
Single Primary Modeなので、「MEMBER_ROLE」がひとつだけPRIMARY(最初のNode)で、それ以外は「SECONDARY」ですね。
確認
こちらに沿って、Group Replicationが構成されていることを確認してみましょう。
Primary Nodeで。
mysql> CREATE DATABASE test; Query OK, 1 row affected (0.03 sec) mysql> USE test; Database changed mysql> CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL); Query OK, 0 rows affected (0.25 sec) mysql> INSERT INTO t1 VALUES (1, 'Luis'); Query OK, 1 row affected (0.06 sec)
追加されたNodeで確認。
mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | | test | +--------------------+ 5 rows in set (0.00 sec) mysql> use test; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> show tables; +----------------+ | Tables_in_test | +----------------+ | t1 | +----------------+ 1 row in set (0.00 sec) mysql> select * from t1; +----+------+ | c1 | c2 | +----+------+ | 1 | Luis | +----+------+ 1 row in set (0.00 sec)
OKそうですね。
ちなみに、SECONDARYなROLEのNodeから更新しようとすると、エラーになります。
mysql> CREATE DATABASE test2; ERROR 1290 (HY000): The MySQL server is running with the --super-read-only option so it cannot execute this statement mysql> INSERT INTO t1 VALUES (2, 'hoge'); ERROR 1290 (HY000): The MySQL server is running with the --super-read-only option so it cannot execute this statement
Multi Primary Modeにしてみよう
ここまでで、Group Replicationの最初の第一歩的な確認をしてみましたが、最後にSingle Primary Modeではなく、Multi Primary Modeとして
構成してみます。
環境としては、先ほどまでとは別に、再度新しく作りました。
変更するのは、Group Replicationの設定で、各Nodeに以下を追加します。
loose-group_replication_single_primary_mode = off
この値は、デフォルトで「on」なのでSingle Primary Modeになります。
こうすると、「MEMBER_ROLE」がすべて「PRIMARY」となります。
mysql> SELECT * FROM performance_schema.replication_group_members; +---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | +---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+ | group_replication_applier | 297582cb-8c2a-11e8-8265-0242ac110003 | 172.17.0.3 | 3306 | ONLINE | PRIMARY | 8.0.11 | | group_replication_applier | 33f1ce00-8c2a-11e8-8a95-0242ac110004 | 172.17.0.4 | 3306 | ONLINE | PRIMARY | 8.0.11 | | group_replication_applier | c1cfe8f2-8737-11e8-b092-0242ac110002 | 172.17.0.2 | 3306 | ONLINE | PRIMARY | 8.0.11 | +---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+ 3 rows in set (0.00 sec)
この状態では、いずれのNodeからも更新することができます。
とりあえず、構築完了、ということで…。