はじめに
MySQLのGroup ReplicationにはFlow controlという機能があります。
Flow controlを制御するためのパラメータが複数ありますが、本記事では一部のパラメータがどのようにFlow controlに影響するかを確認してみました。
前提
今回は、MySQL8.0.35で検証を行います。Group Replicationは3台構成です。
また、今回の記事で確認する変数は全て、SET
コマンドで変更すると即時反映されます。レプリケーションの停止などは不要となります。
なお、各検証で特に断りが無い場合は、パラメータはデフォルト値となっています。
テストデータ準備
検証にはsysbenchを使用して更新処理を行います。
下記のコマンドで事前準備を行います。
1 2 3 |
mysql> CREATE DATABASE sbtest; mysql> CREATE USER sbtest@127.0.0.1 IDENTIFIED BY 'MySQL8.0'; mysql> GRANT ALL PRIVILEGES ON sbtest.* TO sbtest@127.0.0.1 ; |
続いて、下記のコマンドで事前にテーブルを作成します。
1 2 3 4 5 6 7 8 9 |
$ sysbench \ --mysql-host=127.0.0.1 \ --mysql-port=3306 \ --mysql-db=sbtest \ --mysql-user=sbtest \ --mysql-password=MySQL8.0 \ --tables=3 \ --table_size=10000 \ oltp_common prepare |
performance_schema.replication_group_member_statsについて
performance_schema.replication_group_member_statsで各メンバーの統計情報を確認できます。
本記事で関係するカラムを説明します。
-
COUNT_TRANSACTIONS_IN_QUEUE
キュー内の保留中の競合検出チェックのトランザクション数。 トランザクションの競合がチェックされた後、チェックに合格すると、トランザクションも適用されるようにキューに入れられます。 -
COUNT_TRANSACTIONS_REMOTE_IN_APPLIER_QUEUE
このメンバーがレプリケーショングループから受信し、適用を待機しているトランザクションの数。 -
COUNT_TRANSACTIONS_LOCAL_PROPOSED
このメンバーで発生し、グループに送信されたトランザクションの数。
COUNT_TRANSACTIONS_IN_QUEUEがgroup_replication_flow_control_certifier_thresholdを超えるか、COUNT_TRANSACTIONS_REMOTE_IN_APPLIER_QUEUEがgroup_replication_flow_control_applier_thresholdを超えるとFlow controlが発生します。
今回はPercona Monitoring and Management(PMM)のMySQL Group Replication Summaryダッシュボードを使用して、COUNT_TRANSACTIONS_REMOTE_IN_APPLIER_QUEUEやCOUNT_TRANSACTIONS_LOCAL_PROPOSEDなどの値を確認していきます。
検証
group_replication_flow_control_applier_threshold
group_replication_flow_control_applier_threshold
はFlow controlをトリガーする閾値を決めます。
また、group_replication_flow_control_mode
はFlow controlのモードを指定します。DISABLEDに設定するとFlow controlは無効になります。
Flow controlを無効にした場合とgroup_replication_flow_control_applier_threshold
が5000の場合の検証結果を比較します。
-
Flow control無効
1mysql> SET global group_replication_flow_control_mode=DISABLED; -
group_replication_flow_control_applier_thresholdを5000に設定
12mysql> SET global group_replication_flow_control_mode=QUOTA;mysql> SET global group_replication_flow_control_applier_threshold=5000;
下記のコマンドでsysbenchを実行します。
1 2 3 4 5 6 7 8 9 |
$ sysbench \ --mysql-host=127.0.0.1 \ --mysql-port=3306 \ --mysql-db=sbtest \ --mysql-user=sbtest \ --mysql-password=MySQL8.0 \ --threads=50 \ --time=60 \ oltp_write_only run |
最初にFlow control無効にしたパターンを実行し、次にgroup_replication_flow_control_applier_threshold
を5000に設定したパターンを実行しています。
図の左下のReceived Transactions Queueはperformance_schema.replication_group_member_stats
のCOUNT_TRANSACTIONS_REMOTE_IN_APPLIER_QUEUE
カラムのグラフです。これは、現在適用を待機しているトランザクションの数を示しています。2回目の検証では、キューの数が設定した5000の閾値付近で横ばいになっていることがわかります。
また、右上にあるSent Transactionsはperformance_schema.replication_group_member_stats
のCOUNT_TRANSACTIONS_LOCAL_PROPOSED
カラムのグラフです。これは、グループに送信されたトランザクションの数を示しています。2回目の検証では、送信されたトランザクションが途中から増減を繰り返していて、Flow controlによる制御が行われていることがわかります。
Flow control発生中のgroup_replication_flow_control_modeの変更
Flow control発生中にgroup_replication_flow_control_mode
を変更した際の動作を確認します。
まずは、group_replication_flow_control_mode
をQUOTAとし、group_replication_flow_control_applier_threshold
を5000に設定します
1 2 |
mysql> SET global group_replication_flow_control_mode=QUOTA; mysql> SET global group_replication_flow_control_applier_threshold=5000; |
下記のコマンドでsysbenchを実行します。
1 2 3 4 5 6 7 8 9 |
$ sysbench \ --mysql-host=127.0.0.1 \ --mysql-port=3306 \ --mysql-db=sbtest \ --mysql-user=sbtest \ --mysql-password=MySQL8.0 \ --threads=50 \ --time=600 \ oltp_write_only run |
2分後にgroup_replication_flow_control_mode
をDISABLEDに設定します
※このタイミングで目印として、グラフにはオレンジの縦線が挿入されています
1 |
mysql> SET global group_replication_flow_control_mode=DISABLED; |
さらにその2分後にgroup_replication_flow_control_mode
をQUOTAに設定します
※同じくこのタイミングでもグラフにはオレンジの縦線を挿入しています
1 |
mysql> SET global group_replication_flow_control_mode=QUOTA; |
最初の2分間の間にSent Transactionsのグラフで値が上下していることから、Flow controlが発生していることがわかります。
そして、group_replication_flow_control_mode
がDISABLEDに変更されるとすぐに、Sent Transactionsの値はほぼ一定になります。また、Received Transactions Queueの値が急増しています。このことからFlow controlが停止していることがわかります。
2分後に再度group_replication_flow_control_mode
がQUOTAに変更されると、Received Transactions Queueの値がgroup_replication_flow_control_applier_threshold
で設定した5000に下がるまで、一時的にSent Transactionsの値が急減しています。
その後は最初の2分間と同じようにSent Transactionsの値は増減を繰り返します。
意図せずFlow controlが発生が発生した場合は、すぐにFlow controlを無効にできることがわかります。逆にシステム稼働中にFlow controlを有効にしたり、関連パラメータを変更すると急にFlow controlが発生し、処理が制限される可能性もあるので注意が必要です。
group_replication_flow_control_hold_percent
group_replication_flow_control_hold_percent
はドキュメントで下記のように説明されています。
group_replication_flow_control_hold_percent では、フロー制御下のクラスタがバックログで捕捉できるように、未使用のままになるグループ割当ての割合を定義します。 値 0 は、作業バックログを捕捉するために割当て制限の一部が予約されていないことを意味します。
具体的にどのように動作するのか、group_replication_flow_control_hold_percent
の値を順番に10(デフォルト),70,100としてsysbenchを実行した場合を比較してみます。
なお、group_replication_flow_control_applier_threshold
は5000に設定しています。
1 2 3 4 5 6 7 |
mysql> SET global group_replication_flow_control_applier_threshold=5000; mysql> SET global group_replication_flow_control_hold_percent=10; or mysql> SET global group_replication_flow_control_hold_percent=70; or mysql> SET global group_replication_flow_control_hold_percent=100; |
1 2 3 4 5 6 7 8 9 |
$ sysbench \ --mysql-host=127.0.0.1 \ --mysql-port=3306 \ --mysql-db=sbtest \ --mysql-user=sbtest \ --mysql-password=MySQL8.0 \ --threads=50 \ --time=120 \ oltp_write_only run |
group_replication_flow_control_hold_percent=100とした3回目の検証を見ると、Received Transactions Queueのグラフで、キューが0になるのを待っていることがはっきりとわかります。
group_replication_flow_control_max_quota
group_replication_flow_control_max_quota
はドキュメントで下記のように説明されています。
group_replication_flow_control_max_commit_quota では、フロー制御が有効になっている間、グループの最大フロー制御割当て制限または任意の期間の最大使用可能割当て制限が定義されます。 値 0 は、最大割当て制限が設定されていないことを意味します。
※日本語版ドキュメントではgroup_replication_flow_control_max_commit_quota
と記載されていますが、英語版及び実際のパラメータはgroup_replication_flow_control_max_quota
となっていました。
group_replication_flow_control_max_quota
を0(デフォルト),500としてsysbenchを実行した場合を比較します。
なお、今回はCOUNT_TRANSACTIONS_REMOTE_IN_APPLIER_QUEUEが閾値を超えたことによるFlow controlの発生を回避するため、group_replication_flow_control_applier_threshold
は50000に設定しています。
1 2 3 4 5 |
mysql> SET global group_replication_flow_control_applier_threshold=50000; mysql> SET global group_replication_flow_control_max_quota=0; or mysql> SET global group_replication_flow_control_max_quota=500; |
1 2 3 4 5 6 7 8 9 |
$ sysbench \ --mysql-host=127.0.0.1 \ --mysql-port=3306 \ --mysql-db=sbtest \ --mysql-user=sbtest \ --mysql-password=MySQL8.0 \ --threads=50 \ --time=120 \ oltp_write_only run |
Sent Transactionsのグラフから、送信したトランザクションの数が設定した制限(group_replication_flow_control_max_quota=500
)と一致していることがわかります。group_replication_flow_control_applier_threshold
の閾値に達していない場合もトランザクションが制限されることがわかります。
なお、group_replication_flow_control_mode
をDISABLED
に設定した場合は、group_replication_flow_control_max_quota
による制限も行われません。
group_replication_flow_control_min_quota
group_replication_flow_control_min_quota
はドキュメントで下記のように説明されています。
group_replication_flow_control_min_quota は、最後の期間に実行された計算済の最小目標とは関係なく、メンバーに割り当てることができる最小フロー制御目標を制御します。 値 0 は、最小割当て制限がないことを意味します。
group_replication_flow_control_applier_threshold
を5000に設定し、
group_replication_flow_control_min_quota
を0(デフォルト),900でそれぞれsysbenchを実行した場合を比較します。
1 2 3 4 5 |
mysql> SET global group_replication_flow_control_applier_threshold=5000; mysql> SET global group_replication_flow_control_min_quota=0; or mysql> SET global group_replication_flow_control_min_quota=900; |
1 2 3 4 5 6 7 8 9 |
$ sysbench \ --mysql-host=127.0.0.1 \ --mysql-port=3306 \ --mysql-db=sbtest \ --mysql-user=sbtest \ --mysql-password=MySQL8.0 \ --threads=50 \ --time=120 \ oltp_write_only run |
Sent TransactionsとReceived Transactions Queueのグラフから、1回目の検証では、キューの数がgroup_replication_flow_control_applier_threshold
を超えたため、Flow controlがトリガーされていることがわかります。
一方で、2回目の検証では、キューの数がgroup_replication_flow_control_applier_threshold
を超えたものの、group_replication_flow_control_min_quota
で設定した900の辺りまではトランザクションの送信ができていることがわかります。
group_replication_flow_control_release_percent
group_replication_flow_control_release_percent
はドキュメントで下記のように説明されています。
group_replication_flow_control_release_percent では、フロー制御でライターメンバーを制限する必要がなくなった場合に、グループ割当て制限を解放する方法を定義します。
まずは、group_replication_flow_control_applier_threshold
を5000に設定し、
group_replication_flow_control_release_percent
を5,50(デフォルト)でそれぞれsysbenchを実行した場合を比較します。
1 2 3 4 5 |
mysql> SET global group_replication_flow_control_applier_threshold=5000; mysql> SET global group_replication_flow_control_release_percent=5; or mysql> SET global group_replication_flow_control_release_percent=50; |
1 2 3 4 5 6 7 8 9 |
$ sysbench \ --mysql-host=127.0.0.1 \ --mysql-port=3306 \ --mysql-db=sbtest \ --mysql-user=sbtest \ --mysql-password=MySQL8.0 \ --threads=50 \ --time=120 \ oltp_write_only run |
group_replication_flow_control_release_percentを5とした場合、制限が解除された後、Sent Transactionsの値の上昇は緩やかであることがわかります。
次にgroup_replication_flow_control_applier_threshold
を100に設定し、
group_replication_flow_control_release_percent
を50(デフォルト)と1000でそれぞれsysbenchを実行した場合を比較します。
1 2 3 4 5 |
mysql> SET global group_replication_flow_control_applier_threshold=100; mysql> SET global group_replication_flow_control_release_percent=50; or mysql> SET global group_replication_flow_control_release_percent=1000; |
1 2 3 4 5 6 7 8 9 |
$ sysbench \ --mysql-host=127.0.0.1 \ --mysql-port=3306 \ --mysql-db=sbtest \ --mysql-user=sbtest \ --mysql-password=MySQL8.0 \ --threads=50 \ --time=120 \ oltp_write_only run |
group_replication_flow_control_release_percentを1000に設定すると、現在のクォータの最大10 倍(1000%)でクォータを解放できます。ドキュメントでは下記のように説明されています。
The range allows the quota to be released at up to 10 times current quota, as that allows a greater degree of adaptation, mainly when the flow control period is large and the quotas are very small.
グラフを見ると、制限解除後のSent Transactionsの値の値が急上昇していることがわかります。
まとめ
Flow controlを制御しているパラメータの一部について、どのように動作するのかを検証してみました。ドキュメントだけでは読み取りにくかったものも、整理できたのではないかと思います。
Flow control関連のチューニングを考えている場合は、本記事も参考にしてみてください。
また、今回の検証で使用したPMMのグラフは全てデフォルトで使用できるものです。Group Replicationを監視するための追加設定などは不要で簡単にGroup Replicationのステータスの確認ができました。
下記のブログ記事では、PMMのMySQL Group Replication Summaryダッシュボードで監視できる情報について詳しく説明がされているので、本記事と合わせてご参考いただければと思います。
- InnoDB Cluster・Group Replication の監視方法について
https://blog.s-style.co.jp/2022/07/9010/