vlambda博客
学习文章列表

「译」 MySQL 8.0 MGR失效检测和网络分区的机制


18.7.7 失效检测和网络分区的机制

组复制的失效检测机制旨在识别不再与组通信的组成员,并在他们似乎失败时将其驱逐。具有故障检测机制会增加组包含大多数正确工作成员的机会,以便客户端的请求能得到正确处理。


通常,所有组成员都会定期与所有其他组成员交换消息。如果某个组成员在 5 秒内未收到来自特定成员的任何消息,当此检测期结束时,就会产生对该成员的怀疑。当怀疑确认时,怀疑的成员被假定为失败,并被逐出该组。被驱逐的成员在其他成员看来已经从集群中删除了,但它不知道自己已被集群驱逐,因此它看到自己是在线(online),而其他成员则无法到达(unreachable)。如果成员实际上没有失败(例如,由于临时网络问题,它刚刚断开连接),并且能够恢复与其他成员的通信,则它收到包含其已从组中删除的信息的视图。


组成员的响应,包括失败的成员本身,对这些情况的反应可以在一些列的过程中进行配置。默认情况下,如果某成员被怀疑失败,则会发生以下行为:

  1. 在MySQL 8.0.20及之前,当产生怀疑时,它会立即出现。一旦复制组确认怀疑到期,该怀疑成员就立即被驱逐。由于对过期怀疑的检查是周期进行的,因此该成员可能会在超时后再存活几秒钟。从MySQL 8.0.21开始,在怀疑时间到达后增加5秒的等待期,之后怀疑成员就被驱逐。

  2. 在MySQL 8.0.20及之前,如果被驱逐的成员恢复通信并意识到它被驱逐,则不会尝试重新加入该组。从 MySQL 8.0.21 开始,它进行了三次自动尝试重新加入组(每次尝试之间有 5 分钟间隔),如果此自动重新加入程序不起作用,则停止尝试重新加入组。

  3. 当被驱逐的成员不再尝试图重新加入该组时,它会切换到超级只读模式,并等待操作员的注意。(例外情况是,从MySQL 8.0.12 到 8.0.15 的版本,默认行为是成员自行关闭。从 MySQL 8.0.16 开始,该行为已更改,以匹配 MySQL 5.7 中的行为。)


您可以使用本节中描述的组复制配置选项永久或暂时更改这些行为,以适应系统的要求和优先级。如果您遇到因慢速网络或机器、意外瞬时中断率高的网络或计划中的网络中断造成的不必要的驱逐,可以考虑增加驱逐超时和自动重新加入尝试次数。从 MySQL 8.0.21开始,已在此方向更改了默认设置,以减少在这些情况下需要操作员干预以恢复被驱逐成员的频率。需要注意,当成员正处于上述任何默认行为时,尽管它不支持写,但保持通信的客户端仍可以读,随着时间的推移,陈旧读的可能性会越来越大。如果避免陈旧读的优先级是比避免操作员干预更高,请考虑减少驱逐超时和自动重新加入尝试或将其设置为零。

未失败的成员可能会因为网络分区而与复制组的部分成员(但不是全部)失去联系。例如,在 一个5 台服务器的复制组(S1、S2、S3、S4、S5)中,如果 (S1、S2) 和 (S3、S4、S5) 断开连接,则存在网络分区。第一组(S1,S2)现在处于少数,因为它无法联系到超过一半的组成员。少数派的成员处理的任何事务都被阻塞(blocked),因为无法与组内大多数成员通信,所以该少数派无法实现投票。有关此方案的详细描述,请参阅第 18.7.8 节 "处理网络分区和仲裁丢失"。在这种情况下,默认行为是少数成员和多数成员继续留在小组中,继续接受事务(尽管他们是少数派成员而被阻止),并等待操作员的干预。此行为也是可配置的。

请注意,如果组成员处于不支持相关设置的旧 MySQL 服务器版本,或在发布时存在不同的默认值,则根据上述默认行为,他们对自己和其他组成员采取行动。例如,不支持group_replication_member_expel_timeout系统变量的成员在发现怀疑过期后将立即驱逐其他成员,其他成员即使支持系统变量并设置较长的超时设置,也接受此驱逐。


