在 MySQL 组复制中,一组服务器构成一个复制组。一个组有一个名称,采用 UUID 的形式。该组是动态的,服务器可以随时离开(自愿或非自愿)并加入。每当服务器加入或离开时,该组都会自我调整。
如果一台服务器加入该组,它会通过从现有服务器获取丢失的状态来自动更新。如果一台服务器离开该组,例如因为维护而关闭,其余服务器会注意到它已离开并自动重新配置该组。
组复制具有组成员服务,该服务定义哪些服务器处于联机状态并参与该组。联机服务器列表称为视图。组中的每个服务器都对在给定时间点哪些服务器是积极参与该组的成员具有一致的视图。
组成员不仅必须就事务提交达成一致,还必须就当前视图达成一致。如果现有成员同意新服务器应成为该组的一部分,则会重新配置该组以将该服务器集成到其中,这会触发视图更改。如果一台服务器离开该组(无论是自愿还是非自愿),该组都会动态地重新排列其配置,并触发视图更改。
如果成员自愿离开该组,它会首先启动动态组重新配置,在此期间,所有成员都必须就一个没有该离开服务器的新视图达成一致。但是,如果成员非自愿离开该组,例如因为它意外停止或网络连接断开,则它无法启动重新配置。在这种情况下,组复制的故障检测机制会在短时间后识别出该成员已离开,并提出不包含该故障成员的组重新配置。与自愿离开的成员一样,重新配置需要组中大多数服务器的同意。但是,如果该组无法达成一致,例如因为它以无法联机访问大多数服务器的方式进行了分区,则系统将无法动态更改配置,并会阻止以防止出现脑裂情况。这种情况需要管理员进行干预。
成员可能会短时间脱机,然后在故障检测机制检测到其故障之前,以及在重新配置该组以删除该成员之前,尝试重新加入该组。在这种情况下,重新加入的成员会忘记其先前的状态,但是如果其他成员向其发送针对其崩溃前状态的消息,则可能会导致问题,包括可能的数据不一致。如果处于这种情况下的成员参与 XCom 的共识协议,则它可能会导致 XCom 为同一共识轮提供不同的值,方法是在故障前后做出不同的决定。
为了应对这种可能性,MySQL 组复制会检查以下情况:当同一服务器的新实例尝试加入该组时,其旧实例(具有相同的地址和端口号)仍被列为成员。阻止新实例加入该组,直到可以通过重新配置删除旧实例为止。请注意,如果已由group_replication_member_expel_timeout
系统变量添加了等待时间,以便在驱逐成员之前留出更多时间让其重新连接到该组,则如果可疑成员在可疑时间结束之前重新连接到该组,则该成员可以作为其当前实例重新在该组中处于活动状态。当成员超过驱逐超时并从该组中被驱逐时,或者当通过STOP GROUP_REPLICATION
语句或服务器故障在服务器上停止组复制时,它必须作为新实例重新加入。