紧急故障转移使选定的副本集群成为 InnoDB ClusterSet 部署的主 InnoDB 集群。当当前主集群不工作或无法联系时,可以使用此过程。紧急故障切换过程中,无法保证数据一致性,因此为了安全起见,故障切换过程中会将原主集群标记为失效。如果原来的主集群仍然在线,则应在可以联系时立即将其关闭。之后,您可以修复失效的主集群并将其重新加入 InnoDB ClusterSet 拓扑,前提是您可以解决问题。
当InnoDB ClusterSet部署中的主InnoDB集群出现问题或者无法访问它时,不要立即实施紧急故障转移到副本集群。相反,您应该始终从尝试修复当前活动的主集群开始。
重要的
为什么不直接进行故障转移? InnoDB ClusterSet 拓扑中的副本集群正在尽最大努力保持与主集群的同步。但是,根据事务量以及主集群和副本集群之间的网络连接速度和容量,副本集群在接收事务和将更改应用到数据方面可能会落后于主集群。这称为复制滞后。大多数复制拓扑中都会出现一些复制延迟,并且在集群地理上分散且位于不同数据中心的 InnoDB ClusterSet 部署中很可能出现这种情况。
此外,主集群可能会因网络分区而与 InnoDB ClusterSet 拓扑的其他元素断开连接,但仍保持在线状态。如果发生这种情况,某些副本集群可能会保留在主集群中,而某些实例和客户端应用程序可能会继续连接到主集群并应用事务。在这种情况下,InnoDB ClusterSet 拓扑的分区区域开始彼此分离,每组服务器上都有不同的事务集。
当存在复制滞后或网络分区时,如果触发到副本集群的紧急故障转移,则主集群上任何未复制或发散的事务都面临丢失的风险。在网络分区的情况下,故障转移可能会造成脑裂情况,其中拓扑的不同部分具有不同的事务集。因此,在触发紧急故障转移之前,您应该始终尝试修复或重新连接主集群。如果主集群无法足够快地修复或无法到达,您可以继续进行紧急故障转移。
该图显示了 InnoDB ClusterSet 部署示例中紧急故障转移的影响。罗马数据中心的主集群已经离线,因此进行了紧急故障转移,使布鲁塞尔数据中心的副本集群成为InnoDB ClusterSet部署的主InnoDB集群。罗马集群已被标记为无效,其在 InnoDB ClusterSet 部署中的状态已降级为副本集群,尽管它目前无法从布鲁塞尔集群复制事务。
图 8.3 InnoDB ClusterSet 故障转移
设置为跟随主节点的 MySQL Router 实例已将读写流量路由到现在作为主节点的布鲁塞尔集群。当布鲁塞尔集群是副本集群时,按名称将读取流量路由到布鲁塞尔集群的 MySQL Router 实例将继续将流量路由到该集群,并且不会受到该集群现在是主集群而不是副本集群这一事实的影响。但是,按名称将读取流量路由到 Rome 集群的 MySQL Router 实例当前无法向那里发送任何流量。本示例中的报告应用程序不需要在本地数据中心离线时进行报告,但如果该应用程序仍然需要运行,则应更改 MySQL Router 实例的路由选项,以跟随主数据中心或将流量发送到布鲁塞尔簇。
要对主 InnoDB Cluster 执行紧急故障转移,请按照以下过程操作:
-
使用 MySQL Shell,使用 InnoDB Cluster 管理员帐户(使用 创建
*
cluster*.setupAdminAccount()
)连接到 InnoDB ClusterSet 部署中仍处于活动状态的任何成员服务器。您还可以使用 InnoDB Cluster 服务器配置帐户,该帐户也具有所需的权限。建立连接后,
ClusterSet
使用dba.getClusterSet()
或*
cluster*.getClusterSet()
命令从该成员服务器获取对象。您之前从离线的成员服务器检索到的对象ClusterSet
将不再起作用,因此您需要从在线的服务器再次获取它。使用 InnoDB Cluster 管理员帐户或服务器配置帐户非常重要,以便存储在对象中的默认用户帐户ClusterSet
具有正确的权限。例如:解释mysql-js> \connect admin2@127.0.0.1:4410
Creating a session to 'admin2@127.0.0.1:4410'
Please provide the password for 'admin2@127.0.0.1:4410': ********
Save password for 'admin2@127.0.0.1:4410'? [Y]es/[N]o/Ne[v]er (default No):
Fetching schema names for autocompletion... Press ^C to stop.
Closing old connection...
Your MySQL connection id is 71
Server version: 8.0.27-commercial MySQL Enterprise Server - Commercial
No default schema selected; type \use to set one.mysql-js> myclusterset = dba.getClusterSet()
-
使用 MySQL Shell 中的 AdminAPI 功能检查整个部署的状态
*
clusterSet*.status()
。使用该extended
选项可以准确查看问题所在的位置和内容。例如:mysql-js> myclusterset.status({extended: 1})
有关输出的说明,请参见 第 8.6 节 “InnoDB ClusterSet 状态和拓扑”。
-
InnoDB Cluster 可以容忍一些问题并且运行良好,可以继续作为 InnoDB ClusterSet 部署的一部分。
OK
当您使用命令检查时, 运行正常的主集群具有全局状态*
clusterSet*.status()
。例如,如果集群中的一台成员服务器离线,即使该服务器是主服务器,底层的组复制技术也可以处理这种情况并重新配置自身。如果根据报告的状态,主集群在 InnoDB ClusterSet 部署中仍然可以正常运行,但您需要进行维护或修复一些小问题来改善主集群的功能,则可以执行到副本集群的受控切换。然后,您可以根据需要使主集群脱机,修复任何问题,然后将其在 InnoDB ClusterSet 部署中恢复运行。有关执行此操作的说明,请参阅 第 8.7 节 “InnoDB ClusterSet 控制的切换”。
-
如果主集群在 InnoDB ClusterSet 部署中无法正常运行(全局状态
NOT_OK
),但您可以联系它,请首先尝试通过 MySQL Shell 使用 AdminAPI 修复任何问题。例如,如果主集群丢失仲裁,可以使用*
cluster*.forceQuorumUsingPartitionOf
命令恢复。有关执行此操作的说明,请参阅 第 8.9 节 “InnoDB ClusterSet 修复和重新加入”。 -
如果您无法执行受控切换,并且无法通过使用主集群来足够快地解决问题(例如,因为您无法联系它),请继续进行紧急故障转移。首先确定一个合适的可以接管主集群的副本集群。副本集群是否有资格进行紧急故障转移取决于其全局状态,如以下
*
clusterSet*.status()
命令所报告:表 8.2 允许的集群操作(按状态)
ClusterSet 中的 InnoDB 集群全局状态 可路由 受控切换 紧急故障转移 OK
是的 是的 是的 OK_NOT_REPLICATING
是,如果按名称指定为目标集群 是的 是的 OK_NOT_CONSISTENT
是,如果按名称指定为目标集群 不 是的 OK_MISCONFIGURED
是的 是的 是的 NOT_OK
不 不 不 INVALIDATED
是,如果按名称指定为目标集群并 accept_ro
设置路由策略不 不 UNKNOWN
连接的路由器实例可能仍在将流量路由到集群 不 不 您选择的副本集群必须具有所有可访问的副本集群中最新的事务集(GTID 集)。如果多个副本集群符合紧急故障转移的条件,请检查每个集群的复制滞后(显示在命令的扩展输出中
*
clusterSet*.status()
)。选择复制延迟最小的副本集群,因此该集群应该具有最多的事务。紧急故障转移过程会检查当前可访问的所有副本集群的 GTID 集,并告诉您另一个集群是否更新,以便您可以使用该集群重试。 -
*
clusterSet*.routingOptions()
通过在连接到 InnoDB ClusterSet 部署中的任何成员服务器时在 MySQL Shell 中发出命令,检查为每个 MySQL Router 实例设置的路由选项以及 InnoDB ClusterSet 部署 的全局策略 。例如:解释mysql-js> myclusterset.routingOptions()
{
"domainName": "testclusterset",
"global": {
"invalidated_cluster_policy": "drop_all",
"target_cluster": "primary"
},
"routers": {
"Rome1": {
"target_cluster": "primary"
},
"Rome2": {}
}
}
如果所有 MySQL Router 实例都设置为跟随主集群 (
"target_cluster": "primary"
),则流量将在故障转移后的几秒钟内自动重定向到新的主集群。"target_cluster"
如果 MySQL Router 实例未显示路由选项(如上面的for 示例Rome2
),则意味着该实例没有设置该策略,并且遵循全局策略。如果任何实例设置为按名称 ( ) 以当前主集群为目标,它们不会将流量重定向到新的主集群。当主集群不工作时,该 命令无法用于更改路由选项,因此在故障转移到新主集群完成之前,您无法重定向该 MySQL Router 实例处理的流量。
"target_cluster": "*
name_of_primary_cluster*"``*
clusterSet*.setRoutingOption()
-
如果可以,请尝试验证原始主集群是否处于离线状态,如果处于在线状态,请尝试将其关闭。如果它保持在线状态并继续接收来自客户端的流量,则可能会出现裂脑情况,其中 InnoDB ClusterSet 的各个部分会出现分歧。
-
要继续进行紧急故障转移,请发出
*
clusterSet*.forcePrimaryCluster()
命令,将要接管的副本集群命名为新的主集群。例如:解释mysql-js> myclusterset.forcePrimaryCluster("clustertwo")
Failing-over primary cluster of the clusterset to 'clustertwo'
* Verifying primary cluster status
None of the instances of the PRIMARY cluster 'clusterone' could be reached.
* Verifying clusterset status
** Checking cluster clustertwo
Cluster 'clustertwo' is available
** Checking whether target cluster has the most recent GTID set
* Promoting cluster 'clustertwo'
* Updating metadataPRIMARY cluster failed-over to 'clustertwo'. The PRIMARY instance is '127.0.0.1:4410'
Former PRIMARY cluster was INVALIDATED, transactions that were not yet replicated may be lost.
在命令中
*
clusterSet*.forcePrimaryCluster()
:- 该*
clusterName
*参数是必需的,指定用于 InnoDB ClusterSet 中副本集群的标识符,如命令输出中给出的*
clusterSet*.status()
。在示例中,*
clustertwo*
是要成为新主集群的集群。 dryRun
如果您想执行验证并记录更改而不实际执行它们, 请使用该选项。- 使用该
invalidateReplicaClusters
选项来命名任何无法访问或不可用的副本集群。这些将在故障转移过程中被标记为无效。如果在此过程中发现任何您未命名的无法访问或不可用的副本集群,故障转移将被取消。在这种情况下,您必须修复并重新加入副本集群,然后重试该命令,或者在重试该命令时在此选项上命名它们,并稍后修复它们。 - 使用该
timeout
选项定义等待在集群的每个实例中应用挂起事务的最大秒数。确保 GTID_EXECUTED 具有最新的 GTID 集。默认值是从dba.gtidWaitTimeout
选项中检索的。
当您发出
*
clusterSet*.forcePrimaryCluster()
命令时,MySQL Shell 会检查目标副本集群是否符合接管为主集群的要求,如果不符合则返回错误。如果目标副本集群满足要求,MySQL Shell 会执行以下任务:
- 尝试联系当前的主集群,如果确实可以到达,则停止故障转移。
- 检查是否有任何未使用 指定的无法访问或不可用的副本集群
invalidateReplicaClusters
,如果发现任何则停止故障转移。 - 将列出的所有副本集群标记
invalidateReplicaClusters
为无效,并将旧的主集群标记为无效。 - 检查目标副本集群是否具有可用副本集群中最新的 GTID 设置。这涉及停止所有副本集群中的 ClusterSet 复制通道。
- 更新所有副本集群上的 ClusterSet 复制通道,以从目标集群复制为新的主集群。
- 在ClusterSet元数据中将目标集群设置为主集群,并将旧的主集群更改为副本集群,尽管它当前由于被标记为无效而不能作为副本集群运行。
在紧急故障转移期间,MySQL Shell 不会尝试将目标副本集群与当前主集群同步,并且不会锁定当前主集群。如果原来的主集群仍然在线,则应在可以联系时立即将其关闭。
- 该*
-
如果您有任何 MySQL Router 实例需要切换到新的主集群,请立即执行此操作。您可以将它们更改为跟随主集群 (
"target_cluster": "primary"
),或指定已接管为主集群的副本集群 ( )。例如:"target_cluster": "*
name_of_new_primary_cluster*"
解释mysql-js> myclusterset.setRoutingOption('Rome1', 'target_cluster', 'primary')
or
mysql-js> myclusterset.setRoutingOption('Rome1', 'target_cluster', 'clustertwo')
Routing option 'target_cluster' successfully updated in router 'Rome1'.
发出
*
clusterSet*.routingOptions()
命令来检查所有 MySQL Router 实例现在是否都正确路由。 -
*
clusterSet*.status()
使用该选项再次 发出 命令extended
,以验证 InnoDB ClusterSet 部署的状态。 -
如果您能够再次联系旧的主集群,请首先确保没有应用程序流量路由到它,然后将其脱机。然后按照第 8.9 节“InnoDB ClusterSet 修复和重新加入”中的过程 检查事务并决定如何安排 InnoDB ClusterSet 拓扑。
紧急故障转移后,ClusterSet 各部分之间的事务集存在不同的风险,您必须隔离集群以防止写入流量或所有流量。有关更多详细信息,请参阅 InnoDB ClusterSet 中的 Fencing 集群。
如果您必须在切换过程中使任何副本集群失效,并且当您能够再次联系它们时,您可以使用第 8.9 节“InnoDB ClusterSet 修复和重新加入”中的过程来修复它们并将它们添加回 InnoDB簇集。