MySQL Shell 8.4  /  MySQL InnoDB 集群  /  修改或解散 InnoDB 集群

7.9 修改或解散 InnoDB 集群

本节介绍如何将 InnoDB 集群从单主模式更改为多主模式,反之亦然,如何从 InnoDB 集群中删除服务器实例,以及如何解散不再需要的 InnoDB 集群。

更改集群的拓扑

默认情况下,InnoDB 集群在单主模式下运行,其中集群有一个主服务器接受读写查询(R/W),集群中的所有其余实例只接受读查询(R/O)。当您将集群配置为在多主模式下运行时,集群中的所有实例都是主实例,这意味着它们接受读写查询(R/W)。如果集群中的所有实例都运行 MySQL 服务器版本 8.0.15 或更高版本,则可以在集群在线时更改集群的拓扑。在以前的版本中,需要完全解散并重新创建集群才能进行配置更改。这使用通过配置在线组中描述的函数公开的组操作协调器,因此您应该遵守配置在线组的规则。

注意

多主模式被认为是一种高级模式。

通常,当当前主服务器意外离开集群时(例如,由于意外停止),单主集群会选举一个新的主服务器。选举过程通常用于选择当前的哪个辅助服务器成为新的主服务器。要覆盖选举过程并强制底层组复制组中的特定服务器实例成为新的主服务器,请使用Cluster.setPrimaryInstance(instance[, options) 函数,其中instance 指定应成为新的主服务器的实例的连接。您可以使用runningTransactionsTimeout 选项为使用该函数时正在运行的事务添加 0 到 3600 秒的超时。设置超时后,发出命令后的传入事务将被拒绝。

您可以使用以下操作更改集群在其运行的单主模式和多主模式之间的模式(有时称为拓扑)

  • Cluster.switchToMultiPrimaryMode(),将集群切换到多主模式。所有实例都成为主实例。

  • Cluster.switchToSinglePrimaryMode([instance]),将集群切换到单主模式。如果指定了instance,则它将成为主实例,所有其他实例都将成为辅助实例。如果未指定instance,则新的主实例是成员权重最高(如果成员权重相同,则为 UUID 最低)的实例。

从 InnoDB 集群中删除实例

如果需要,您可以随时从集群中删除实例。这可以使用Cluster.removeInstance(instance) 方法完成,如下例所示

mysql-js> cluster.removeInstance('root@localhost:3310')

The instance will be removed from the InnoDB cluster. Depending on the instance
being the Seed or not, the Metadata session might become invalid. If so, please
start a new session to the Metadata Storage R/W instance.

Attempting to leave from the Group Replication group...

The instance 'localhost:3310' was successfully removed from the cluster.

cluster.removeInstance() 操作可确保从所有处于ONLINE 状态的集群成员以及实例本身的元数据中删除该实例。无法使用此操作删除 InnoDB 集群中最后一个处于ONLINE 状态的实例。

当要删除的实例具有仍需应用的事务时,AdminAPI 将等待 MySQL Shell dba.gtidWaitTimeout 选项配置的秒数,以便应用事务(GTID)。MySQL Shell dba.gtidWaitTimeout 选项的默认值为 60 秒,有关更改默认值的更多信息,请参阅第 13.4 节“配置 MySQL Shell 选项”。如果在等待应用事务时达到dba.gtidWaitTimeout 定义的超时值并且force 选项为false(或未定义),则会发出错误并中止删除操作。如果在等待应用事务时达到dba.gtidWaitTimeout 定义的超时值并且force 选项设置为true,则操作将继续进行,不会出现错误,并从集群中删除该实例。

注意

Cluster.removeInstance(instance) force 选项强制从集群的元数据中删除该实例。如果该实例不再是成员,但仍注册为集群的一部分,则此选项非常有用。此选项对正常的、可联系的实例没有影响,并且仅影响无法访问的实例或无法与集群同步的实例。

解散 InnoDB 集群

要解散 InnoDB 集群,您可以连接到读写实例(例如,单主集群中的主实例),并使用Cluster.dissolve() 命令。这将删除与集群关联的所有元数据和配置,并在实例上禁用组复制。不会删除在实例之间复制的任何数据。

重要

无法撤消集群的解散。要重新创建它,请使用dba.createCluster()

Cluster.dissolve() 操作只能配置处于ONLINE 状态或可访问的实例。如果在您发出Cluster.dissolve() 命令的成员无法访问集群的成员,则必须决定如何继续进行解散操作。如果您希望重新加入从集群中识别为丢失的任何实例,强烈建议您取消解散操作,并首先使丢失的实例重新联机,然后再继续进行解散操作。这可确保所有实例的元数据都能正确更新,并且不会出现脑裂情况。但是,如果无法访问的集群实例已永久离开集群,则可能别无选择,只能强制执行解散操作,这意味着将忽略丢失的实例,并且只有联机实例才会受到该操作的影响。

警告

强制解散操作忽略集群实例可能会导致在解散操作期间无法访问的实例继续运行,从而导致脑裂的风险。只有在您确定实例不可能再次联机的情况下,才能强制执行解散操作以忽略丢失的实例。

在交互模式下,如果在解散操作期间无法访问集群的成员,则会显示一个交互式提示,例如

mysql-js> Cluster.dissolve()
The cluster still has the following registered instances:
{
    "clusterName": "testCluster",
    "defaultReplicaSet": {
        "name": "default",
        "topology": [
            {
                "address": "ic-1:3306",
                "label": "ic-1:3306",
                "role": "HA"
            },
            {
                "address": "ic-2:3306",
                "label": "ic-2:3306",
                "role": "HA"
            },
            {
                "address": "ic-3:3306",
                "label": "ic-3:3306",
                "role": "HA"
            }
        ]
    }
}
WARNING: You are about to dissolve the whole cluster and lose the high
availability features provided by it. This operation cannot be reverted. All
members will be removed from the cluster and replication will be stopped,
internal recovery user accounts and the cluster metadata will be dropped. User
data will be maintained intact in all instances.

Are you sure you want to dissolve the cluster? [y/N]: y

ERROR: The instance 'ic-2:3306' cannot be removed because it is on a '(MISSING)'
state. Please bring the instance back ONLINE and try to dissolve the cluster
again. If the instance is permanently not reachable, then you can choose to
proceed with the operation and only remove the instance from the Cluster
Metadata.

Do you want to continue anyway (only the instance metadata will be removed)?
[y/N]: y

Instance 'ic-3:3306' is attempting to leave the cluster...  Instance 'ic-1:3306'
is attempting to leave the cluster...

WARNING: The cluster was successfully dissolved, but the following instance was
skipped: 'ic-2:3306'. Please make sure this instance is permanently unavailable
or take any necessary manual action to ensure the cluster is fully dissolved.

在本例中,该集群由三个实例组成,其中一个实例在发出 dissolve 命令时处于脱机状态。错误被捕获,您可以选择如何继续操作。在本例中,将忽略丢失的ic-2 实例,并更新可访问成员的元数据。

当 MySQL Shell 以非交互模式运行时(例如,在运行批处理文件时),您可以使用force 选项配置Cluster.dissolve() 操作的行为。要强制解散操作忽略任何无法访问的实例,请发出

mysql-js> Cluster.dissolve({force: true})

可以访问的任何实例都将从集群中删除,任何无法访问的实例都将被忽略。本节中关于强制从集群中删除丢失实例的警告同样适用于这种强制解散操作的技术。

MySQL Shell 选项dba.gtidWaitTimeout 配置Cluster.dissolve() 操作在从集群中删除目标实例之前等待集群事务应用的时间,但前提是目标实例处于ONLINE 状态。如果在等待要删除的任何实例上应用集群事务时达到超时,则会发出错误,除非使用了 force: true,在这种情况下会跳过错误。

注意

发出cluster.dissolve() 后,分配给Cluster 对象的任何变量都将失效。