20.7.8 网络分区和仲裁丢失处理
组需要在发生需要复制的变化时达成一致。这适用于常规事务,但也适用于组成员身份变更和一些内部消息,这些消息保持组的一致性。达成一致需要大多数组成员同意。当大多数组成员丢失时,组无法继续前进,因为它不能确保大多数或仲裁。
仲裁可能会在出现多个非故意故障时丢失,这样导致大多数服务器突然从组中移除。例如,在5台服务器组中,如果3台服务器同时变得沉默,那么大多数被 compromis和因此无法实现仲裁。在实际情况下,剩下的两台服务器不能确定另外3台服务器是否崩溃或网络分区是否将这2台服务器孤立,因此组不能自动重新配置。
另一方面,如果服务器自愿退出组,它们会通知组应该重新配置自己。在实际情况下,这意味着离开的服务器告诉其他成员它要离开。这意味着其他成员可以正确地重新配置组,保持成员身份的一致性,并重新计算大多数。例如,在上述5台服务器组中,如果3台离开的服务器一个接一个地警告组它们要离开,那么membership就能从5到2调整,同时确保仲裁。
仲裁丢失本身是一种坏规划的副作用。计划组大小,以期望的故障数量为准(无论是否连续、同时或散乱)。
在单主模式的组中,如果网络分区发生时,主服务器可能还没有将事务写入到其他成员上。因此,如果您考虑排除主服务器从新组中,请注意这些事务可能会被丢失。拥有额外事务的成员无法重新加入组,并且尝试结果会出现错误,显示消息:该成员具有比组中的更多已执行的事务。为避免这种情况,请将group_ replication_ unreachable_majority_timeout
系统变量设置为组成员的值。
以下部分解释了如果系统在分区时无法自动实现大多数服务器在组中的情况。
性能chema表replication_group_members
显示了每个服务器在当前视图中的状态,从这个服务器的角度看待。系统大多数情况下不会遇到分区,因此表中显示的一致信息跨越所有组成员。在其他字,表中每个服务器的状态是当前视图中所有服务器同意的。但是,如果出现网络分区,并且大多数被丢失,那么表中将显示状态UNREACHABLE
的服务器,这些服务器无法联系到。这个信息由Group Replication中的本地故障检测器导出。
为了理解这种网络分区,以下部分描述了一个场景,其中最初有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现在处于一个没有进度的组,因为大多数服务器不可达。在这种特定情况下,需要重置组成员列表以允许系统继续,这一部分将解释。或者,您也可以选择停止Group Replication on s1和s2(或完全停止s1和s2),然后确定s3、s4和s5的状态,然后重新启动Group Replication(或服务器)。
Group replication允许您通过强制特定的配置来重置组成员列表。例如,在上述情况下,where s1和s2是唯一在线的服务器,您可以选择强制一个仅包含s1和s2的成员配置。这需要检查一些关于s1和s2的信息,然后使用group_replication_force_members
变量。
假设您现在回到情况,where s1和s2是唯一剩下的服务器。服务器s3、s4和s5意外离开组。要使s1和s2继续,您想强制一个仅包含s1和s2的成员配置。
这个过程使用group_replication_force_members
,应该被视为最后的手段。它必须以极度小心和仅用于超越仲裁的损失。如果滥用,它可能会创建人工脑裂或阻止整个系统。
在强制新的成员配置时,确保要从组中排除的服务器已经停止。如上面的场景,如果s3、s4和s5不是真的不可达,而是在线,他们可能已经形成了自己的功能分区(他们是5中的3个,因此拥有多数)。因此,在强制组成员列表时,可能会创建人工脑裂情况。因此,在强制新的成员配置之前,需要确保要排除的服务器已经停止,如果它们没有停止,则在继续前先将其停止。
对于单主模式的组,主服务器可能在网络分区时还没有将事务写入到其他成员上。如果您考虑排除主服务器从新组中,请注意这些事务可能会丢失。拥有额外事务的成员无法重新加入组,并且尝试结果会出现错误信息:This member has more executed transactions than those present in the group。为避免这种情况,设置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
系统变量成功强制新的组成员身份并解锁组后,请确保清除该系统变量。group_replication_force_members
必须为空,以便于START GROUP_REPLICATION
语句的执行。