MySQL Shell 8.4  /  ...  /  从重大故障重启集群

7.8.3 从重大故障重启集群

如果您的集群遇到完全中断,您可以使用 dba.rebootClusterFromCompleteOutage() 重新配置它。此操作使您能够连接到集群中的一个 MySQL 实例,并使用其元数据来恢复集群。

完全中断意味着所有成员实例上的组复制都已停止。

注意

在运行 dba.rebootClusterFromCompleteOutage() 之前,请确保所有集群成员都已启动。如果集群成员不可访问,则该命令将失败。

如果集群为 INVALIDATED 并且是 ClusterSet 的成员,则会忽略此检查。

连接到最新的实例并运行以下命令

  JS> var cluster = dba.rebootClusterFromCompleteOutage()

如果所有成员具有相同的 GTID 集,则您当前连接到的成员将成为主节点。请参见 使用 rebootClusterFromCompleteOutage 选择主节点

dba.rebootClusterFromCompleteOutage() 操作按以下步骤执行,以确保集群正确地重新配置

  • 从当前实例检索集群元数据和集群拓扑。

  • 如果集群成员处于 RECOVERING 或 ERROR 状态,并且所有其他成员都处于 OFFLINE 或 ERROR 状态,则 dba.rebootClusterFromCompleteOutage() 会尝试停止该成员上的组复制。如果组复制无法停止,则该命令会停止并显示错误。

  • 检查当前连接的实例上找到的 InnoDB 集群元数据,以查看其是否包含 GTID 超集。如果当前连接的实例不包含 GTID 超集,则操作将中止并提供该信息。

    请参见 GTID 超集

  • 如果实例包含 GTID 超集,则会根据该实例中存储的元数据来恢复集群。

  • MySQL Shell 检查集群的哪些实例当前可访问,如果任何成员当前不可访问,则会失败。

    注意

    可以使用 force 选项绕过此检查。这将使用剩余的可访问成员重启集群。

    请参见 强制选项

  • 类似地,MySQL Shell 会检测当前不可访问的实例。如果它们当前不可访问,则无法将以前的成员添加到集群中或从集群中删除以前的成员,作为 dba.rebootClusterFromCompleteOutage() 命令的一部分。

  • 如果在集群的主实例上启用,则在单主模式下,super_read_only 将被禁用。

GTID 超集

要重启集群,您必须连接到具有 GTID 超集的成员,这意味着在中断之前已应用最多事务的实例。

要确定哪个成员具有 GTID 超集,请执行以下操作之一

  • 连接到实例并使用 dryRun: true 运行 dba.rebootClusterFromCompleteOutage()。生成的报告将返回类似于以下内容的信息:。

                  Switching over to instance '127.0.0.1:4001' to be used as seed.

    这表示具有 GTID 超集的成员。

    在具有较低 GTID 集的成员上运行 dba.rebootClusterFromCompleteOutage() 会导致错误。

  • 依次连接到每个实例,并在 SQL 模式下运行以下内容

    SHOW VARIABLES LIKE 'gtid_executed';

    已应用最大 GTID 集 事务的实例包含 GTID 超集。

注意

可以使用 force 选项覆盖此行为,并使用具有较低 GTID 集的实例。使用 force 选项运行 dba.rebootClusterFromCompleteOutage()

这会将所选成员设为主节点,并丢弃所选成员的 GTID 集中未包含的任何事务。

如果此过程失败,并且集群元数据已严重损坏,则可能需要删除元数据,并从头开始重新创建集群。可以使用 dba.dropMetadataSchema() 删除集群元数据。

警告

dba.dropMetadataSchema() 方法应仅用作最后的手段,在无法恢复集群时使用。它无法撤消。

如果您将 MySQL 路由器与集群一起使用,当您删除元数据时,所有当前连接都会被删除,并且会禁止新的连接。这会导致完全中断。

选项

