基于案例分析 MySQL Group Replication 的故障检测流程( 三 )

日志的输出包括两部分,以空格为分界线 。
1. 当网络连接恢复后,node3 与 node1、node2 重新建立起了连接,发现自己已经被集群驱逐,于是节点进入到 ERROR 状态 。
mysql> select member_id,member_host,member_port,member_state,member_role from performance_schema.replication_group_members;+--------------------------------------+----------------+-------------+--------------+-------------+| member_id                            | member_host    | member_port | member_state | member_role |+--------------------------------------+----------------+-------------+--------------+-------------+| 4cbfdc79-0192-11ed-8b01-02001701bd0a | 192.168.244.30 |        3306 | ERROR        |             |+--------------------------------------+----------------+-------------+--------------+-------------+1 row in set (0.00 sec)节点进入到 ERROR 状态,会自动设置为只读,即日志中看到的 super_read_only=ON 。注意 , ERROR 状态的节点设置为只读是默认行为 , 与后面提到的 group_replication_exit_state_action 参数无关 。
2. 如果group_replication_autorejoin_tries不为 0,对于 ERROR 状态的节点,会自动重试 , 重新加入集群(auto-rejoin) 。重试的次数由 group_replication_autorejoin_tries 决定,从 MySQL 8.0.21 开始,默认为 3 。重试的时间间隔是 5min 。重试成功后,会进入到分布式恢复阶段 。
接下来看看 node1 的日志 。
2022-07-31T13:07:39.555613-00:00 0 [System] [MY-011503] [Repl] Plugin group_replication reported: 'Group membership changed to 192.168.244.10:3306, 192.168.244.20:3306, 192.168.244.30:3306 on view 16592724636525403:4.'2022-07-31T13:07:40.732568-00:00 0 [System] [MY-011492] [Repl] Plugin group_replication reported: 'The member with address 192.168.244.30:3306 was declared online within the replication group.'node3 又重新加入到集群中 。
故障检测流程结合上面的案例,我们来看看 Group Repliction 的故障检测流程 。

  1. 集群中每个节点都会定期(每秒 1 次)向其它节点发送心跳信息 。如果在 5s 内(固定值,无参数调整)没有收到其它节点的心跳信息,则会将该节点标记为可疑节点,同时会将该节点的状态设置为 UNREACHABLE。如果集群中有等于或超过 1/2 的节点显示为 UNREACHABLE ,则该集群不能对外提供写服务 。
  2. 如果在group_replication_member_expel_timeout(从 MySQL 8.0.21 开始 , 该参数的默认值为 5,单位 s,最大可设置值为3600,即 1 小时)时间内 , 可疑节点恢复正常 , 则会直接应用 XCom Cache 中的消息 。XCom Cache 的大小由group_replication_message_cache_size 决定 , 默认是 1G 。
  3. 如果在group_replication_member_expel_timeout时间内,可疑节点没有恢复正常,则会被驱逐出集群 。
  4. 而少数派节点呢,不会自动离开集群 , 它会一直维持当前的状态,直到:
    • 网络恢复正常 。
    • 达到 group_replication_unreachable_majority_timeout 的限制 。注意,该参数的起始计算时间是连接断开 5s 之后,不是可疑节点被驱逐出集群的时间 。该参数默认为 0 。
  5. 无论哪种情况 , 都会触发:
    • 节点状态从 ONLINE 切换到 ERROR。
    • 回滚当前被阻塞的写操作 。
      mysql> delete from slowtech.t1 where id=1;ERROR 3100 (HY000): Error on observer while running replication hook 'before_commit'.
  6. ERROR 状态的节点会自动设置为只读 。
  7. 如果group_replication_autorejoin_tries不为 0,对于 ERROR 状态的节点,会自动重试,重新加入集群(auto-rejoin) 。
  8. 如果group_replication_autorejoin_tries为 0 或重试失败,则会执行 group_replication_exit_state_action 指定的操作 。可选的操作有: