# 18.7.8处理网络分区和法定人数丢失
每当需要复制的变化发生时,团队需要达成共识。这适用于常规交易,但也适用于更改组成员身份和一些保持组一致性的内部消息。达成共识需要多数集团成员就某一决定达成一致。当大多数组成员丢失时,该组将无法前进并阻止,因为它无法获得多数或法定人数。
当出现多个非自愿故障时,仲裁可能会丢失,导致大多数服务器突然从组中删除。例如,在一个由5台服务器组成的组中,如果其中3台服务器同时变为静默,则大多数服务器都会受到影响,因此无法达到法定人数。事实上,剩下的两台无法判断其他3台服务器是否崩溃,或者网络分区是否单独隔离了这两台服务器,因此无法自动重新配置组。
另一方面,如果服务器自愿退出组,它们会指示组重新配置自身。实际上,这意味着即将离开的服务器会告诉其他服务器它将离开。这意味着其他成员可以正确地重新配置组,保持成员身份的一致性,并重新计算大多数成员。例如,在上面的5台服务器中,3台同时离开,如果3台离开的服务器一个接一个地警告组他们要离开,那么成员身份可以将自己从5调整为2,同时在这一情况下确保仲裁。
笔记
失去法定人数本身就是计划不当的副作用。针对预期故障的数量规划团队规模(无论是连续故障、一次性故障还是零星故障)。
以下各节解释了如果系统分区的方式导致组中的服务器无法自动实现仲裁,该怎么办。
提示
在失去多数票并随后进行重新配置后被排除在组之外的主要交易可能包含新组中不包括的额外交易。如果发生这种情况,尝试从组中重新添加被排除的成员将导致错误消息,该成员执行的事务比组中的事务多。
# 检测分区
这个复制组成员
performance schema表从服务器的角度显示当前视图中每个服务器的状态。大多数情况下,系统不会运行到分区中,因此该表显示了组中所有服务器的一致信息。换句话说,此表中每个服务器的状态都得到当前视图中所有人的同意。但是,如果存在网络分区,且仲裁丢失,则该表将显示状态遥不可及
对于那些它无法联系的服务器。此信息由内置于组复制中的本地故障检测器导出。
图18.14失去法定人数

为了理解这种类型的网络分区,以下部分描述了一个场景,其中最初有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并查看其
复制组成员
性能模式表。例如:
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上的表格显示,它仍然在线,但其他几个成员没有。事实上,如下图所示,它们被标记为遥不可及
此外,该系统无法重新配置自身以改变成员身份,因为大多数成员已经失去。
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的一些信息,然后使用小组成员
变量
图18.15强制加入新成员

假设您回到了s1和s2是组中仅存的服务器的情况。服务器s3、s4和s5意外离开了该组。要使服务器s1和s2继续,需要强制只包含s1和s2的成员身份配置。
警告
本程序使用小组成员
应该被视为最后的补救措施。信息技术必须使用时应格外小心,且仅适用于超过法定人数的损失。如果使用不当,它可能会制造一个人工分裂大脑的场景,或完全阻断整个系统。
回想一下,系统被阻塞,当前配置如下(由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上验证更改后的组成员身份。首先是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 |
+--------------------------------------+--------------+
在强制进行新的成员身份配置时,请确保将被强制退出组的所有服务器都已停止。在上面描述的场景中,如果s3、s4和s5不是真的不可访问,而是在线的,那么它们可能已经形成了自己的功能分区(五分之三,因此它们占多数)。在这种情况下,强制使用s1和s2作为组成员列表可能会造成人工分裂大脑的情况。因此,在强制进行新的成员资格配置之前,确保要排除的服务器确实已关闭非常重要,如果未关闭,请在继续之前将其关闭。
在你使用了小组成员
系统变量要成功强制新组成员身份并取消阻止该组,请确保清除系统变量。小组成员
必须为空才能发出启动组复制
陈述