はじめに
2020 年 1 月 13 日に MySQL Shell 8.0.19 がリリースされました。今回は、ここでリリースされている新機能について過去バージョンとの比較をしながら調査をおこないました。
新機能について
MySQL Shell 8.0.19 でリリースされた機能は大きく分けて以下の通りです。
- InnoDB ReplicaSet に関する管理 API を追加。
- メタデータスキーマ(mysql_innodb_cluster_metadata) が Ver.2.0 にアップグレード。
- MySQL Router に関する管理 API を追加。
このうち、InnoDB ReplicaSet については以前にも当ブログで紹介しているので説明を省略します。ここでは、残りの 2 つの機能について詳細を確認していたいと思います。
環境
以下の環境を使用して MySQL InnoDB Cluster を構築します。
※構築方法は以前に当ブログで紹介した手順を使用しています。
- MySQL Server 8.0.19
- MySQL Shell 8.0.18 / MySQL Shell 8.0.19
- MySQL Router 8.0.18 / MySQL Router 8.0.19
メタデータスキーマのアップグレード
MySQL Server 8.0.19 による InnoDB ReplicaSet 機能の実装などにともない、メタデータ情報が格納されている mysql_innodb_cluster_metadata データベースの構成が変化(Ver.1.0.1 → Ver.2.0)しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
[MySQL Shell 8.0.18] mysql > SELECT * FROM mysql_innodb_cluster_metadata.schema_version; +-------+-------+-------+ | major | minor | patch | +-------+-------+-------+ | 1 | 0 | 1 | +-------+-------+-------+ 1 row in set (0.0006 sec) mysql > SHOW TABLES FROM mysql_innodb_cluster_metadata; +-----------------------------------------+ | Tables_in_mysql_innodb_cluster_metadata | +-----------------------------------------+ | clusters | | hosts | | instances | | replicasets | | routers | | schema_version | +-----------------------------------------+ 6 rows in set (0.0029 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 |
[MySQL Shell 8.0.19] mysql> SELECT* FROM mysql_innodb_cluster_metadata.schema_version; +-------+-------+-------+ | major | minor | patch | +-------+-------+-------+ | 2 | 0 | 0 | +-------+-------+-------+ 1 row in set (0.00 sec) mysql > SHOW TABLES FROM mysql_innodb_cluster_metadata; +-----------------------------------------+ | Tables_in_mysql_innodb_cluster_metadata | +-----------------------------------------+ | async_cluster_members | | async_cluster_views | | clusters | | instances | | router_rest_accounts | | routers | | schema_version | | v2_ar_clusters | | v2_ar_members | | v2_clusters | | v2_gr_clusters | | v2_instances | | v2_router_rest_accounts | | v2_routers | | v2_this_instance | +-----------------------------------------+ 15 rows in set (0.0041 sec) |
Ver.2.0 にアップグレードされることで、主に以下のテーブルが追加あるいは変更されています。
- InnoDB RelicaSet のメタデータ情報 : 格納先が replicasets テーブルから async_cluster_* テーブルに変更。
- MySQL Router のメタデータ情報 : routers テーブルのカラム数が増加。 router_rest_accounts テーブルは MySQL Shell 8.0.19 では使用されていないようです。
- v2_% テーブル : 各メタデータ情報のビュー。 ar は Async Replication、gr は Group Replication の略称です。基本的にほぼ同じ内容ですが、ある程度情報がまとめて表示されています。
また、メタデータスキーマのバージョンアップに伴って、MySQL Shell 8.0.18 以前から MySQL Shell 8.0.19 にアップグレードした場合、読み取り操作以外は以下のようなエラーが出力されて実行できなくなってしまうので注意してください。
1 2 |
MySQL 192.168.153.9:3306 ssl JS > var cluster = dba.getCluster("mycluster") WARNING: No cluster change operations can be executed because the installed metadata version 1.0.1 is lower than the version required by Shell which is version 2.0.0. Upgrade the metadata to remove this restriction. See \? dba.upgradeMetadata for additional details. |
その場合、以下のような手順でアップグレードをおこなう必要があります。
- MySQL Shell 8.0.18 を MySQL Shell 8.0.19 にアップグレード。
- MySQL Router を 8.0.19 にアップグレード。
dba.upgradeMetadata()
を実行。
なお、 dba.upgradeMetadata()
を実行すると、アップグレードする MySQL Router が残っている場合は以下のような出力が表示されます。
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 |
JS > dba.upgradeMetadata() InnoDB Cluster Metadata Upgrade The cluster you are connected to is using an outdated metadata schema version 1.0.1 and needs to be upgraded to 2.0.0. Without doing this upgrade, no AdminAPI calls except read only operations will be allowed. NOTE: After the upgrade, this InnoDB Cluster/ReplicaSet can no longer be managed using older versions of MySQL Shell. The grants for the MySQL Router accounts that were created automatically when bootstrapping need to be updated to match the new metadata version's requirements. Updating Router accounts... NOTE: 5 Router accounts have been updated. WARNING: If MySQL Routers have been bootstrapped using custom accounts, the set of account privileges must be updated for them to match the following grants: GRANT EXECUTE, SELECT ON mysql_innodb_cluster_metadata.* TO <user>@<host> GRANT DELETE, INSERT, UPDATE ON mysql_innodb_cluster_metadata.routers TO <user>@<host> GRANT DELETE, INSERT, UPDATE ON mysql_innodb_cluster_metadata.v2_routers TO <user>@<host> GRANT SELECT ON performance_schema.global_variables TO <user>@<host> GRANT SELECT ON performance_schema.replication_group_member_stats TO <user>@<host> GRANT SELECT ON performance_schema.replication_group_members TO <user>@<host> An upgrade of all cluster router instances is required. All router installations should be updated first before doing the actual metadata upgrade. +-----------------+-----------+---------------+----------+----------+ | Instance | Version | Last Check-in | R/O Port | R/W Port | +-----------------+-----------+---------------+----------+----------+ | mysql_router:: | <= 8.0.18 | NULL | NULL | NULL | +-----------------+-----------+---------------+----------+----------+ There is 1 Router to upgrade. Please upgrade it and select Continue when done. 1) Re-check for outdated Routers and continue with the metadata upgrade. 2) Unregister the remaining Routers. 3) Abort the operation. 4) Help Please select an option: |
どの対応を行うか選択できますが、それぞれの内容は以下の通りです。
- MySQL Router を全て 8.0.19 以上にアップグレードしたので、アップグレードを継続する。
- 古い MySQL Router のメタデータ情報を切り捨ててアップグレードを実行する。
- アップグレードを中止する。
- もう一度この内容を出力する。
通常は接続している MySQL Router を全て 8.0.19 にアップグレードしてから 1 を選択すれば良いですが、もしメタデータ情報だけ残っていて使用しているかどうか不明な MySQL Router の情報がある場合などは、2 を選択してしまうのが良いかと思います。
1 2 3 4 5 6 7 |
Please select an option: 2 Unregistering a Router implies it will not be used in the Cluster, do you want to continue? [y/N]: y Upgrading metadata at 'chandra:3306' from version 1.0.1 to version 2.0.0. Creating backup of the metadata schema... Step 1 of 1: upgrading from 1.0.1 to 2.0.0... Removing metadata backup... Upgrade process successfully finished, metadata schema is now on version 2.0.0 |
2 を選択すると、古いバージョンの MySQL Router の情報は削除される旨の確認があった後、スキーマのアップグレードが完了します。ただし、ここで削除されるのは MySQL Router のメタデータ情報のみであり、MySQL Router との接続ユーザー(mysql_router*_************)は残ったままなので注意してください。
MySQL Router の管理 API
MySQL Shell 8.0.18 までは、MySQL Router のメタデータ情報を routers テーブルからのみ確認することができました。
1 2 3 4 5 6 7 |
mysql > SELECT * FROM mysql_innodb_cluster_metadata.routers; +-----------+-------------+---------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+ | router_id | router_name | host_id | attributes | +-----------+-------------+---------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+ | 1 | system | 4 | {"version": "8.0.18", "ROEndpoint": "6447", "RWEndpoint": "6446", "ROXEndpoint": "64470", "RWXEndpoint": "64460", "MetadataUser": "mysql_router1_n12rzws7e945"} | | 2 | test | 4 | {"version": "8.0.18", "ROEndpoint": "6447", "RWEndpoint": "6446", "ROXEndpoint": "64470", "RWXEndpoint": "64460", "MetadataUser": "mysql_router2_tjrfo8e8ddth"} | +-----------+-------------+---------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+ |
そのため、どの接続が現在使用されているか、既に使用しなくなっているものがあるかどうかなどは、 SHOW PROCESSLIST
コマンドで現在の状態を確認するくらいしか確かめる方法がなく、使わなくなったメタデータ情報がある場合には、該当のメタデータ情報やユーザー情報を手動で削除するか、諦めて放置するしかありませんでした。
MySQL Shell 8.0.19 からは、以下の API が追加されており、それぞれ MySQL Router のメタデータ情報を操作することが可能になっています。
[cluster/replicasetオブジェクト].listRouters()
現在の MySQL Router の接続を表示します。
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 |
JS > var cluster = dba.getCluster("mycluster") JS > cluster.listRouters() { "clusterName": "mycluster", "routers": { "mysql_router::system": { "hostname": "mysql_router", "lastCheckIn": "2020-04-06 16:39:26", "roPort": 6447, "roXPort": 64470, "rwPort": 6446, "rwXPort": 64460, "version": "8.0.19" }, "mysql_router::test": { "hostname": "mysql_router", "lastCheckIn": null, "roPort": 6447, "roXPort": 64470, "rwPort": 6446, "rwXPort": 64460, "version": "8.0.19" } } } |
MySQL Shell 8.0.18 との違いは lastCheckIn
が追加されていることです。この項目により、最後に MySQL Router からの接続(疎通確認)がいつ来たかを確認することが可能になっています。そのため、この内容がかなり前の日付になっていたり、そもそも null になっている場合は、現在使用されていない接続である可能性が高いと推測することができます。
[cluster/replicasetオブジェクト].removeRouterMetadata()
上記のように不要な接続を確認することができたら、 removeRouterMetadata("Routername")
でその情報を削除することができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
JS > cluster.removeRouterMetadata("mysql_router::test") JS > cluster.listRouters() { "clusterName": "mycluster", "routers": { "mysql_router::system": { "hostname": "mysql_router", "lastCheckIn": "2020-04-06 16:45:10", "roPort": 6447, "roXPort": 64470, "rwPort": 6446, "rwXPort": 64460, "version": "8.0.19" } } } |
これでユーザー管理の煩雑さからも解放…されると思いきや、MySQL Router の接続ユーザーはしっかりと残っているようです。
1 2 3 4 5 6 7 8 9 10 |
mysql > SELECT user,host FROM mysql.user; +---------------------------------+-----------+ | user | host | +---------------------------------+-----------+ (...) | mysql_router1_n12rzws7e945 | % | | mysql_router2_tjrfo8e8ddth | % | (...) +---------------------------------+-----------+ 12 rows in set (0.0019 sec) |
そのため、メタデータ情報を削除した MySQL Router を再び立ち上げると、問題なく接続することができてしまいます。
1 2 3 4 5 6 7 8 9 10 |
# mysqlrouter -c /tmp/mysqlrouter/mysqlrouter.conf& logging facility initialized, switching logging to loggers specified in configuration [1] 2131 # mysql -utest -h127.0.0.1 -pMySQL8.0 -P6447 -e "SELECT @@hostname;" mysql: [Warning] Using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | node2 | +------------+ |
したがって、MySQL Shell 8.0.19 においても、不要になった MySQL Router のユーザーは適宜手動で削除するか、放置して増えるがままに任せるしかないようです。
まとめ
ここまで、MySQL Shell 8.0.19 における新機能やその内容について確認してきました。機能についてはまだ痒い所に手が届いていないですが、徐々に機能も拡充されてきており、大きなバグも取れてきている印象を受けます。
※ここでは説明を省きますが、MySQL Shell 8.0.18 までは、autocommit=0 のときに正常にクラスタ―を構築できず、各種の操作(removeInstance()など)にも影響が出てしまうバグ(Bug #30202883, Bug #30324461)などが存在しています
まだまだ新機能が追加されている MySQL 8.0 において、これからの更新と改善には引き続き注目していきたいところです。