2020/10/19 に、待望の MySQL Server 8.0.22 がGAしました。
本リリースでも様々な興味深い機能が追加されていますので、今回は、MySQL Server 8.0.22に含まれる気になる新機能についてご紹介します。
新機能や変更点について網羅的に知りたいという場合は、公式のリリースノートをご確認頂ければと思います。
https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-22.html
なお、弊社ではMySQLを始めとした製品のリリース情報を和訳しサイトに公開していますので、よろしければ合わせてご確認ください。
https://www.s-style.co.jp/mysql_news/mysql/mysql-8-0-22-ga版(リリース日:2020年10月19日).html
非同期レプリケーション接続フェイルオーバについて
リリースノートを眺めていると、以下の内容がサラッと記載されています。
You can use MySQL Server’s new asynchronous connection failover mechanism to automatically establish an asynchronous (source to replica) replication connection to a new source after the existing connection from a replica to its source fails. The connection fails over if the replication I/O thread stops due to the source stopping or due to a network failure. The asynchronous connection failover mechanism can be used to keep a replica synchronized with multiple MySQL servers or groups of servers that share data, including asynchronous replication from servers where Group Replication is in use. To activate asynchronous connection failover for a replication channel set SOURCE_CONNECTION_AUTO_FAILOVER=1 on the CHANGE MASTER TO statement for the channel, and set up a source list for the channel using the asynchronous_connection_failover_add_source and asynchronous_connection_failover_delete_source UDFs.
MariaDB MaxScaleや、 Orchestratorでは フェイルオーバ/スイッチオーバの一環としてレプリカの接続先のソースを正常なインスタンスに切り替えるという動作が含まれています。
上記のような機能が、この度ネイティブな機能として実装されたようです。
WL#12649 で本機能の詳細な説明を確認できますが、以下の記載の通り、本機能はMySQL InnoDB Cluster(MIC)をソースとした構成を意識した機能となっています。
MOTIVATION
The main driver of this worklog is to make deployment fault-tolerant of sender failure by automating the process of re-establishment of an asynchronous replication connection to another sender of sender list. The sender server can be deployed across wide-area in different location, to improve the Disaster Recovery (DR) to even failures of whole data center. This will also be true for Innodb cluster as the sender can also be a member of an Innodb cluster. When Innodb Cluster was introduced it created a fault-tolerant system where redundant components could be removed automatically and the system continued to operate as expected. This work will further improve fault-tolerance of Innodb cluster to failures of whole data center, by creating fault-tolerant replica cluster across wide-area in different location.
MICをソース(=Sender)としたリードレプリカ(=Receiver)を構築した際に、MICの各ノードをフェイルオーバ候補として登録しておくだけで、非同期レプリカの手動ソース切り替えを必要とせずサービスを継続する事ができます。
同機能の要件
https://dev.mysql.com/doc/refman/8.0/en/replication-asynchronous-connection-failover.html
本機能を使用するための要件は以下のとおりです。
- ソース、レプリカともに
gtid_mode = ON
である - レプリカの設定において、
CHANGE MASTER TO ... MASTER_AUTO_POSITION = 1
が設定されている - すべてのソース候補となるデータベースへ、チャネルごとに同じユーザ/パスワードで接続できる
- START REPLICA実行時にパスワードを指定する方法では利用できない(CHANGE MASTER TO時に指定する)
GTIDが有効であれば、利用に際して大きなハードルはありません。
機能検証
今回はdbdeployerを使用して検証を行いました。
手元で検証を行われる場合は、dbdeployerとMySQL 8.0.22 の必要なパッケージの準備をお願いいたします。
1 2 3 |
$ dbdeployer init --skip-tarball-download $ curl -OkL https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.22-linux-glibc2.12-x86_64.tar.xz $ dbdeployer unpack mysql-8.0.22-linux-glibc2.12-x86_64.tar.xz |
Group Replication(GR) + Async Replicationのセットアップ
MICをソースとした場合の非同期レプリカの動作を確認します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# Configure GR $ dbdeployer deploy replication --topology=group --single-primary --remote-access=% --bind-address=0 --gtid --sandbox-directory=gr8022 8.0.22 # Configure Single Instance $ dbdeployer deploy single --remote-access=% --bind-address=0 --gtid --sandbox-directory=single8022 8.0.22 # GR to Single replication configuration $ ~/sandboxes/single8022/use -e "CHANGE MASTER TO MASTER_USER='msandbox', MASTER_PASSWORD='msandbox', MASTER_HOST='127.0.0.1', MASTER_PORT=23223, MASTER_AUTO_POSITION=1" # Start repliation $ ~/sandboxes/single8022/use -e "START REPLICA" # Test $ ~/sandboxes/gr8022/n1 -e "CREATE TABLE test.t (i int primary key auto_increment)" $ ~/sandboxes/gr8022/use_all -e "show tables from test" $ ~/sandboxes/single8022/use -e "show tables from test" |
注意点として、本機能はCHANGE MASTER TO
に指定する MASTER_CONNECT_RETRY
の間隔で、 MASTER_RETRY_COUNT
回数の再接続を施行しても成功しなかった時にトリガされます。
デフォルトでは、MASTER_CONNECT_RETRY
は 60(秒)
、MASTER_RETRY_COUNT
は86400(回)
となっており、60日間フェイルオーバが発生しませんので、適宜オプションを変更する必要があります。
今回は1秒×5回(=5s)でフェイルオーバする設定としましたが、本番ではレプリカで遅延を許容できる値に調整する必要があります。
そして、本機能を有効化するためには SOURCE_CONNECTION_AUTO_FAILOVER = 1
を指定する必要があります。
SOURCE_CONNECTION_AUTO_FAILOVER
はレプリケーション(I/Oスレッド)が実行中であっても設定が即時反映されますので、機能のON/OFFは気軽に切り替えられます。
1 2 3 4 |
$ ~/sandboxes/single8022/use -e " STOP REPLICA; CHANGE MASTER TO MASTER_CONNECT_RETRY = 1, MASTER_RETRY_COUNT = 5, SOURCE_CONNECTION_AUTO_FAILOVER = 1; START REPLICA;" |
次にレプリカ上でソースとなるインスタンスの候補リストを作成します。
ソース候補の追加と削除は、以下のUDFを使用して行います。
https://dev.mysql.com/doc/refman/8.0/en/replication-functions-source-list.html
- asynchronous_connection_failover_add_source(channel, host, port, network_namespace, weight)
- asynchronous_connection_failover_delete_source(channel, host, port, network_namespace)
channel
, host
, port
は既知のレプリケーションパラメータと同義です。
channel
は必須ではありません。
network_namespace はこちらも8.0.22から導入された機能となり、コンテナ・仮想環境で動作するmysqldを想定した物理NICとは異なるネットワーク名前空間上の通信を制御するためのものです。
物理NICに設定されたネットワークを利用する場合は空で問題ありません。
weight
はフェイルオーバ先の優先順位をつけるためのものであり、同じweight
を持つソースはランダムで選択されます。
今回はGroup Replicationに所属するすべてのインスタンスを指定しました。
また、1インスタンスのみweightを低めに設定しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
$ ~/sandboxes/single8022/use -e "SELECT asynchronous_connection_failover_add_source('', '127.0.0.1', 23223, '', 100)" +------------------------------------------------------------------------------+ | asynchronous_connection_failover_add_source('', '127.0.0.1', 23223, '', 100) | +------------------------------------------------------------------------------+ | The UDF asynchronous_connection_failover_add_source() executed successfully. | +------------------------------------------------------------------------------+ $ ~/sandboxes/single8022/use -e "SELECT asynchronous_connection_failover_add_source('', '127.0.0.1', 23224, '', 100)" +------------------------------------------------------------------------------+ | asynchronous_connection_failover_add_source('', '127.0.0.1', 23224, '', 100) | +------------------------------------------------------------------------------+ | The UDF asynchronous_connection_failover_add_source() executed successfully. | +------------------------------------------------------------------------------+ $ ~/sandboxes/single8022/use -e "SELECT asynchronous_connection_failover_add_source('', '127.0.0.1', 23225, '', 80)" +------------------------------------------------------------------------------+ | asynchronous_connection_failover_add_source('', '127.0.0.1', 23225, '', 80) | +------------------------------------------------------------------------------+ | The UDF asynchronous_connection_failover_add_source() executed successfully. | +------------------------------------------------------------------------------+ |
追加したソース候補は mysql.replication_asynchronous_connection_failover
に格納されています。
1 2 3 4 5 6 7 8 |
$ ~/sandboxes/single8022/use -e "select * from mysql.replication_asynchronous_connection_failover" +--------------+-----------+-------+-------------------+--------+ | Channel_name | Host | Port | Network_namespace | Weight | +--------------+-----------+-------+-------------------+--------+ | | 127.0.0.1 | 23223 | | 100 | | | 127.0.0.1 | 23224 | | 100 | | | 127.0.0.1 | 23225 | | 80 | +--------------+-----------+-------+-------------------+--------+ |
それでは現在アクティブなソースであるMIC(node1)のインスタンスを停止します。
1 2 3 4 5 6 |
$ ~/sandboxes/gr8022/node1/stop $ ~/sandboxes/gr8022/status_all MULTIPLE /home/nari/sandboxes/gr8022 node1 : node1 off - (23223) node2 : node2 on - port 23224 (23224) node3 : node3 on - port 23225 (23225) |
レプリカのエラーログには以下の出力が確認できました。
1 2 3 4 5 6 7 8 9 10 |
2020-10-27T02:19:13.458740Z 57 [System] [MY-010558] [Repl] Slave for channel '': received end packet from server due to dump thread being killed on master. Dump threads are killed for example during master shutdown, explicitly by a user, or when the master receives a binlog send request from a duplicate server UUID <00008022-0000-0000-0000-000000008022> : Error 2020-10-27T02:19:13.459154Z 57 [Warning] [MY-010897] [Repl] 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. 2020-10-27T02:19:13.459483Z 57 [ERROR] [MY-010584] [Repl] Slave I/O for channel '': error reconnecting to master 'msandbox@127.0.0.1:23223' - retry-time: 1 retries: 1 message: Can't connect to MySQL server on '127.0.0.1' (111), Error_code: MY-002003 2020-10-27T02:19:14.459990Z 57 [ERROR] [MY-010584] [Repl] Slave I/O for channel '': error reconnecting to master 'msandbox@127.0.0.1:23223' - retry-time: 1 retries: 2 message: Can't connect to MySQL server on '127.0.0.1' (111), Error_code: MY-002003 2020-10-27T02:19:15.460570Z 57 [ERROR] [MY-010584] [Repl] Slave I/O for channel '': error reconnecting to master 'msandbox@127.0.0.1:23223' - retry-time: 1 retries: 3 message: Can't connect to MySQL server on '127.0.0.1' (111), Error_code: MY-002003 2020-10-27T02:19:16.461087Z 57 [ERROR] [MY-010584] [Repl] Slave I/O for channel '': error reconnecting to master 'msandbox@127.0.0.1:23223' - retry-time: 1 retries: 4 message: Can't connect to MySQL server on '127.0.0.1' (111), Error_code: MY-002003 2020-10-27T02:19:17.461543Z 57 [ERROR] [MY-010584] [Repl] Slave I/O for channel '': error reconnecting to master 'msandbox@127.0.0.1:23223' - retry-time: 1 retries: 5 message: Can't connect to MySQL server on '127.0.0.1' (111), Error_code: MY-002003 2020-10-27T02:19:17.473336Z 60 [Warning] [MY-010897] [Repl] 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. 2020-10-27T02:19:17.474410Z 60 [System] [MY-010562] [Repl] Slave I/O thread for channel '': connected to master 'msandbox@127.0.0.1:23224',replication started in log 'FIRST' at position 192 2020-10-27T02:19:17.475906Z 60 [Warning] [MY-010549] [Repl] The master's UUID has changed, although this should not happen unless you have changed it manually. The old UUID was 00023223-1111-1111-1111-111111111111. |
同機能がトリガされたという明示的なメッセージは見当たりませんが、5回リトライした後通常のCHANGE MASTER/START REPLICAを実行した時とほぼ同じ出力が確認できました。
※ソースが切り替わった都合上MY-010549のメッセージが出力されています。
レプリケーションも特に問題なく継続されました。
1 2 3 4 5 6 7 8 9 |
$ ~/sandboxes/gr8022/node2/use -e "insert into test.t values (1), (2), (3)" $ ~/sandboxes/single8022/use -e "select * from test.t" +---+ | i | +---+ | 1 | | 2 | | 3 | +---+ |
実運用ではMIC等のノード毎にホスト上で実行するジョブ等を分けていたり、運用上の役割をもたせているなどの都合から、復旧後はフェイルバックしたいという事もよくあります。
再度MIC(node1)を起動することで、自動的にレプリケーションもフェイルバックするか試してみましたが、結論としてはフェイルバックはしませんでした。
1 2 3 |
$ ~/sandboxes/gr8022/node1/start $ ~/sandboxes/single8022/use -e "show replica status\G" | grep -i source_port Source_Port: 23224 |
これについてはドキュメントにもフェイルバックは行われない旨が明記されています。
Once the replica has succeeded in making a connection, it does not change the connection unless the new source stops or there is a network failure. This is the case even if the source that became unavailable and triggered the connection change becomes available again and has a higher priority setting.
ただしMIC(node1)が起動していれば、現在の接続先であるMIC(node2)を停止することで、MIC(node3)のweightよりもMIC(node1)のweightが高いため、フェイルバックされるはずです。
ここで気をつけたいのが、以下のドキュメントの記載に当てはまる場合、一度停止したサーバではレプリケーションユーザの認証情報のキャッシュが消えてしまい、認証に失敗します。
https://dev.mysql.com/doc/refman/8.0/en/change-master-to.html
重要
caching_sha2_passwordプラグインで 認証されるレプリケーションユーザーアカウントを使用してソースに接続するには、 17.3.1項「暗号化された接続を使用するためのレプリケーションの設定」の説明に従って安全な接続を 設定するか、暗号化されていない接続を有効にしてパスワードをサポートする必要があります。
RSAキーペアを使用して交換します。 caching_sha2_password認証プラグインは、MySQL 8.0から作成された新規ユーザーのデフォルトです(詳細については、参照 セクション6.4.1.2を、「キャッシュSHA-2のPluggable Authentication」)。作成またはレプリケーションに使用するユーザーアカウントの場合(MASTER_USER オプション)はこの認証プラグインを使用し、安全な接続を使用していない場合、接続を成功させるにはRSAキーペアベースのパスワード交換を有効にする必要があります。
非SSLレプリケーション接続(デフォルト)をご利用の場合は、レプリケーションユーザの認証プラグインをmysql_native_passwordとすることをおすすめします。
1 2 |
$ ~/sandboxes/gr8022/n2 -e "alter user 'msandbox'@'127.0.0.1' identified with mysql_native_password by 'msandbox'" $ ~/sandboxes/single8022/use -e "stop replica;start replica" |
MIC(node2)を停止すると、weightの高いMIC(node1)にフェイルオーバしました。
1 2 3 |
$ ~/sandboxes/gr8022/node2/stop $ ~/sandboxes/single8022/use -e "show replica status\G" | grep -i source_port Source_Port: 23223 |
このように、暗黙的に意図したソースへフェイルオーバ、フェイルバックを行いたい場合は、weightを活用するとよいかと思います。
なおマニュアルが介在するのであれば、今まで通りレプリカを停止後 CHANGE MASTER TO MASTER_HOST = <フェイルバック先 IP>
を実行しレプリカを起動してソースの切り替えをすることをおすすめします。
レプリカの複製
ドキュメントを見ると、Remote Cloneで作成したレプリカにはDONERのSOURCE_CONNECTION_AUTO_FAILOVERとmysql.replication_asynchronous_connection_failoverが引き継がれるようです。
The setting for the SOURCE_CONNECTION_AUTO_FAILOVER option of the CHANGE MASTER TO statement, and the source list, are transferred to a clone of the replica during a remote cloning operation.
Clone Pluginをインストールし、既存のレプリカをDONERとして新しいレプリカを作成します。
Clone Pluginの使用方法は弊社の記事を参考にして頂ければ幸いです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# Configure New Single Instance $ dbdeployer deploy single --remote-access=% --bind-address=0 --gtid --sandbox-directory=new8022 8.0.22 # Install Clone Plugin $ ~/sandboxes/single8022/use -e "INSTALL PLUGIN clone SONAME 'mysql_clone.so'" $ ~/sandboxes/new8022/use -e "INSTALL PLUGIN clone SONAME 'mysql_clone.so'" # GR to Single replication configuration $ ~/sandboxes/new8022/use -e "SET GLOBAL clone_valid_donor_list = '127.0.0.1:8022'" # Cloning $ ~/sandboxes/new8022/use -e "CLONE INSTANCE FROM msandbox@127.0.0.1:8022 IDENTIFIED BY 'msandbox'" $ ~/sandboxes/new8022/use -e "select source, begin_time, end_time, state from performance_schema.clone_status" +----------------+-------------------------+-------------------------+-----------+ | source | begin_time | end_time | state | +----------------+-------------------------+-------------------------+-----------+ | 127.0.0.1:8022 | 2020-10-27 16:00:20.936 | 2020-10-27 16:00:36.527 | Completed | +----------------+-------------------------+-------------------------+-----------+ # Start Replication $ ~/sandboxes/new8022/use -e "START REPLICA" |
確かに設定が引き継がれているようです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$ ~/sandboxes/new8022/use -e "select Host, Port, Source_connection_auto_failover from mysql.slave_master_info" +-----------+-------+---------------------------------+ | Host | Port | Source_connection_auto_failover | +-----------+-------+---------------------------------+ | 127.0.0.1 | 23223 | 1 | +-----------+-------+---------------------------------+ $ ~/sandboxes/new8022/use -e "select * from mysql.replication_asynchronous_connection_failover" +--------------+-----------+-------+-------------------+--------+ | Channel_name | Host | Port | Network_namespace | Weight | +--------------+-----------+-------+-------------------+--------+ | | 127.0.0.1 | 23223 | | 100 | | | 127.0.0.1 | 23224 | | 100 | | | 127.0.0.1 | 23225 | | 80 | +--------------+-----------+-------+-------------------+--------+ |
MIC(node1)を停止すると、正常にフェイルオーバが行われました。
1 2 3 4 5 6 7 |
$ ~/sandboxes/gr8022/node1/stop $ ~/sandboxes/new8022/use -e "select Host, Port, Source_connection_auto_failover from mysql.slave_master_info" +-----------+-------+---------------------------------+ | Host | Port | Source_connection_auto_failover | +-----------+-------+---------------------------------+ | 127.0.0.1 | 23224 | 1 | +-----------+-------+---------------------------------+ |
基本的にはシンプルな機能ということもあり、特に気になることもなく非常に安定感を感じました。
様々なトポロジでの利用
機能自体は特にMICに限定されたものでは無く、レプリカ側のバージョンが8.0.22であれば利用可能であるため、Galera ClusterやDRBDをソースとした環境、多段レプリケーションで中間マスタが停止した場合の保険として利用する事等、幅広い用途が考えられます。
Galera Cluster + Async Replica
Async Replica(Source + 2 Replica)
フェイルオーバ先の第一候補でないレプリカのソース候補を指定しておくことでトポロジが保たれます。
Multi Source Replication
例えばマルチソースレプリケーションを使用している環境ではチャネル毎にソース候補を登録しておくことで冗長性が保たれます。
例では対向環境におけるF/O先のレプリカをソース候補とし、レプリカはマルチソースレプリケーションを使用しています。
所感
従来からのMySQLの強みであるレプリケーション機能がより自律的になり、Clone Pluginと合わせて使用することで、
マルチサイト、マルチリージョン、マルチクラウドでの運用の敷居が低くなるように思いました。
また、小規模な環境でも本機能を導入することで、障害発生時にレプリカのことを気にせずにソースの復旧に注力できるのではないでしょうか。
今後もMySQLの高可用性界隈の機能に注目していきたいと思います!