无论何时发生需要复制的更改,组都需要达成一致。对于常规事务而言,情况就是这样,但对于组成员资格更改和保持组一致性的一些内部消息传递而言,也是必需的。一致性要求大多数组成员同意给定决定。当失去大多数组成员时,组将无法继续并阻塞,因为它无法确保大多数或仲裁。
当发生多个非自愿故障时,可能会失去仲裁,导致大多数服务器突然从组中删除。例如,在由 5 个服务器组成的组中,如果其中 3 个服务器同时静默,则多数票将受到损害,因此无法达成仲裁。事实上,剩下的两个服务器无法判断其他 3 个服务器是否已崩溃,或者网络分区是否只隔离了这两个服务器,因此该组无法自动重新配置。
另一方面,如果服务器自愿退出组,它们会指示组重新配置自身。实际上,这意味着离开的服务器会告诉其他服务器它将离开。这意味着其他成员可以正确地重新配置组,成员资格的一致性得以维护,并且重新计算多数票。例如,在上述 5 个服务器场景中,如果 3 个服务器同时离开,如果 3 个离开的服务器依次警告组它们将离开,那么成员资格能够从 5 调整到 2,同时在发生这种情况时确保仲裁。
失去仲裁本身是糟糕规划的副作用。计划组的大小以适应预期故障数量(无论这些故障是连续发生的、同时发生的还是零星发生的)。
对于处于单主模式的组,主服务器可能在网络分区时有一些尚未存在于其他成员上的事务。如果您正在考虑将主服务器从新组中排除,请注意这些事务可能会丢失。具有额外事务的成员无法重新加入组,并且尝试这样做会导致错误,消息为 此成员执行的事务比组中存在的事务多。设置 group_replication_unreachable_majority_timeout
系统变量以避免这种情况。
以下部分说明了如果系统以无法通过组中的服务器自动达成仲裁的方式进行分区,该怎么办。
性能模式表 replication_group_members
显示了当前视图中从该服务器角度看每个服务器的状态。大多数情况下,系统不会遇到分区,因此该表显示的信息在组中的所有服务器之间都是一致的。换句话说,该表上每个服务器的状态在当前视图中由所有服务器达成一致。但是,如果存在网络分区并且失去仲裁,则该表会将那些它无法联系的服务器的状态显示为 UNREACHABLE
。此信息由内置于组复制中的本地故障检测器导出。
为了理解这种类型的网络分区,以下部分描述了以下场景:最初有 5 个服务器在正常运行,然后发生了一些更改,导致只有 2 个服务器在线。该场景如图所示。
因此,假设有一个包含以下 5 个服务器的组
服务器 s1,其成员标识符为
199b2df7-4aaf-11e6-bb16-28b2bd168d07
服务器 s2,其成员标识符为
199bb88e-4aaf-11e6-babe-28b2bd168d07
服务器 s3,其成员标识符为
1999b9fb-4aaf-11e6-bb54-28b2bd168d07
服务器 s4,其成员标识符为
19ab72fc-4aaf-11e6-bb51-28b2bd168d07
服务器 s5,其成员标识符为
19b33846-4aaf-11e6-ba81-28b2bd168d07
最初,该组运行良好,服务器彼此之间愉快地进行通信。您可以通过登录 s1 并查看其性能模式表 replication_group_members
来验证这一点。例如
mysql> SELECT MEMBER_ID,MEMBER_STATE, MEMBER_ROLE FROM performance_schema.replication_group_members;
+--------------------------------------+--------------+-------------+
| MEMBER_ID | MEMBER_STATE | MEMBER_ROLE |
+--------------------------------------+--------------+-------------+
| 1999b9fb-4aaf-11e6-bb54-28b2bd168d07 | ONLINE | SECONDARY |
| 199b2df7-4aaf-11e6-bb16-28b2bd168d07 | ONLINE | PRIMARY |
| 199bb88e-4aaf-11e6-babe-28b2bd168d07 | ONLINE | SECONDARY |
| 19ab72fc-4aaf-11e6-bb51-28b2bd168d07 | ONLINE | SECONDARY |
| 19b33846-4aaf-11e6-ba81-28b2bd168d07 | ONLINE | SECONDARY |
+--------------------------------------+--------------+-------------+
但是,片刻之后,发生了灾难性故障,服务器 s3、s4 和 s5 意外停止。在此之后几秒钟,再次查看 s1 上的 replication_group_members
表,会发现它仍然在线,但其他几个成员不在线。事实上,如以下所示,它们被标记为 UNREACHABLE
。此外,该系统无法自行重新配置以更改成员资格,因为多数票已丢失。
mysql> SELECT MEMBER_ID,MEMBER_STATE FROM performance_schema.replication_group_members;
+--------------------------------------+--------------+
| MEMBER_ID | MEMBER_STATE |
+--------------------------------------+--------------+
| 1999b9fb-4aaf-11e6-bb54-28b2bd168d07 | UNREACHABLE |
| 199b2df7-4aaf-11e6-bb16-28b2bd168d07 | ONLINE |
| 199bb88e-4aaf-11e6-babe-28b2bd168d07 | ONLINE |
| 19ab72fc-4aaf-11e6-bb51-28b2bd168d07 | UNREACHABLE |
| 19b33846-4aaf-11e6-ba81-28b2bd168d07 | UNREACHABLE |
+--------------------------------------+--------------+
该表显示,s1 现在位于一个没有手段在没有外部干预的情况下继续运行的组中,因为大多数服务器都无法访问。在这种特定情况下,需要重置组成员资格列表才能让系统继续运行,这将在本部分中进行说明。或者,您也可以选择停止 s1 和 s2 上的组复制(或完全停止 s1 和 s2),找出 s3、s4 和 s5 发生了什么情况,然后重新启动组复制(或服务器)。
组复制使您能够通过强制执行特定配置来重置组成员资格列表。例如,在上述情况下,其中 s1 和 s2 是唯一在线的服务器,您可以选择强制执行仅包含 s1 和 s2 的成员资格配置。这需要检查有关 s1 和 s2 的一些信息,然后使用 group_replication_force_members
变量。
假设您回到了 s1 和 s2 是组中仅剩的服务器的情况。服务器 s3、s4 和 s5 意外地离开了组。为了使服务器 s1 和 s2 继续运行,您希望强制一个仅包含 s1 和 s2 的成员资格配置。
此过程使用 group_replication_force_members
,应被视为最后的手段。它必须谨慎使用,并且仅用于覆盖失去仲裁的情况。如果使用不当,它可能会创建人为的脑裂场景或完全阻塞整个系统。
强制新的成员资格配置时,请确保要从组中强制移除的任何服务器都已停止。在上图所示的场景中,如果 s3、s4 和 s5 实际上没有不可访问,而是在线,它们可能已经形成了自己的功能性分区(它们是 5 个中的 3 个,因此它们拥有多数票)。在这种情况下,强制使用 s1 和 s2 的组成员资格列表可能会创建人为的脑裂场景。因此,在强制新的成员资格配置之前,重要的是要确保要排除的服务器确实已关闭,如果未关闭,请在继续之前关闭它们。
对于处于单主模式的组,主服务器可能在网络分区时有一些尚未存在于其他成员上的事务。如果您正在考虑将主服务器从新组中排除,请注意这些事务可能会丢失。具有额外事务的成员无法重新加入组,并且尝试这样做会导致错误,消息为 此成员执行的事务比组中存在的事务多。设置 group_replication_unreachable_majority_timeout
系统变量以避免这种情况。
回想一下,系统已阻塞,当前配置如下(如 s1 上的本地故障检测器所感知)
mysql> SELECT MEMBER_ID,MEMBER_STATE FROM performance_schema.replication_group_members;
+--------------------------------------+--------------+
| MEMBER_ID | MEMBER_STATE |
+--------------------------------------+--------------+
| 1999b9fb-4aaf-11e6-bb54-28b2bd168d07 | UNREACHABLE |
| 199b2df7-4aaf-11e6-bb16-28b2bd168d07 | ONLINE |
| 199bb88e-4aaf-11e6-babe-28b2bd168d07 | ONLINE |
| 19ab72fc-4aaf-11e6-bb51-28b2bd168d07 | UNREACHABLE |
| 19b33846-4aaf-11e6-ba81-28b2bd168d07 | UNREACHABLE |
+--------------------------------------+--------------+
首先要做的是检查 s1 和 s2 的本地地址(组通信标识符)。登录到 s1 和 s2,并获取以下信息。
mysql> SELECT @@group_replication_local_address;
一旦您知道了 s1 (127.0.0.1:10000
) 和 s2 (127.0.0.1:10001
) 的组通信地址,您可以在两台服务器中的任何一台服务器上使用它来注入新的成员资格配置,从而覆盖已失去仲裁的现有配置。要在 s1 上执行此操作
mysql> SET GLOBAL group_replication_force_members="127.0.0.1:10000,127.0.0.1:10001";
这将通过强制不同的配置来解除组的阻塞。检查 s1 和 s2 上的 replication_group_members
,以验证此更改后的组成员资格。首先在 s1 上。
mysql> SELECT MEMBER_ID,MEMBER_STATE FROM performance_schema.replication_group_members;
+--------------------------------------+--------------+
| MEMBER_ID | MEMBER_STATE |
+--------------------------------------+--------------+
| b5ffe505-4ab6-11e6-b04b-28b2bd168d07 | ONLINE |
| b60907e7-4ab6-11e6-afb7-28b2bd168d07 | ONLINE |
+--------------------------------------+--------------+
然后在 s2 上。
mysql> SELECT * FROM performance_schema.replication_group_members;
+--------------------------------------+--------------+
| MEMBER_ID | MEMBER_STATE |
+--------------------------------------+--------------+
| b5ffe505-4ab6-11e6-b04b-28b2bd168d07 | ONLINE |
| b60907e7-4ab6-11e6-afb7-28b2bd168d07 | ONLINE |
+--------------------------------------+--------------+
在成功使用 group_replication_force_members
系统变量强制新的组成员资格并解除组的阻塞后,请确保清除系统变量。为了发出 START GROUP_REPLICATION
语句,group_replication_force_members
必须为空。