18.7.7.1 驱逐超时

您可以使用 MySQL 8.0.13 开始提供的group_replication_member_expel_timeout系统变量,以便在产生怀疑到驱逐可疑成员之间增加更多时间。当一台服务器没有接收来自另一台服务器的消息时,就会产生怀疑,如第 18.1.4.2 节"故障检测"中所述。

在组复制的组成员产生对其他成员(或自身)的怀疑之前,有一个初始的 5 秒检测期。然后,当另一个成员怀疑它(或它自己怀疑自己)时,小组成员就会被驱逐。之后可能再过一段较短的时间,然后驱逐机制开始检测和实施驱逐。group_replication_member_expel_timeout指定了单位为秒的时间段(称为驱逐超时),即组成员从开始怀疑到被驱逐之间的等待时间。可疑成员在此等待期间被认为是不可达(UNREACHABLE),但未从组的成员名单中删除。

  • 如果可疑成员在怀疑等待期结束前再次活跃起来,则成员将应用 XCom 消息缓存中其余组成员缓冲的所有消息,并在没有操作员干预的情况下,进入在线(ONLINE)状态。在这种情况下,该成员被复制组视为相同的身份。

  • 如果可疑成员仅仅在怀疑等待期结束后才变得活跃,并且能够恢复通信,它会意识到自己被驱并收到自己被驱逐的视图。您可以使用 MySQL 8.0.16 开始提供的group_replication_autorejoin_tries系统变量,使成员在此刻(怀疑等待期结束)自动尝试重新加入组。从 MySQL 8.0.21 开始,此功能默认激活,成员会进行三次自动重新加入尝试。如果自动重新加入程序没有成功或没有尝试,被驱逐的成员则遵循group_replication_exit_state_action指定的退出行动。

驱逐成员之前的等待期仅适用于以前在小组中活跃的成员。从未在小组中活跃过的非成员不会获得此等待期,并在初始检测期后被移除,因为他们加入的时间太长。

如果group_replication_member_expel_timeout设定为 0,则没有等待期,且疑似成员可在 5 秒检测期结束后立即被驱逐。此设置是默认值,一直到MySQL 8.0.20(包含 8.0.20 )。这也是组成员在 不支持group_replication_member_expel_timeout系统变量的MySQL 服务器版本中的组成员行为。从 MySQL 8.0.21开始,该值默认为 5,这意味着可疑成员在 5 秒检测期后 5 秒后可能被驱逐。复制组的所有成员并非必须有相同的group_replication_member_expel_timeout,但建议这样做,以避免意外的驱逐。任何成员都可以产生对任何其他成员(包括自身)的怀疑,因此有效的驱逐超时是最低的设置值。

以下情况,考虑调大group_replication_member_expel_timeout值:

  • 网络速度缓慢,驱逐前等待的默认5 或 10 秒时间不够长,不足以让组成员至少交换一条消息。

  • 网络有时有瞬时中断,您希望避免在这些时候不必要的驱逐和主节点(primary )成员更改。

  • 网络不在您的直接控制之下,您希望最大限度地减少操作员干预的需要。

  • 预计会出现临时网络中断,您不希望部分或全部成员因此被驱逐。

  • 某台服务器运行缓慢,您不希望将其从组中驱逐。

您可以指定最大 3600 秒(1 小时)的驱逐超时。请务必确保 XCom 的消息缓存足够大,足以在指定时间段(加上初始 5 秒检测期)内包含预期容量的消息,否则成员无法重新连接。您可以使用group_replication_message_cache_size系统变量调整缓存大小限制。有关更多信息,请参阅第 17.7.6 节 "XCom 高 速缓存管理"。

