组需要在每次需要复制的更改发生时达成共识。对于常规事务来说,情况就是这样,但这也需要进行组成员资格更改以及一些保持组一致性的内部消息传递。共识需要大多数组成员同意某个特定决定。当大多数组成员丢失时,组将无法前进并被阻塞,因为它无法获得多数票或仲裁。
当出现多个非自愿故障导致多数服务器突然从组中移除时,可能会丢失仲裁。例如,在由 5 台服务器组成的组中,如果其中 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
必须为空。