MySQL Shell 9.0  /  MySQL AdminAPI  /  标记元数据

6.9 标记元数据

提供了一个可配置的标记框架,允许使用附加信息标记 InnoDB Cluster、InnoDB ClusterSet 或 InnoDB ReplicaSet 的元数据。 标记可以将自定义键值对与集群、副本集或实例相关联。 已保留标记供 MySQL Router 使用,这使得兼容的 MySQL Router 能够支持对应用程序隐藏实例。 以下标记为此目的保留

  • _hidden 指示 MySQL Router:从客户端应用程序的可能目标列表中排除该实例。

  • _disconnect_existing_sessions_when_hidden:指示路由器断开与标记为隐藏的实例的现有连接。

有关更多信息,请参见 从路由中移除实例

此外,标记框架是用户可配置的。 自定义标记可以包含任何 ASCII 字符,并提供一个 命名空间,它充当可以与集群、副本集或其特定实例相关联的字典键值对。 标记值可以是任何 JSON 值。 此配置使您能够在元数据之上添加自己的属性。

显示标记

Cluster.options() 操作显示有关分配给各个集群实例以及集群本身的标记的信息。 例如,分配给 myCluster 的 InnoDB Cluster 可以显示

mysql-js> myCluster.options()
{
    "cluster": {
        "name": "test1",
        "tags": {
            "ic-1:3306": [
                {
                    "option": "_disconnect_existing_sessions_when_hidden",
                    "value": true
                },
                {
                    "option": "_hidden",
                    "value": false
                }
            ],
            "ic-2:3306": [],
            "ic-3:3306": [],
            "global": [
                {
                    "option": "location:",
                    "value": "US East"
                }
            ]
        }
    }
}

此集群有一个名为 location 的全局标记,其值为 US East,并且实例 ic-1 已被标记。

在集群实例上设置标记

您可以在实例级别设置标记,例如,这使您能够将实例标记为不可用,以便应用程序和路由器将其视为脱机。 使用 Cluster.setInstanceOption(instance, option, value) 操作为实例设置标记的值。

instance 参数是目标实例的连接字符串。 option 参数必须是格式为 namespace:option 的字符串。 value 参数是应在指定的 命名空间 中分配给 option 的值。 如果该值为 null,则从指定的 命名空间 中删除 option。 对于属于集群的实例,setInstanceOption() 操作仅接受 tag 命名空间。 任何其他命名空间都会导致 ArgumentError

例如,要使用 JavaScript 在 myCluster 实例 ic-1 上将标记 test 设置为 true,请发出

mysql-js> myCluster.setInstanceOption("icadmin@ic-1:3306", "tag:test", true);

或者使用 Python 在 myCluster 实例 ic-1 上将标记 test 设置为 true,请发出

mysql-py> myCluster.set_instance_option("icadmin@ic-1:3306", "tag:test", True);

从路由中移除实例

当 AdminAPI 和 MySQL Router 一起工作时,它们支持特定的标记,使您能够将实例标记为隐藏并将其从路由中移除。 然后,MySQL Router 会从路由目标候选列表中排除此类标记的实例。 此功能使您能够安全地使服务器实例脱机,以便应用程序和 MySQL Router 忽略它。 例如,当您执行维护任务时,例如服务器升级或配置更改。

_hidden 标记设置为 true 时,这会指示 MySQL Router 从客户端应用程序的可能目标列表中排除该实例。 实例保持在线状态,但不会路由到新的传入连接。 _disconnect_existing_sessions_when_hidden 标记控制如何关闭与实例的现有连接。 此标记假定为 true,并且它指示针对 InnoDB Cluster、InnoDB ClusterSet 或 InnoDB ReplicaSet 引导的任何 MySQL Router 实例在 _hidden 标记为 true 时断开与实例的任何现有连接。

_disconnect_existing_sessions_when_hidden 为 false 时,如果 _hidden 为 true,则不会关闭与实例的任何现有客户端连接。 保留的 _hidden_disconnect_existing_sessions_when_hidden 标记特定于实例,不能在集群级别使用。

警告

use_gr_notifications MySQL Router 选项启用时,它默认为 60 秒。 这意味着当您设置标记时,MySQL Router 最多需要 60 秒才能检测到更改。 要减少等待时间,请将 use_gr_notifications 更改为较低的值。

例如,假设您要从路由目标中移除作为分配给 myCluster 的 InnoDB Cluster 一部分的 ic-1 实例。 使用 setInstanceOption() JavaScript 操作来启用 _hidden_disconnect_existing_sessions_when_hidden 标记

mysql-js> myCluster.setInstanceOption("icadmin@ic-1:3306", "tag:_hidden", true);

或者使用 set_instance_option() Python 操作来启用 _hidden_disconnect_existing_sessions_when_hidden 标记

			mysql-js> myCluster.set_instance_option("icadmin@ic-1:3306", "tag:_hidden", true);

您可以通过检查选项来验证元数据中的更改。 例如,对 ic-1 所做的更改将在选项中显示为

mysql-js> myCluster.options()
{
    "cluster": {
        "name": "test1",
        "tags": {
            "ic-1:3306": [
                {
                    "option": "_disconnect_existing_sessions_when_hidden",
                    "value": true
                },
                {
                    "option": "_hidden",
                    "value": true
                }
            ],
            "ic-2:3306": [],
            "ic-3:3306": [],
            "global": []
        }
    }
}

您可以通过查看日志文件来验证 MySQL Router 是否已检测到元数据中的更改。 检测到对 ic-1 所做的更改的 MySQL Router 将显示如下更改

