17.4.3 网络分区

每当需要复制的更改发生时,小组就需要达成共识。常规 Transaction 就是这种情况,但组成员资格更改和保持组一致的某些内部消息传递也是必需的。共识要求大多数小组成员同意给定的决定。当大多数组成员丢失时,该组将无法 continue 前进并阻止,因为它无法确保多数或法定人数。

当发生多个非自愿故障时,仲裁可能会丢失,从而导致大多数服务器突然从组中删除。例如,在一组 5 台服务器中,如果其中 3 台立即变为静默状态,则大多数服务器将受到损害,因此无法实现仲裁。实际上,其余两个服务器无法判断其他 3 台服务器是否崩溃,或者网络分区是否单独隔离了这 2 台服务器,因此无法自动重新配置该组。

另一方面,如果服务器自愿退出该组,则它们会指示该组重新配置自身。实际上,这意味着要离开的服务器会告诉其他人它要离开。这意味着其他成员可以正确地重新配置组,维护成员身份的一致性,并重新计算大多数成员。例如,在上面的场景中有 5 个服务器同时离开 3 个服务器的情况下,如果 3 个离开服务器警告一组即将离开的组,则成员资格能够将自己从 5 个调整为 2 个时间,确保达到法定人数。

Note

仲裁丢失本身就是不良计划的副作用。根据预期的故障数量计划组的大小(无论它们是连续的,一次发生的还是偶然的)。

以下各节说明了如果系统以这种方式分区(组中的服务器不会自动实现仲裁)的方式进行操作。

Tip

在失去多数票并重新配置后已从组中排除的主数据库可能包含新组中未包含的其他事务。如果发生这种情况,尝试从组中添加回被排除的成员将导致错误消息:此成员具有比组中存在的事务更多的已执行事务。

Detecting Partitions

replication_group_members性能方案 table 从该服务器的角度显示当前视图中每个服务器的状态。在大多数情况下,系统没有运行到分区,因此该 table 显示的信息在组中的所有服务器之间都是一致的。换句话说,该 table 中每个服务器的状态在当前视图中被所有人同意。但是,如果存在网络分区,并且仲裁丢失,那么该 table 将显示其无法联系的那些服务器的状态UNREACHABLE。该信息由组复制中内置的本地故障检测器导出。

图 17.7 丢失仲裁

为了了解这种类型的网络分区,以下部分描述了一个场景,其中最初有 5 台服务器正常工作,然后只有 2 台服务器处于联机状态,然后对组进行了更改。图中描绘了该场景。

因此,假设其中有一个包含这 5 个服务器的组:

最初,该组运行良好,服务器之间彼此通信愉快。您可以通过登录 s1 并查看其replication_group_members性能架构 table 来验证这一点。例如:

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_memberstabletable 明它仍然处于联机状态,但其他几个成员不在。实际上,如下所示,它们被标记为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  |
+--------------------------------------+--------------+

该 table 显示,由于大多数服务器无法访问,因此 s1 现在位于没有外部干预就无法进行升级的组中。在这种特殊情况下,需要重置组成员资格列 table 以使系统 continue 运行,这在本节中进行了说明。或者,您也可以选择停止 s1 和 s2 上的组复制(或完全停止 s1 和 s2),找出 s3,s4 和 s5 发生了什么,然后重新启动组复制(或服务器)。

取消分区分区

组复制使您可以通过强制进行特定配置来重置组成员资格列 table。例如,在上面的示例中,其中 s1 和 s2 是唯一的联机服务器,您可以选择强制仅由 s1 和 s2 组成的成员身份配置。这需要检查有关 s1 和 s2 的一些信息,然后使用group_replication_force_members变量。

图 17.8 强制加入新成员

假设您又回到了 s1 和 s2 是组中剩下的唯一服务器的情况。服务器 s3,s4 和 s5 意外离开了该组。为了使服务器 s1 和 s2continue 运行,您想强制仅包含 s1 和 s2 的成员资格配置。

Warning

此过程使用group_replication_force_members,应被视为最后的补救措施。 必须必须格外小心地使用,并且仅用于使仲裁无效。如果使用不当,它可能会创建人为裂脑方案或完全阻塞整个系统。

回想一下,系统已被阻塞,并且当前配置如下(如 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       |
+--------------------------------------+--------------+

强制执行新的成员资格配置时,请确保确实要停止将要从组中强制退出的所有服务器。在上述情况下,如果 s3,s4 和 s5 并不是 true 不可访问而是在线的,则它们可能已经形成了自己的功能分区(5 分之 3,因此占多数)。在这种情况下,将组成员列 table 强制为 s1 和 s2 可能会造成人为的裂脑情况。因此,在强制执行新的成员资格配置之前,确保要排除的服务器确实已关闭是很重要的;如果没有关闭,请在 continue 操作之前将其关闭。

使用group_replication_force_members系统变量成功强制新的组成员身份并取消阻止该组后,请确保清除系统变量。 group_replication_force_members必须为空才能发出START GROUP_REPLICATION语句。

首页