MySQL 8.0.21 におけるグループレプリケーションの変更点について
はじめに
2020 年 7 月 13 日にリリースされた MySQL 8.0.21 では、いくつかのグループレプリケーションに関係する機能が追加あるいは変更されました。
Changes in MySQL 8.0.21 Functionality Added or Changed
今回は、これらの新機能について、これまでの挙動と比較しながら内容を確認していきたいと思います。
変更内容
今回追加あるいは変更された機能は大きく分けて以下の通りです。
- group_replication_advertise_recovery_endpoints システム変数の追加
- グループレプリケーション関連メッセージののロギングレベルの変更
- GROUP REPLICATION 開始時のユーザー認証情報の指定
- group_replication_message_cache_size システム変数の下限値引き下げ(1G → 128M)
- group_replication_member_expel_timeout システム変数のデフォルト値引き上げ(0 → 5)
- group_replication_autorejoin_tries システム変数のデフォルト値引き上げ(0 → 3)
それでは、それぞれの機能について、どのように挙動が変化したのかを確認していきます。
検証環境
以下のような環境で検証をおこないました。
- CentOS 7.7 / MySQL 8.0.19 (デフォルト値)
- CentOS 7.7 / MySQL 8.0.21 (デフォルト値)
- IP アドレス
- ens33 : Node1(Primary) – 192.168.174.9, Node2 – 192.168.174.10, Node3 – 192.168.174.7
- ens34 : Node1(Primary) – 192.168.153.9, Node2 – 192.168.153.10, Node3 – 192.168.153.7
group_replication_advertise_recovery_endpoints システム変数の追加
引用元 : Changes in MySQL 8.0.21 Functionality Added or Changed
Group Replication group members can now advertise a list of IP addresses that joining members can use to make connections to them for state transfer during distributed recovery. Previously, the existing member’s standard SQL client connection was used for this purpose as well as for client traffic. Advertising distributed recovery endpoints instead gives you improved control of distributed recovery traffic (comprising remote cloning operations and state transfer from the binary log) in your network infrastructure. The list of distributed recovery endpoints for a member is specified using the new group_replication_advertise_recovery_endpoints system variable, and the same SSL requirements are applied that would be in place if the SQL client connection was used for distributed recovery.
新しく group_replication_advertise_recovery_endpoints 変数が追加され、ノードのリカバリー中に使用する IP アドレスを指定できるようになりました。
MySQL 8.0.21 までは、たとえば MySQL Shell の addInstance() からノードを Clone 機能で複製した場合、以下のように指定したクライアント接続(ここでは ens34) からデータの送受信がおこなわれていました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# netstat -i Kernel Interface table Iface MTU RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg ens33 1500 134 0 0 0 91 0 0 0 BMRU ens34 1500 100 0 0 0 109 0 0 0 BMRU ### Node1 から以下のコマンドを実行 ### MySQL 192.168.153.9:3306 ssl JS > cluster.addInstance('icroot@192.168.153.7:3306') # netstat -i Kernel Interface table Iface MTU RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg ens33 1500 155 0 0 0 101 0 0 0 BMRU ens34 1500 42182 0 0 0 1346 0 0 0 BMRU |
MySQL 8.0.21 からは、group_replication_advertise_recovery_endpoints をたとえば以下のように変更することで、指定したクライアント接続に関わらず、ノードの複製あるいはリカバリー時に使用するネットワークやポートを指定することができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
mysql> SHOW GLOBAL VARIABLES LIKE 'group_replication_advertise_recovery_endpoints'; +------------------------------------------------+---------+ | Variable_name | Value | +------------------------------------------------+---------+ | group_replication_advertise_recovery_endpoints | DEFAULT | +------------------------------------------------+---------+ 1 row in set (0.0013 sec) mysql> SET GLOBAL group_replication_advertise_recovery_endpoints='192.168.174.9:3306'; Query OK, 0 rows affected (0.0003 sec) mysql> SHOW GLOBAL VARIABLES LIKE 'group_replication_advertise_recovery_endpoints'; +------------------------------------------------+--------------------+ | Variable_name | Value | +------------------------------------------------+--------------------+ | group_replication_advertise_recovery_endpoints | 192.168.174.9:3306 | +------------------------------------------------+--------------------+ 1 row in set (0.0015 sec) |
上記設定をノード側に設定した状態で MySQL Shell の addInstance() などを実行すると、今度は指定したネットワーク(ここでは ens33) を使用してデータが送受信されていることが確認できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# netstat -i Kernel Interface table Iface MTU RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg ens33 1500 118 0 0 0 71 0 0 0 BMRU ens34 1500 98 0 0 0 107 0 0 0 BMRU ### Node1 から以下のコマンドを実行 ### MySQL 192.168.153.9:3306 ssl JS > cluster.addInstance('icroot@192.168.153.7:3306') # netstat -i Kernel Interface table Iface MTU RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg ens33 1500 43387 0 0 0 1251 0 0 0 BMRU ens34 1500 567 0 0 0 565 0 0 0 BMRU |
なお、group_replication_advertise_recovery_endpoints を指定する場合は、IP アドレスあるいは名前解決可能なホスト名を指定することと、port、report_port、admin_port で既に指定しているポート番号を指定する必要があるので注意してください。また、値を複数記載した場合は先頭のリストから順番に接続が施行され、すべての接続に失敗した場合はエラーとなります。
この機能によって、ノードのリカバリー処理時に想定外のネットワーク負荷がかかり、パフォーマンス影響が発生するリスクを避けることができるようになりました。
グループレプリケーション関連メッセージののロギングレベルの変更
引用元 : Changes in MySQL 8.0.21 Functionality Added or Changed
The default logging level for MySQL Server omits informational log messages, which previously included some significant lifecycle events for Group Replication that were non-error situations, such as a group membership change. Messages about significant events for a replication group have now been reclassified as system messages, so they always appear in the server’s error log regardless of the server logging level. Operators can therefore review a complete history of the server’s membership in a replication group. Also, socket bind errors on the group communication layer have been reclassified from information to error messages.
MySQL 8.0.21 までは、たとえばメンバーの追加をおこなった際のログなどは [Note] 表記になっていたため、デフォルトの状態(log_error_verbosity=2) ではエラーログに出力されませんでした。
たとえば、以下の内容は MySQL 8.0.19 において log_error_verbosity=3 にした際の addInstance() 実行時のメッセージです。
1 2 3 4 5 6 7 8 9 |
[Note] [MY-010733] [Server] Shutting down plugin 'clone' [Note] [MY-011735] [Repl] Plugin group_replication reported: '[GCS] Re-using server node 0 host Node1' [Note] [MY-011735] [Repl] Plugin group_replication reported: '[GCS] Re-using server node 1 host Node2' [Note] [MY-011735] [Repl] Plugin group_replication reported: '[GCS] Re-using server node 2 host Node3' [Note] [MY-011735] [Repl] Plugin group_replication reported: '[GCS] Installed site start={5d94393 2015 0} boot_key={5d94393 2004 0} event_horizon=10 node 0' [Note] [MY-011735] [Repl] Plugin group_replication reported: '[GCS] Group is able to support up to communication protocol version 8.0.16' [Note] [MY-011501] [Repl] Plugin group_replication reported: 'Members joined the group: Node3:3306' [Note] [MY-011503] [Repl] Plugin group_replication reported: 'Group membership changed to Node3:3306, Node1:3306, Node2:3306 on view 15971126006846740:7.' [Note] [MY-011492] [Repl] Plugin group_replication reported: 'The member with address Node3:3306 was declared online within the replication group. |
MySQL 8.0.21 からは、最後の 2 行が [System] 表記に変更されたため、以下のようにデフォルト値の状態でもエラーログに出力されるようになりました。
1 2 |
[System] [MY-011503] [Repl] Plugin group_replication reported: 'Group membership changed to Node3:3306, Node1:3306 on view 15971215320781114:8.' [System] [MY-011492] [Repl] Plugin group_replication reported: 'The member with address Node3:3306 was declared online within the replication group.' |
なお、もともと log_error_verbosity=3 に設定している場合は出力内容に変化はありません。
GROUP REPLICATION 開始時のユーザー認証情報の指定
引用元 : Changes in MySQL 8.0.21 Functionality Added or Changed
You can now specify user credentials for distributed recovery on the START GROUP_REPLICATION statement using the USER, PASSWORD, and DEFAULT_AUTH options. These credentials are used for distributed recovery on the group_replication_recovery channel. When you specify user credentials on START GROUP_REPLICATION, the credentials are saved in memory only, and are removed by a STOP GROUP_REPLICATION statement or server shutdown. These credentials can replace user credentials set using a CHANGE MASTER TO statement, which are stored in the replication metadata repositories, and can therefore help to secure the Group Replication servers against unauthorized access.
START GROUP_REPLICATION コマンドの実行時、通常のレプリケーションと同様に、以下のオプションを指定できるようになりました。
- USER
- PASSWORD
- DEFAULT_AUTH
これによって、通常は master.infoファイルや以下のように mysql.slave_master_info テーブルに平文で保存されている group_replication_recovery チャンネルのユーザー資格情報を秘匿することが可能になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
mysql> SELECT * FROM mysql.slave_master_info\G (...) *************************** 2. row *************************** Number_of_lines: 31 Master_log_name: Master_log_pos: 4 Host: User_name: mysql_innodb_cluster_477616015 User_password: :0$4,$S3^_#F]/w*.w_.;~b#[|e~#Q>? Port: 3306 (...) Channel_name: group_replication_recovery Tls_version: Public_key_path: Get_public_key: 0 Network_namespace: Master_compression_algorithm: uncompressed Master_zstd_compression_level: 3 Tls_ciphersuites: NULL 2 rows in set (0.00 sec) |
ただし、group_replication_recovery チャンネルのユーザー資格情報を設定する際にユーザー情報を指定しなかった場合、group_replication_start_on_boot が有効(デフォルト値)になっているとグループレプリケーションの起動に失敗してしまうため、group_replication_start_on_boot は無効にしておく必要があります。
また、MySQL Shell の addInstance() を使用してノードを追加した場合も自動でパスワード情報が記録されてしまうため、この機能を使用する場合は、手動でグループレプリケーションを構築・運用しなければならないので注意してください。
group_replication_message_cache_size システム変数の下限値引き下げ(1G → 128M)
引用元 : Changes in MySQL 8.0.21 Functionality Added or Changed
The minimum setting for the maximum size for the XCom message cache in Group Replication, specified by the group_replication_message_cache_size system variable, has been reduced from approximately 1 GB to 134217728 bytes, or approximately 128 MB. Note that this size limit applies only to the data stored in the cache, and the cache structures require an additional 50 MB of memory. The same cache size limit should be set on all group members. The default XCom message cache size of 1 GB, which was formerly also the minimum setting, is unchanged.
group_replication_message_cache_size は、グループレプリケーションにおいて各ノード間で交換されるメッセージおよびメタデータを保持する XCom メッセージキャッシュと呼ばれるメモリー領域です。通常、この領域は障害が発生したノードが復旧する際、それまでに実行されたメッセージ情報を回復させるために参照されます。このパラメータは MySQL 8.0.16 までは内部的にのみ存在しており、それ以降はパラメータ化していますが、最小値は 1GB となっていました。
このパラメータは、グループレプリケーションで更新をおこなっていると GCS_XCom::xcom_cache としてメモリーを使用していき、最大で group_replication_message_cache_size(デフォルト値:1GB) まで増加します。
1 2 3 4 5 6 7 |
mysql> SELECT * FROM sys.memory_global_by_current_bytes WHERE event_name='memory/group_rpl/GCS_XCom::xcom_cache'; +---------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+ | event_name | current_count | current_alloc | current_avg_alloc | high_count | high_alloc | high_avg_alloc | +---------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+ | memory/group_rpl/GCS_XCom::xcom_cache | 3809 | 1016.67 MiB | 273.32 KiB | 7995 | 1.01 GiB | 132.34 KiB | +---------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+ 1 row in set (0.00 sec) |
また、この領域はプロセスを再起動するまでは解放されず、最大値を超えて使用される場合、最も古いメッセージから順番に削除されるようになっています。このような仕様上、グループレプリケーションを使用する場合は、group_replication_message_cache_size が最低 1GB のメモリーを使用することを設計時に考慮する必要がありました。
MySQL 8.0.21 では、group_replication_message_cache_size の最小値が 128MB に下がったため、このパラメータをデフォルト値から変更することで、メモリーへの影響を少なくすることが可能になりました。
ただし、group_replication_message_cache_size の値が少なすぎると、ノードで障害が発生した際に XCom メッセージキャッシュから復旧できなくなり、ノードのリカバリーをおこなう必要が出てくるため、復旧までの時間が長くなってしまう可能性があるので注意してください。
なお、ノードの障害中に XCom メッセージキャッシュの最大値を超えてメッセージが入ってきた場合は、以下のような [Warning] が他のノードに出力されます。
1 |
[Warning] [MY-011735] [Repl] Plugin group_replication reported: '[GCS] Messages that are needed to recover node Node2:33061 have been evicted from the message cache. Consider resizing the maximum size of the cache by setting group_replication_message_cache_size.' |
そのため、group_replication_message_cache_size の値は後述している group_replication_member_expel_timeout と併せて、ノードが他のメンバーから切り離される前に実行されるトランザクション量より大きくすることが推奨されています。
group_replication_member_expel_timeout システム変数のデフォルト値引き上げ(0 → 5)
引用元 : Changes in MySQL 8.0.21 Functionality Added or Changed
group_replication_member_expel_timeout specifies the period of time in seconds that a Group Replication group member waits after creating a suspicion, before expelling from the group the member suspected of having failed. The initial 5-second detection period before a suspicion is created does not count as part of this time.
グループレプリケーションでは、5 秒間応答がなかったノードを接続不能としてマークした後、group_replication_member_expel_timeout の秒数だけ待機しても再接続できなければ、メンバーから切り離します。MySQL 8.0.21 では、この待機秒数が 5 秒に引き上げられました。
また、前述した group_replication_message_cache_size は、切り離されるまでの間に障害から復旧できた場合、それまでに XCom メッセージキャッシュが溢れていなければ、XCom メッセージキャッシュを利用してノードの復旧をおこないます。
この変更によりデフォルトでは、ノードで障害が発生してから 10 秒間はメンバーから切り離されなくなったので、XCom メッセージキャッシュをより有効利用できるようになりました。しかし、その分ノードが切り離される( = MySQL Router で障害を検知する)までの秒数は長くなってしまうため、注意が必要です。
group_replication_autorejoin_tries システム変数のデフォルト値引き上げ(0 → 3)
引用元 : Changes in MySQL 8.0.21 Functionality Added or Changed
Group Replication’s auto-rejoin feature is now activated by default. The group_replication_autorejoin_tries system variable, which is available from MySQL 8.0.16, makes a member that has been expelled or reached its unreachable majority timeout try to rejoin the group automatically. This system variable, which originally defaulted to 0 so auto-rejoin was not activated, now defaults to 3, meaning that a member makes three attempts to rejoin the group in the event of its expulsion or unreachable majority timeout. Between each attempt the member waits for 5 minutes. If the specified number of tries is exhausted without the member rejoining or being stopped, the member proceeds to the action specified by the group_replication_exit_state_action system variable.
ノードがメンバーから切り離された後、再び他のメンバーと通信できるようになった際に、group_replication_autorejoin_tries の数だけメンバーへの再加入を試みます。MySQL 8.0.20 までは無効になっているため、ノードが障害から復旧しても再加入はおこなわれず、手動でメンバーに復帰させる必要がありました。
MySQL 8.0.21 からは、自動で 3 回までメンバーへの再加入を試みます。なお、一度再加入に失敗した場合、5 分間待機した後、再加入を試みます。そして、group_replication_autorejoin_tries の数だけ再加入に失敗した場合は group_replication_exit_state_action が実行されて、デフォルトでは READ_ONLY モードに切り替わります。
まとめ
ここまで、MySQL 8.0.21 におけるグループレプリケーションに関係する変更点について確認してきました。
全体として、デフォルト値でも手動オペレーションを減らせるような設定に変更されていると感じました。ただし group_replication_member_expel_timeout については、障害を検知するまでの時間が長くなってしまうので、システム要件によっては 0 に戻した方が良いかもしれません。
その他にも、メモリーやネットワーク負荷を軽減させるようなパラメータの変更ができるようになったので、この辺りに問題を抱えているような環境では、是非 MySQL 8.0.21 へのアップグレードをご検討ください。