2020-07-03 16:32:16 metadata_cache INFO [7fa9d164c700] Potential changes detected in cluster 'testCluster' after metadata refresh
2020-07-03 16:32:16 metadata_cache INFO [7fa9d164c700] view_id = 4, (3 members)
2020-07-03 16:32:16 metadata_cache INFO [7fa9d164c700]     ic-1:3306 / 33060 - mode=RW
2020-07-03 16:32:16 metadata_cache INFO [7fa9d164c700]     ic-1:3306 / 33060 - mode=RO
2020-07-03 16:32:16 metadata_cache INFO [7fa9d164c700]     ic-1:3306 / 33060 - mode=RO hidden=yes disconnect_when_hidden=yes
2020-07-03 16:32:16 routing INFO [7fa9d164c700] Routing routing:testCluster_x_ro listening on 64470 got request to disconnect invalid connections: metadata change
2020-07-03 16:32:16 routing INFO [7fa9d164c700] Routing routing:testCluster_x_rw listening on 64460 got request to disconnect invalid connections: metadata change
2020-07-03 16:32:16 routing INFO [7fa9d164c700] Routing routing:testCluster_rw listening on 6446 got request to disconnect invalid connections: metadata change
2020-07-03 16:32:16 routing INFO [7fa9d164c700] Routing routing:testCluster_ro listening on 6447 got request to disconnect invalid connections: metadata change

要使实例恢复在线状态,请使用 setInstanceOption() 操作删除标记,MySQL Router 会自动将实例添加回路由目标,并且它会为应用程序联机。 例如

mysql-js> myCluster.setInstanceOption(icadmin@ic-1:3306, "tag:_hidden", false);

再次检查选项以验证元数据中的更改

mysql-js> myCluster.options()
{
    "cluster": {
        "name": "test1",
        "tags": {
            "ic-1:3306": [
                {
                    "option": "_disconnect_existing_sessions_when_hidden",
                    "value": true
                },
                {
                    "option": "_hidden",
                    "value": false
                }
            ],
            "ic-2:3306": [],
            "ic-3:3306": [],
            "global": []
        }
    }
}

您还可以使用以下命令输出中的属性 hiddenFromRouter 查看成员的 _hidden 状态

  • Cluster.status()

  • Cluster.describe()

  • ReplicaSet.status()

对于使用 _hidden 元数据标记从 MySQL Router 流量中隐藏的任何成员,此属性均为 true

在集群上设置标记

Cluster.setOption(option, value) 操作使您能够更改整个集群的命名空间选项的值。 option 参数必须是格式为 namespace:option 的字符串。

value 参数是要在指定的 命名空间 中分配给 option 的值。 如果该值为 null,则从指定的 命名空间 中删除 option。 对于集群,setOption() 操作接受 tag 命名空间。 任何其他命名空间都会导致 ArgumentError

提示

在集群级别设置的标记不会覆盖在实例级别设置的标记。 您不能使用 Cluster.setOption() 删除在实例级别设置的所有标记。

不要求所有实例都处于联机状态,只需集群具有仲裁即可。 要使用设置为 US East 的 location 标记标记分配给 myCluster 的 InnoDB Cluster,请在 JavaScript 中发出以下内容

mysql-js> myCluster.setOption("tag:location", "US East")
mysql-js> myCluster.options()
{
    "cluster": {
        "name": "test1",
        "tags": {
            "ic-1:3306": [],
            "ic-2:3306": [],
            "ic-3:3306": [],
            "global": [
                {
                    "option": "location:",
                    "value": "US East"
                }
            ]
        }
    }
}

或在 Python 中发出以下内容

mysql-py> myCluster.set_option("tag:location", "US East")
mysql-pys> myCluster.options()
{
    "cluster": {
        "name": "test1",
        "tags": {
            "ic-1:3306": [],
            "ic-2:3306": [],
            "ic-3:3306": [],
            "global": [
                {
                    "option": "location:",
                    "value": "US East"
                }
            ]
        }
    }
}

从集群中移除标记

要从集群中移除标记,请在 JavaScript 中使用值为 nullCluster.setOption(option, value) 操作,并在 Python 中使用值为 None 的操作。

要使用 location 标记从分配给 myCluster 的 InnoDB Cluster 中移除标记,请在 JavaScript 中发出以下内容

mysql-js> myCluster.setOption("tag:location", null)

或使用 Python

mysql-js> myCluster.set_option("tag:location", None)

用户定义的标记

AdminAPI 支持 tag 命名空间,您可以在其中存储与给定集群、副本集或实例关联的键值对中的信息。 tag 命名空间下的选项不受约束,这意味着只要它是有效的 MySQL ASCII 标识符,您就可以使用您选择的任何信息进行标记。

您可以为标记使用任何名称和值,只要该名称遵循以下语法:_ 或字母后跟字母数字和 _ 字符。

namespace 选项是一个用冒号分隔的字符串,格式为 namespace:option,其中 namespace 是命名空间的名称,option 是实际的选项名称。 您可以在实例级别或集群或副本集级别设置和删除标记。

标签名称可以是任何值,只要以字母或下划线开头,可选后跟字母数字和 _ 字符,例如 ^[a-zA-Z_][0-9a-zA-Z_]*。只有内置标签允许以下划线 _ 字符开头。

如何使用自定义标签取决于您。您可以在集群上设置自定义标签以标记集群的位置。例如,在集群上设置名为 location 的自定义标签,其值为 EMEA