控制切换使选定的副本集群成为 InnoDB ClusterSet 部署的主集群。在控制切换过程中,可以确保数据一致性。该过程会验证所选副本集群是否与主集群同步(如果存在复制延迟,则可能需要稍等片刻),然后将该集群设为 InnoDB ClusterSet 的主集群。原始主集群降级为工作只读副本集群。然后,如果需要,您可以使原始主集群脱机,修复任何问题,并将其恢复到 InnoDB ClusterSet 部署中运行。
如果 InnoDB ClusterSet 部署中的主集群正常运行,但您需要执行维护或修复一些小问题以改进主集群的功能,请按照控制切换过程进行操作。当您使用 MySQL Shell 中的 AdminAPI 的
命令检查主集群时,如果其正常运行,则其全局状态为 clusterSet
.status()OK
。
如果 InnoDB ClusterSet 部署中的主集群未正常运行(全局状态为 NOT_OK
),请首先尝试使用 MySQL Shell 通过 AdminAPI 修复任何问题。例如,如果主集群已丢失仲裁,则可以使用
命令将其恢复。有关执行此操作的说明,请参阅第 8.9 节“InnoDB ClusterSet 修复和重新加入”。cluster
.forceQuorumUsingPartitionOf
如果您无法通过处理主集群来解决问题(例如,因为您无法联系到它),则需要执行紧急故障转移。紧急故障转移专为在主集群突然不可用时进行灾难恢复而设计。该过程存在丢失事务和为 InnoDB ClusterSet 造成脑裂情况的风险。如果您确实需要执行紧急故障转移,请按照第 8.8 节“InnoDB ClusterSet 紧急故障转移”中的过程进行操作,以确保风险得到管理。
该图显示了在示例 InnoDB ClusterSet 部署中进行控制切换的效果。罗马数据中心的主集群需要维护,因此已执行控制切换,以使布鲁塞尔数据中心中的副本集群成为 InnoDB ClusterSet 部署的主集群,并将罗马集群降级为副本集群。罗马集群上的 ClusterSet 复制通道已由控制切换过程激活,并且正在复制来自布鲁塞尔集群的事务。现在罗马集群是一个副本集群,如果需要执行维护工作,则可以安全地使成员服务器或整个集群脱机。
在示例 InnoDB Cluster 部署中,设置为跟随主集群的 MySQL Router 实例已将读写流量路由到布鲁塞尔集群,该集群现在是主集群。当布鲁塞尔集群是副本集群时,按名称将读取流量路由到该集群的 MySQL Router 实例会继续将流量路由到该集群,并且不受该集群现在是主集群而不是副本集群这一事实的影响。同样,按名称将读取流量路由到罗马集群的 MySQL Router 实例可以继续这样做,因为副本集群仍然接受读取流量。
要对主 InnoDB Cluster 执行控制切换,请按照以下过程进行操作
-
使用 MySQL Shell,使用 InnoDB Cluster 管理员帐户(使用
创建)连接到主集群或其中一个副本集群中的任何成员服务器。您还可以使用 InnoDB Cluster 服务器配置帐户,该帐户也具有所需的权限。使用cluster
.setupAdminAccount()dba.getClusterSet()
或
命令获取cluster
.getClusterSet()ClusterSet
对象。务必使用 InnoDB Cluster 管理员帐户或服务器配置帐户,以便存储在ClusterSet
对象中的默认用户帐户具有正确的权限。例如mysql-js> \connect [email protected]:3310 Creating a session to '[email protected]:3310' Please provide the password for '[email protected]:3310': ******** Save password for '[email protected]:3310'? [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 52 Server version: 8.0.27-commercial MySQL Enterprise Server - Commercial No default schema selected; type \use <schema> to set one. <ClassicSession:[email protected]:3310> mysql-js> myclusterset = dba.getClusterSet() <ClusterSet:testclusterset>
在此示例中:
-
是集群中任何在线成员服务器实例的类 URI 连接字符串。admin2
@127.0.0.1:3310
类 URI 连接字符串由以下元素组成:
是 InnoDB Cluster 管理员帐户的用户名。admin2
是成员服务器实例的主机和端口,如127.0.0.1:3310
命令所示。cluster
.status()返回的
ClusterSet
对象分配给变量myclusterset
。
-
-
使用 MySQL Shell 中的 AdminAPI 的
命令检查整个 InnoDB ClusterSet 部署的状态。使用clusterSet
.status()extended
选项查看部署中所有集群的详细信息,并检查是否存在任何问题。例如mysql-js> myclusterset.status({extended: 1})
有关输出的说明,请参阅第 8.6 节“InnoDB ClusterSet 状态和拓扑”。
-
确定一个合适的副本集群,该集群可以接管为主集群。副本集群是否有资格进行控制切换取决于其全局状态,如
命令报告的那样:clusterSet
.status()表 8.1 按状态允许的集群操作
ClusterSet 中的 InnoDB Cluster 全局状态 可路由 控制切换 紧急故障转移 OK
是 是 是 OK_NOT_REPLICATING
是,如果按名称指定为目标集群 是 是 OK_NOT_CONSISTENT
是,如果按名称指定为目标集群 否 是 OK_MISCONFIGURED
是 是 是 NOT_OK
否 否 否 INVALIDATED
是,如果按名称指定为目标集群并且设置了 accept_ro
路由策略否 否 UNKNOWN
已连接的 MySQL Router 实例可能仍在将流量路由到集群 否 否 全局状态为
OK_NOT_CONSISTENT
的副本集群在集群上具有一组事务(GTID 集),该事务集与主集群上的 GTID 集不一致。InnoDB ClusterSet 不允许对处于此状态的集群进行控制切换,因为客户端将访问不正确的数据。如果集群在可用选项中具有最新的事务集,则可以进行紧急故障转移。 -
通过连接到 InnoDB ClusterSet 部署中的任何成员服务器并在 MySQL Shell 中发出
命令,检查为每个 MySQL Router 实例设置的路由选项以及 InnoDB ClusterSet 部署的全局策略。例如clusterSet
.routingOptions()mysql-js> myclusterset.routingOptions() { "domainName": "testclusterset", "global": { "invalidated_cluster_policy": "drop_all", "target_cluster": "primary" }, "routers": { "Rome1": { "target_cluster": "primary" }, "Rome2": {} } }
默认情况下,MySQL Router 实例会将流量发送到当前在 InnoDB ClusterSet 部署中充当主集群的任何集群。如果所有 MySQL Router 实例都设置为跟随主集群(
"target_cluster": "primary"
),则流量将在切换后的几秒钟内自动重定向到新的主集群。如果未为 MySQL Router 实例显示路由选项(如上例中的Rome2
),则表示该实例未设置该策略,并且遵循全局策略。如果任何实例都设置为按名称将流量定向到当前的主集群(
"target_cluster": "
),则它们不会将流量重定向到新的主集群。在这种情况下,如果适合应用程序,您可以使用name_of_primary_cluster
"
命令更改这些实例的路由策略。您可以将这些实例更改为跟随主集群(clusterSet
.setRoutingOption()"target_cluster": "primary"
),在这种情况下,现在可以设置该选项。例如mysql-js> myclusterset.setRoutingOption('Rome1', 'target_cluster', 'primary') Routing option 'target_cluster' successfully updated in router 'Rome1'.
在此示例中,
是myclusterset
ClusterSet
对象的变量,而
是 MySQL Router 实例的名称。Rome1
或者,您可以指定将接管为主集群的副本集群,在这种情况下,在切换发生后,当您验证切换已成功时,设置选项(
"target_cluster": "
)。name_of_new_primary_cluster
" -
发出
命令,命名将接管为新的主集群的副本集群。使用您使用 InnoDB Cluster 管理员帐户通过clusterSet
.setPrimaryCluster()dba.getClusterSet()
或
命令检索到的cluster
.getClusterSet()ClusterSet
对象。例如mysql-js> myclusterset.setPrimaryCluster('clustertwo') Switching the primary cluster of the clusterset to 'clustertwo' * Verifying clusterset status ** Checking cluster clustertwo Cluster 'clustertwo' is available ** Checking cluster clusterone Cluster 'clusterone' is available * Refreshing replication account of demoted cluster * Synchronizing transaction backlog at 127.0.0.1:4410 ** Transactions replicated ############################################################ 100% * Updating metadata * Updating topology ** Changing replication source of 127.0.0.1:3330 to 127.0.0.1:4410 * Acquiring locks in replicaset instances ** Pre-synchronizing SECONDARIES ** Acquiring global lock at PRIMARY ** Acquiring global lock at SECONDARIES * Synchronizing remaining transactions at promoted primary ** Transactions replicated ############################################################ 100% * Updating replica clusters Cluster 'clustertwo' was promoted to PRIMARY of the clusterset. The PRIMARY instance is '127.0.0.1:4410'
对于
命令:clusterSet
.setPrimaryCluster()clusterName
参数是必需的,它指定用于 InnoDB ClusterSet 中副本集群的标识符,如
命令的输出中所示。在本例中,clusterSet
.status()
是将成为新的主集群的集群。clustertwo
如果要在不实际执行更改的情况下执行验证并记录更改,请使用
dryRun
选项。使用
timeout
选项设置在切换发生之前等待副本集群与主集群同步的最长时间(以秒为单位)。如果超时,则切换将被取消。使用
invalidateReplicaClusters
选项来指定任何不可访问或不可用的副本集群。这些副本集群将在切换过程中被标记为无效。如果在该过程中发现任何未命名的不可访问或不可用副本集群,则切换将被取消。在这种情况下,您必须先修复并重新加入副本集群,然后重试该命令,或者在重试该命令时在该选项上指定它们的名称,并在以后再修复它们。
当您发出
命令时,MySQL Shell 会检查目标副本集群是否符合接管主集群的要求,如果不符合,则返回错误。如果目标副本集群满足要求,MySQL Shell 将执行以下任务clusterSet
.setPrimaryCluster()检查是否有任何未指定为
invalidateReplicaClusters
的不可访问或不可用副本集群。等待目标副本集群通过应用来自主集群的任何未完成事务与当前主集群同步。如果
timeout
选项设置的超时时间在副本集群完成应用事务之前过期,则切换将被取消。通过发出
FLUSH TABLES WITH READ LOCK
语句并在所有成员服务器上设置super_read_only
系统变量来锁定当前主集群,以防止在切换过程中发生进一步更改。禁用组复制成员操作mysql_disable_super_read_only_if_primary
,以便在故障转移后super_read_only
保持设置状态。-
协调当前主集群和副本集群之间视图更改事件的差异,以便 GTID 集相同。这些组复制内部事务由
group_replication_view_change_uuid
系统变量指定的 UUID 标识。MySQL Shell 在所有副本集群上注入空事务,以匹配主集群上的视图更改事件。注意对于运行 MySQL Server 8.3.0 或更高版本的集群,这不是必需的。
更新所有副本集群上的 ClusterSet 复制通道,以从目标集群作为新的主集群进行复制。
在目标集群的主服务器上禁用
super_read_only
,并启用组复制成员操作mysql_disable_super_read_only_if_primary
,以处理该集群中主服务器的任何更改。在旧主集群的主服务器上禁用组复制成员操作
mysql_disable_super_read_only_if_primary
,以便它保持只读状态,并在该服务器上启用组复制成员操作
,以便为 ClusterSet 复制通道上的副本启用异步连接故障转移。mysql_start_failover_channels_if_primary
在 ClusterSet 元数据中将目标集群设置为主要集群,并将旧主集群更改为副本集群。
再次使用
extended
选项发出
命令,以验证 InnoDB ClusterSet 部署的状态。clusterSet
.status()-
如果您有任何 MySQL Router 实例要切换到以新主集群为目标,请立即执行此操作。例如:
mysql-js> myclusterset.setRoutingOption('Rome1', 'target_cluster', 'clustertwo') Routing option 'target_cluster' successfully updated in router 'Rome1'.
在此示例中,
是myclusterset
ClusterSet
对象的变量,
是 MySQL Router 实例的名称,Rome1
是要定位的特定集群的名称。完成后,发出clustertwo
命令,检查所有 MySQL Router 实例现在是否都正确路由。clusterSet
.routingOptions() 现在,您可以使用旧主集群来修复问题或执行维护。如果在切换过程中必须使任何副本集群无效,则也可以修复这些副本集群并将其重新添加到 InnoDB ClusterSet 中。第 8.9 节“InnoDB ClusterSet 修复和重新加入”说明了如何修复集群问题、如何将集群重新加入 InnoDB ClusterSet 以及如何使集群再次成为主集群。