如果一个复制组中的所有成员当前均被怀疑,则不能重新配置组成员关系(通过增加或删除成员或选举新领导者)。如果需要在一个或多个成员受到怀疑时实施组成员变更,并且您希望可疑成员继续留在组内,请采取任何必要的行动,使成员再次激活,如果可能的话。如果你不能让成员再次激活,并且你希望他们从组里被驱逐,你可以强迫这些怀疑成员立即超时。在任何激活的成员上修改group_replication_member_expel_timeout的值为低于自产生怀疑以来已经过去的时间值。嫌疑成员随后立即被驱逐。

如果复制组成员意外停止并立即重新启动(例如,实例是通过mysqld_safe启动的),则如果设置了group_replication_start_on_boot=on,它会自动尝试重新加入组。在这种情况下,有可能在重新启动并重新加入尝试前,成员先前的化身已被驱逐出复制组,在这种情况下,成员无法重新加入。从 MySQL 8.0.19 开始,组复制自动使用组通信系统 (GCS) 功能对成员进行 10 次重新加入尝试,每次重试间隔为 5 秒。这应该涵盖大多数情况,并留出足够的时间将以前的化身从组中驱逐,让成员重新加入。请注意,如果将group_replication_member_expel_timeout系统变量设置为指定在成员被驱逐之前更长的等待期,则自动重新加入尝试可能仍然不成功。

有关避免在没有group_replication_member_expel_timeout系统变量的情况下进行不必要的驱逐的替代缓解策略,请参见第 17.3.2 节 "组复制限制"。

18.7.7.2 无法联系到多数派的超时

默认情况下,成员发现它们由于网络分区而属于少数派时不会自动离开组。您可以使用系统变量group_replication_unreachable_majority_timeout设置成员在与大多数组成员失去联系后等待的秒数,超时后退出组。设置超时意味着您不需要在网络分区后主动监控处于少数组的服务器,并且您可以避免由于不当干预而造成脑裂情况(有两个版本的组成员关系)的可能性。

group_replication_unreachable_majority_timeout指定的超时 时间达到时,少数派的成员处理的所有待决事务将回滚,该组中的成员将变成ERROR状态。您可以使用从 MySQL 8.0.16 开始的group_replication_autorejoin_tries系统变量,使成员在此超时后自动尝试重新加入组。从 MySQL 8.0.21 开始,此功能默认激活,成员进行三次自动重新加入尝试。如果自动重新加入程序没有成功或没有尝试,少数派成员则遵循group_replication_exit_state_action指定的动作进行退出。

在决定是否设置无法到达的多数超时 时,请考虑以下几点:

  • 在对称组中,例如具有两台或四台服务器的组,如果两个分区都包含同等数量的服务器,则两组都认为自己是少数并进入ERROR状态。在这种情况下,复制组就没有功能性的分区。

  • 当存在少数派时,即使被少数派处理过的事务都被接受,但因少数派无法达到法定人数而被阻塞,直到这些服务器上发出STOP GROUP_REPLICATION命令或超过无法联系到多数派的超时 时间时。

  • 如果您没有设置无法访问多数派的超时 时间时,少数派的成员永远不会自动进入ERROR状态,并且必须手动停止它们。

  • 当少数派成员已经进入到与多数派失去联系的检测后,此时在少数派成员设置无法联系多数派的超时 时间将会无效。

如果您不使用group_replication_unreachable_majority_timeout系统变量,则第 18.7.8 节 "处理网络分区和仲裁丢失"中描述了网络分区情况下操作员干预的过程。该过程包括检查哪些服务器正在运行,并在必要时强制更新组成员关系。

18.7.7.3 自动重新加入

group_replication_autorejoin_tries系统变量(从 MySQL 8.0.16 开始),使已被驱逐或达到其无法访问多数派的超时 时间的成员尝试自动重新加入组。一直到 MySQL 8.0.20,此系统变量默认值值为 0,因此默认情况下不会自动重新加入。从 MySQL 8.0.21 开始,系统变量默认值改为 3,这意味着成员自动进行 3 次尝试重新加入组,每次间隔 5 分钟。

