最近は、弊社のブログでもよく情報を発信している MySQL InnoDB Cluster ですが、実稼働システムでの採用事例も徐々に増えているのではないでしょうか。
今回は、MySQL 8.0.13 の MySQL InnoDB Cluster にインスタンスを追加し、追加したインスタンスに MySQL Router からルーティングされるまでの確認をしてみたいと思います。
同バージョンでの MySQL InnoDB Cluster を構築する方法については、以下の記事をご参照下さい。
MySQL 8.0.13 で MySQL InnoDB Cluster を構築する
構成
VirtualBox+Vagrantを使用し、MySQL Router と MySQL Shell は同一サーバにインストールしています。
マシン | IP | ホスト名 |
---|---|---|
MySQL Router MySQL Shell |
192.168.33.10 | mysqlrouter |
MySQL Server 1 | 192.168.33.11 | node1 |
MySQL Server 2 | 192.168.33.12 | node2 |
MySQL Server 3 | 192.168.33.13 | node3 |
MySQL Server 4 (追加するインスタンス) |
192.168.33.14 | node4 |
※本来、MySQL InnoDB Cluster ではスプリットブレイン等を考慮して、3台以上の奇数でのグループ構成を推奨しています。
構成の状態確認 (インスタンス追加前)
以下のように、node1, 2, 3 の Single Primary モードの3台構成で、 node1 が PRIMARY の状態です。
1 2 3 4 5 6 7 8 9 |
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 | 06b571d4-fc39-11e8-b941-0800278bc93f | node1 | 3306 | ONLINE | PRIMARY | 8.0.13 | | group_replication_applier | 073d6303-fc39-11e8-b0f0-0800278bc93f | node2 | 3306 | ONLINE | SECONDARY | 8.0.13 | | group_replication_applier | 076bd2d8-fc39-11e8-b16c-0800278bc93f | node3 | 3306 | ONLINE | SECONDARY | 8.0.13 | +---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+ 3 rows in set (0.00 sec) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
MySQL 192.168.33.11:33060+ ssl JS > cluster.status() { "clusterName": "mycluster", "defaultReplicaSet": { "name": "default", "primary": "192.168.33.11:3306", "ssl": "REQUIRED", "status": "OK", "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.", "topology": { "192.168.33.11:3306": { "address": "192.168.33.11:3306", "mode": "R/W", "readReplicas": {}, "role": "HA", "status": "ONLINE" }, "192.168.33.12:3306": { "address": "192.168.33.12:3306", "mode": "R/O", "readReplicas": {}, "role": "HA", "status": "ONLINE" }, "192.168.33.13:3306": { "address": "192.168.33.13:3306", "mode": "R/O", "readReplicas": {}, "role": "HA", "status": "ONLINE" } } }, "groupInformationSourceMember": "mysql://root@192.168.33.11:3306" } |
インスタンスの追加
現時点で SECONDARY が node2, 3 の2台ですが、node4 を追加します。
また、既存インスタンスには、100,000 件のレコードが存在するテーブルが存在しています。
1 2 3 4 5 6 7 |
mysql> select count(*) from test.t1; +----------+ | count(*) | +----------+ | 100000 | +----------+ 1 row in set (0.01 sec) |
まずは、MySQL Router サーバにインストールした MySQL Shell で「dba.configureInstance()」 を実行し、node4 のパラメータを変更します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
[vagrant@mysqlrouter ~]$ mysqlsh MySQL Shell 8.0.13 Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type '\help' or '\?' for help; '\quit' to exit. MySQL JS > dba.configureInstance('root@192.168.33.14') Please provide the password for 'root@192.168.33.14': ************** Save password for 'root@192.168.33.14'? [Y]es/[N]o/Ne[v]er (default No): Y Configuring MySQL instance at 192.168.33.14:3306 for use in an InnoDB cluster... This instance reports its own address as node4 Clients and other cluster members will communicate with it through this address by default. If this is not correct, the report_host MySQL system variable should be changed. The instance '192.168.33.14:3306' is valid for InnoDB cluster usage. MySQL JS > |
今回は事前に必要な server_id 等の設定を my.cnf にしていた為、変更パラメータはなしとなります。
次に MySQL Shell で既存インスタンスのいずれかに接続し、
「cluster = dba.getCluster()」 → 「cluster.addInstance()」 を実行して node4 を追加します。
本来であれば、事前に追加インスタンスへフルバックアップからリストアする作業が必要になりますが、今回は既存インスタンスに Cluster 構築時からのバイナリログが全て残っている為、リストア作業は不要な状態となっています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
[vagrant@mysqlrouter ~]$ mysqlsh MySQL Shell 8.0.13 Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type '\help' or '\?' for help; '\quit' to exit. MySQL JS > \c root@192.168.33.11 Creating a session to 'root@192.168.33.11' Please provide the password for 'root@192.168.33.11': ************** MySQL 192.168.33.11:33060+ ssl JS > cluster = dba.getCluster() <Cluster:mycluster> MySQL 192.168.33.11:33060+ ssl JS > cluster.addInstance('root@192.168.33.14') A new instance will be added to the InnoDB cluster. Depending on the amount of data on the cluster this might take from a few seconds to several hours. Adding instance to the cluster ... Validating instance at 192.168.33.14:3306... This instance reports its own address as node4 Instance configuration is suitable. The instance 'root@192.168.33.14' was successfully added to the cluster. |
コマンドが正常終了したので、インスタンスが正常に追加されているか確認してみます。
構成の状態確認 (インスタンス追加後)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
MySQL 192.168.33.11:33060+ ssl JS > cluster.status() { "clusterName": "mycluster", "defaultReplicaSet": { "name": "default", "primary": "192.168.33.11:3306", "ssl": "REQUIRED", "status": "OK", "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.", "topology": { "192.168.33.11:3306": { "address": "192.168.33.11:3306", "mode": "R/W", "readReplicas": {}, "role": "HA", "status": "ONLINE" }, "192.168.33.12:3306": { "address": "192.168.33.12:3306", "mode": "R/O", "readReplicas": {}, "role": "HA", "status": "ONLINE" }, "192.168.33.13:3306": { "address": "192.168.33.13:3306", "mode": "R/O", "readReplicas": {}, "role": "HA", "status": "ONLINE" }, "192.168.33.14:3306": { "address": "192.168.33.14:3306", "mode": "R/O", "readReplicas": {}, "role": "HA", "status": "ONLINE" } } }, "groupInformationSourceMember": "mysql://root@192.168.33.11:3306" } |
1 2 3 4 5 6 7 8 9 10 |
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 | 06b571d4-fc39-11e8-b941-0800278bc93f | node1 | 3306 | ONLINE | PRIMARY | 8.0.13 | | group_replication_applier | 073d6303-fc39-11e8-b0f0-0800278bc93f | node2 | 3306 | ONLINE | SECONDARY | 8.0.13 | | group_replication_applier | 076bd2d8-fc39-11e8-b16c-0800278bc93f | node3 | 3306 | ONLINE | SECONDARY | 8.0.13 | | group_replication_applier | 5c5cf0ba-fc3d-11e8-8468-0800278bc93f | node4 | 3306 | ONLINE | SECONDARY | 8.0.13 | +---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+ 4 rows in set (0.01 sec) |
正常にインスタンスが追加されている事が確認できます。
MySQL Shell で「cluster.status()」を実行した際に、 192.168.33.14 (node4) の「status」は 100,000 件のデータが反映されるまでは RECOVERING
となっており、ONLINE
となるまでは2分30秒程かかりました。
MySQL Router のルーティングについて
インスタンス追加前から MySQL Router の READ ONLY のポートに常時接続をしていると、node4 のステータスが ONLINE
になったのとほぼ同時に自動的に node4 へのルーティングも追加され、100,000 件のデータも参照できています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
[vagrant@mysqlrouter ~]$ while :; do mysql -h 127.0.0.1 -P 6447 -e "select @@hostname, count(*) from test.t1"; done ・・・(省略) +------------+----------+ | @@hostname | count(*) | +------------+----------+ | node2 | 100000 | +------------+----------+ +------------+----------+ | @@hostname | count(*) | +------------+----------+ | node3 | 100000 | +------------+----------+ +------------+----------+ | @@hostname | count(*) | +------------+----------+ | node2 | 100000 | +------------+----------+ +------------+----------+ | @@hostname | count(*) | +------------+----------+ | node3 | 100000 | +------------+----------+ +------------+----------+ | @@hostname | count(*) | +------------+----------+ | node4 | 100000 | (node4へルーティングされるようになる) +------------+----------+ +------------+----------+ | @@hostname | count(*) | +------------+----------+ | node2 | 100000 | +------------+----------+ +------------+----------+ | @@hostname | count(*) | +------------+----------+ | node3 | 100000 | +------------+----------+ +------------+----------+ | @@hostname | count(*) | +------------+----------+ | node4 | 100000 | +------------+----------+ ・・・(省略) |
しかし、このままだと node1 から node3 までが停止して、node4 だけがアクティブな状態になると、MySQL Router からはルーティングされません。
(期待する動作は node4 がPRIMARYノードになって、READ/WRITE のポートへのアクセスが node4 にルーティングされることでした)
何故かというと、MySQL Router の InnoDB Cluster 構築時に実行した bootstrap オプションを指定して設定ファイルを作成した場合、以下のような設定となっています。
1 2 3 4 5 6 7 8 9 |
[vagrant@mysqlrouter ~]$ sudo cat /etc/mysqlrouter/mysqlrouter.conf ・・・(省略) [metadata_cache:mycluster] router_id=1 bootstrap_server_addresses=mysql://192.168.33.11:3306,mysql://192.168.33.12:3306,mysql://192.168.33.13:3306 user=mysql_router1_iswgnw9ak1if metadata_cluster=mycluster ttl=0.5 ・・・(省略) |
bootstrap_server_addresses にはメタ情報を取得するインスタンスの情報があり、ここに指定のないサーバからはメタ情報を取得できない為、ルーティング情報が取得できない状態になります。
なので、今回のケースであれば、以下のように追加したインスタンス(node4:192.168.33.14)情報を追加して、MySQL Router を再起動すれば、 node4 のみになった場合は、READ WRITE のポートへのアクセスが正常に node4 に割り振られるようになります。
1 |
bootstrap_server_addresses=mysql://192.168.33.11:3306,mysql://192.168.33.12:3306,mysql://192.168.33.13:3306,mysql://192.168.33.14:3306 |
まとめ
MySQL InnoDB Cluster にインスタンスを追加した場合は、MySQL Router の設定ファイルで bootstrap_server_addresses の更新が必要である事を確認しましたが、MySQL 8.0.13から dynamic_config なるパラメータが追加され、動的にメタ情報を取得できるようなオプションが追加されているようです。
しかし、現時点(2018年12月11日)でリファレンスマニュアルには、dynamic_config で設定するパラメータファイルの情報がなく、使用方法が不明な状況です。
今後、リファレンスマニュアルが更新されれば、dynamic_config の動作についても確認してみようと思います。