17.5.3 网络分区

每当需要复制的更改发生时,团队都需要达成共识。这是常规事务的情况,但对于组成员身份更改和一些保持组一致的内部消息传递也是必需的。共识要求大多数组成员就给定的决定达成一致。当大多数组成员丢失时,该组将无法前进并阻塞,因为它无法确保多数或法定人数。

当出现多个非自愿故障时,仲裁可能会丢失,导致大多数服务器突然从组中删除。例如,在一个由 5 个服务器组成的组中,如果其中 3 个服务器同时停止运行,则大多数服务器都受到了损害,因此无法达到法定人数。事实上,剩下的两个无法判断其他 3 个服务器是否已崩溃或网络分区是否单独隔离了这 2 个,因此无法自动重新配置组。

另一方面,如果服务器自愿退出组,它们会指示组应该重新配置自己。实际上,这意味着要离开的服务器告诉其他人它要离开了。这意味着其他成员可以适当地重新配置组,保持成员的一致性并重新计算多数。例如,在上面的 5 个服务器的场景中,其中 3 个同时离开,如果 3 个离开的服务器一个一个地警告组他们要离开,那么成员就可以从 5 调整到 2,同时时间,在发生这种情况时确保法定人数。

笔记

失去法定人数本身就是糟糕计划的副作用。为预期故障的数量规划组大小(无论它们是连续的、同时发生的还是偶发的)。

以下部分解释了如果系统分区的方式导致组中的服务器无法自动获得法定人数,该怎么办。

小费

在多数损失和重新配置之后被排除在组之外的主节点可以包含未包含在新组中的额外事务。如果发生这种情况,尝试从组中添加被排除的成员会导致错误,并显示消息“该成员执行的事务比组中存在的事务多”。

检测分区

性能模式表是从本replication_group_members 台服务器的角度来呈现当前视图下每台服务器的状态。大多数情况下,系统不会遇到分区问题,因此该表显示的信息在组中的所有服务器上都是一致的。换句话说,每个服务器在这个表上的状态在当前视图中都是一致的。但是,如果存在网络分区,并且法定人数丢失,则该表会显示UNREACHABLE 无法联系的那些服务器的状态。此信息由组复制中内置的本地故障检测器导出。

图 17.7 失去法定人数

五个服务器实例S1、S2、S3、S4和S5部署为一个互连的组,这是一个稳定的组。 当其中三台服务器 S3、S4 和 S5 发生故障时,大多数服务器都会丢失,并且该组无法在没有干预的情况下继续进行。

为了理解这种类型的网络分区,以下部分描述了一个场景,其中最初有 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 意外停止。几秒钟后,再次 replication_group_members查看 s1 上的表显示它仍然在线,但其他几个成员不在线。事实上,如下所示,它们被标记为 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 变量。

图 17.8 强制新成员资格

一组中的三台服务器 S3、S4 和 S5 发生故障,因此大部分服务器丢失,并且该组无法在没有干预的情况下继续进行。 通过下文所述的干预,S1 和 S2 能够自行形成一个稳定的群体。

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

警告

此程序使用 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;

127.0.0.1:10000一旦知道 s1 ( ) 和 s2 ( ) 的组通信地址127.0.0.1:10001,就可以在两台服务器之一上使用它来注入新的成员资格配置,从而覆盖已丢失仲裁的现有配置。在 s1 上执行此操作:

mysql> SET GLOBAL group_replication_force_members="127.0.0.1:10000,127.0.0.1:10001";

这通过强制不同的配置来解锁组。检查replication_group_memberss1 和 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不是真的不可达而是在线,它们可能已经形成了自己的功能分区(它们是5个中的3个,因此它们占多数)。在那种情况下,强制使用 s1 和 s2 的组成员列表可能会造成人为的裂脑情况。因此,在强制执行新的成员资格配置之前,务必确保要排除的服务器确实已关闭,如果未关闭,请在继续之前将其关闭。

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