2020-08-14
集群有三个成员memberA、B、C成,其中memberB意外故障停掉了,然后memberA 执行stop group_replication退去集群.此时整个集群不可用了(不能更新数据)。
集群中唯一剩余的成员memberC上看到的成员状态为:
但是memberA看到的状态为:
查看最后的存活的memberC的错误日志发现:
"Plugin group_replication reported: 'This server is not able to reach a majority of members in the group. This server will now block all updates. The server will remain blocked until contact with the majority is restored. It is possible to use group_replication_force_members to force a new group membership.' "
大概意思是当前的服务没法获取到成员的投票数,当前服务将会阻塞所有的更新,直到能够获取到投票数。可以使用group_replication_force_members 来强制组成一个新的组。
开始认为这是MGR功能的一个bug,不过后来想想这样的设定也是合理的,因为如果是当前的服务成员自身网络或其他问题导致的无法与其他成员的通信成功,那么这样的情况下这种设定也是合理的,因为不能让它自动重新组成一个组,否则就会可能出现多个重复的组。对于为什么组成员A执行stop group_replication后,剩余的memberC的视图中memberA还是online状态,可能是因为memberB已经unreachable,所以memberC去请求是否同意memberA退去时没有得到结果,一直阻塞等待造成的。此时,memberA的退出结果应该是无法多数投票通过的,因此memberA的退出结果应该是失败的。查看memberA的error日志,结果确实如此:
[ERROR] [MY-011735] [Repl] Plugin group_replication reported: '[GCS] Timeout while waiting for the group communication engine to exit!'
[ERROR] [MY-011735] [Repl] Plugin group_replication reported: '[GCS] The member has failed to gracefully leave the group.'
解决的方法是memberC也执行stop group_replication停掉这个组,再重新组成一个新的组。
mysql> set global group_replication_bootstrap_group=ON;
Query OK, 0 rows affected (0.00 sec)
mysql> start group_replication;
Query OK, 0 rows affected (3.06 sec)
mysql> set global group_replication_bootstrap_group=OFF;
Query OK, 0 rows affected (0.00 sec)
此时memberA再重新加入就成功了:
mysql> start group_replication;
Query OK, 0 rows affected (4.30 sec)
结果:
以此类推,当有多个server组成的group而有多数成员已经意外故障时,导致整个组的停止更新,目前想到的解决的方法就是停掉现在的组,重新组成新的组。
ps:
增加Group Replication System Variables中group_replication_member_expel_timeout的大小,可以避免网络问题或执行事务慢造成的错误驱逐。
网友评论