当自动重新加入未激活时,成员在恢复通信后立即接受其驱逐命令,并继续执行group_replication_exit_state_action系统变量指定的动作。在此之后,需要人工干预才能将成员加入复制组。如果您能够忍受陈旧读的可能性,并希望最大限度地减少手动干预的需要,则使用自动重新加入功能是合适的,尤其是在高频瞬时网络问题导致成员被驱逐的情况下。

使用自动重新加入,当成员被驱逐或达到其无法访问多数派的超时 时间时,它会尝试重新加入(使用当前的插件选项值),然后继续进行进一步的自动重新加入尝试,直至到达指定的尝试次数。在一次失败的自动重新加入尝试后,成员等待 5 分钟才能进行下一次尝试。自动重新加入尝试和它们之间的时间统称为自动重新加入程序。在指定的尝试次数用尽后,如果没有成员重新加入或停止的情况下,则成员将执行group_replication_exit_state_action系统变量指定的动作。

在自动重新加入尝试期间和之间,成员保持超级只读取模式,并在复制组的视图上显示为ERROR状态。在此期间,成员不接受写操作。但是,仍然可以在此成员上执行查询操作,随着时间的推移,陈旧读的可能性越来越大。如果您确实想在自动重新加入过程中进行干预,让成员离线,则可以在任何时候通过使用STOP GROUP_REPLICATION语句或关闭实例来手动停止成员。如果您不能容忍任何时间出现陈旧读,请将group_replication_autorejoin_tries系统变量设置为 0。

您可以使用Performance Schema监控自动重新加入程序。在发生自动重新加入动作时,Performance Schema的events_stages_current表会显示"Undergoing auto-rejoin procedure"事件,以及迄今为止自动重新加入尝试的次数(对应WORK_COMPLETED字段中)。events_stages_summary_global_by_event_name表显示服务器实例启动自动重新加入程序(对应 COUNT_STAR字段)的次数。events_stages_history_long表显示了每次自动重新加入程序完成的时间(在TIMER_END字段)。当一个成员正在重新加入复制组,在复制组完成兼容性检查并接受它之前,其状态为OFFLINEERROR。当这个成员获取到复制组的事务时,其状态为:RECOVERING

18.7.7.4 退出操作

group_replication_exit_state_action系统变量,从 MySQL 8.0.12 和 MySQL 5.7.24 开始可用,其指定了组复制在成员因错误或问题无意中离开组时的行为,无论是自动尝试重新加入失败还是不尝试。请注意,在这些情况下的被驱逐成员,它不知道它已被驱逐,直到它重新连接到该复制组,所以只有在成员设法重新连接,或者如果成员被怀疑并驱逐自己时,才会执行指定地动作。

按影响顺序排列,退出操作如下:

  1. 如果退出操作是READ_ONLY,实例通过设置系统变量super_read_onlyON将 MySQL切换到超级只读模式。当成员处于超级只读模式时,即使客户具有CONNECTION_ADMIN特权(或被弃用的SUPER特权),他们也不能进行任何更新操作。但是,客户端仍然可以读取数据,并且由于不再进行更新,因此可能会出现随着时间推移而增加陈旧读的概率。因此,通过此设置,您需要主动监控服务器故障。此退出操作是 MySQL 8.0.15 开始的默认值。采取此退出动作后,成员在组视图中的状态将显示为ERROR

  2. 如果退出操作是OFFLINE_MODE,实例通过设置系统变量offline_modeON将 MySQL切换到离线模式。当成员处于离线模式时,已连接的客户端用户在下一个请求时断开连接,并且不再接受连接,但具有CONNECTION_ADMIN特权(或被弃用的SUPER特权)的客户端用户除外。组复制还将系统变量super_read_only设置为ON,这样客户端就不能进行任何更新,即使他们以CONNECTION_ADMINSUPER特权连接。此退出操作可防止更新和陈旧读(有指定特权的客户端用户除外),并使 MySQL Router等代理工具能够识别服务器是不可用并重定向客户端连接。它还使正在运行的实例离开,以便管理员可以尝试在不关闭 MySQL 的情况下解决此问题。此退出操作从 MySQL 8.0.18 开始可用。采取此退出操作后,成员在组视图中的状态将显示为ERROR(不是 OFFLINE,这意味着有组复制功能的成员是可用的,但当前不属于某个复制组)。

  3. 如果退出操作是 ABORT_SERVER,实例会关闭 MySQL。指示成员自行关闭以防止所有陈旧读和客户端更新,但这意味着 MySQL 服务器实例不可用,必须重新启动,即使问题可以解决而不采取该步骤。此退出操作是从MySQL 8.0.12 开始的新增系统变量的默认值,直到 MySQL 8.0.15 。采取此退出操作后,在组视图中将成员从服务器列表中删除。