dba.rebootClusterFromCompleteOutage() 具有以下选项

  • force: true | false (默认):如果为 true,则即使集群的某些成员无法访问,或者所选主节点具有不同的或较低的 GTID_SET,也必须执行该操作。请参见 强制选项

  • dryRun: true | false (默认):执行命令及其选项的所有验证和步骤,但不进行任何更改。完成后将显示报告。请参见 测试 rebootClusterFromCompleteOutage

  • primary:表示必须选择为主节点的实例的实例定义。请参见 使用 rebootClusterFromCompleteOutage 选择主节点

  • switchCommunicationStack: mysql | xcom:重启后集群要使用的组复制协议堆栈。请参见 第 7.5.9 节,“配置组复制通信堆栈”

  • ipAllowList:使用 XCOM 协议堆栈时,允许连接到实例以进行组复制流量的主机列表。

  • localAddress:字符串值,用于指定组复制本地地址,而不是在使用 XCOM 协议堆栈时自动生成的地址。

强制选项

force 选项使您能够忽略集群成员的可用性或所选成员中 GTID 集的差异,并重启集群。

例如,重启集群 myCluster

  JS> var cluster = dba.rebootClusterFromCompleteOutage("myCluster",{force: true})

在以下情况下不允许使用 force 选项

  • 如果集群属于 ClusterSet,并且处于 INVALIDATED 状态,或者主集群不在全局状态 OK 中。

  • 集群属于 ClusterSet,是主集群,并且处于 INVALIDATED 状态。

无法使用 rebootClusterFromCompleteOutage 添加或重新加入实例。如果您使用 force 忽略了不可访问的成员并重启了集群,则必须使用 cluster.rejoinInstance() 将不可访问的成员添加到集群中。

使用 rebootClusterFromCompleteOutage 选择主节点

您可以通过以下方式之一定义集群主节点

  • dba.rebootClusterFromCompleteOutage() 命令中定义 primary 选项。

    例如,重启集群 myCluster 并将运行在本地机器上端口 4001 上的成员设为主节点

    var cluster = dba.rebootClusterFromCompleteOutage("myCluster",{primary: "127.0.0.1:4001"})

  • 通过在具有比另一个成员更低的 GTID 集的集群成员上,使用 primary 选项以及 force 选项。

测试 rebootClusterFromCompleteOutage

您可以使用 dryRun 选项测试更改。此选项会验证命令及其选项,并生成结果日志。如果提出的更改存在问题,则会引发异常。

以下示例显示了重启集群 myCluster 的干运行,将主节点设置为运行在端口 4001 上的本地成员,以及它返回的日志消息

JS > var cluster = dba.rebootClusterFromCompleteOutage("myCluster",{primary: "127.0.0.1:4001", dryRun: true})

NOTE: dryRun option was specified. Validations will be executed, but no changes will be applied.
Cluster instances: '127.0.0.1:4000' (OFFLINE), '127.0.0.1:4001' (OFFLINE), '127.0.0.1:4002' (OFFLINE)
Switching over to instance '127.0.0.1:4001' to be used as seed.
dryRun finished.

对 ClusterSet 和 ReplicaSet 的注意事项

rebootClusterFromCompleteOutage 会执行以下检查,如果集群不满足要求,则会生成警告

  • 确认副本集群没有被强制从 ClusterSet 中删除。

  • 确认 ClusterSet 的主集群可访问。

  • 检查集群中是否存在错误的事务,这些事务不是视图更改日志事件 (VCLE)。请参见 分布式恢复的工作原理

  • 确认集群的已执行事务集 (GTID_EXECUTED) 不为空。

该命令会自动将副本集群重新加入 ClusterSet,确保为所有集群成员配置了 ClusterSet 复制通道。

切换通信堆栈

您可以在 dba.rebootClusterFromCompleteOutage() 操作期间切换通信堆栈。

例如

        js> dba.rebootClusterFromCompleteOutage("testcluster", {switchCommunicationStack: "mysql"})

MYSQL 协议切换到 XCOM 需要为 localAddress 指定额外的网络地址,并且可能还需要您定义 ipAllowList 值。