请记住,无论设定什么退出行动,人员干预都是需要的,作为已用尽自动重新加入尝试次数(或从未有过)且已被驱逐出组的前成员,在不重启组复制的情况下不得重新加入。退出操作仅影响客户端是否仍能读取无法重新加入组的服务器上的数据,无论服务器是否在运行。

重要

如果在成员成功加入组之前发生故障,则不采取group_replication_exit_state_action 指定的退出操作。比如,本地配置检查过程中出现故障,或者加入成员的配置与组的配置不匹配。在这些情况下,super_read_only系统变量将不再是其原始值,服务器也不会关闭 MySQL。因此,为了确保服务器在组复制未启动时不接受更新,我们建议将super_read_only=ON设置在服务器启动时读取的配置文件中,组复制会在成员成功启动后,将primary 成员的super_read_only设置为OFF。当服务器被配置为在服务器启动时就启动组复制(group_replication_start_on_boot=ON),此保护措施尤其重要,但当使用START GROUP_REPLICATION命令手动启动组复制时,该保护措施也很有用。

如果成员在成功加入组后发生故障,则会采取指定的退出操作。以下情况是一些示例:

  1. Applier error - 复制应用时的错误。此问题无法恢复。

  2. Distributed recovery not possible - 这是一个组复制的分布式恢复过程(使用远程克隆操作和从二进制日志中进行状态传输)无法完成的问题。组复制在它认为有意义的时候自动尝试分布式恢复,但如果没有更多的选项来完成该过程,则停止。有关详细信息,请参见第 17.5.4.4 节 "分布式恢复的容错能力"。

  3. Group configuration change error - 使用某些功能进行全组配置更改时发生的错误,如第 18.5.1 节 "配置联机组"中所述。

  4. Primary election error - 在单主模式下选举新的主库时发生的错误,参见第18.1.1.3.1节"单主模式"所述。

  5. Unreachable majority timeout - 成员因已与大多数组成员失去联系而处于少数派,并且由group_replication_unreachable_majority_timeout系统变量设置的超时 时间已过。

  6. Member expelled from group - 已对该成员提出怀疑,group_replication_member_expel_timeout系统变量设置的任何超时已过期,虽然该成员已恢复与该复制组的通信,但发现该成员已被驱逐。

  7. Out of auto-rejoin attempts - group_replication_autorejoin_tries系统变量设置为在失去与多数派联系或被驱逐后,自动重新加入集群的尝试次数,成员尝试此指定次数后仍没有没有成功。

下表总结了每个案例中的失败场景和操作:


表 18.3 组复制失败情况下的退出操作

失败情况

`START GROUP_REPLICATION`启动组复制`

group_replication_start_on_boot =ON`启动组复制

成员本地配置检查失败
成员和复制组不匹配

`super_read_only`和`offline_mode`不变
MySQL继续运行
在启动时设置`super_read_only=ON`,以防止更新

`super_read_only`和`offline_mode`不变
MySQL继续运行
在启动时设置`super_read_only=ON`,以防止更新(重要)

成员应用错误
无法进行分布式恢复
复制组配置更改错误
主库驱逐错误
无法达到多数派超时
成员被复制组驱逐
超过自动重新加入次数

`super_read_only`设置为`ON`或
`offline_mode`及`super_read_only`设置为`ON` 或
关闭MySQL

`super_read_only`设置为`ON`或
`offline_mode`及`super_read_only`设置为`ON` 或
关闭MySQL