根本原因是gcs收不到心跳消息,表现为“gcs: timeout while waiting for message”错误;需检查skip-name-resolve、loose-group_replication_local_address静态ip配置、网络抖动(mtr)、防火墙idle timeout及group_replication_exit_state_action设置。

根本原因不是“连接失败”,而是组通信系统(GCS)收不到心跳消息,直接表现为 gcs: timeout while waiting for message 错误。这不是应用层问题,不能靠调 wait_timeout 或重置复制参数解决。
查日志先看有没有 gcs: timeout while waiting for message
这是最直接的信号——GCS 层已中断,所有后续状态变化(UNREACHABLE、ERROR、OFFLINE)都是结果,不是原因。
- 立刻执行
tail -n 200 /var/lib/mysql/error.log | grep "gcs: timeout",5 分钟内高频出现即确认是 GCS 心跳断了 - 别急着查
performance_schema.replication_group_members状态,那只是“已经崩了”的快照 - 这个错误和 GTID、binlog 位置、用户权限完全无关,跳过所有同步类排查步骤
skip-name-resolve 和 loose-group_replication_local_address 必须静态 IP
DNS 解析卡住或地址解析不稳定,会阻塞 GCS 初始化阶段的节点发现流程,导致心跳无法建立。
- 所有节点
my.cnf中必须有skip-name-resolve=ON,否则 GCS 可能卡在反向 DNS 查询上 -
loose-group_replication_local_address必须写死 IPv4 地址+端口,例如192.168.164.30:33061,绝不能是域名、localhost或0.0.0.0 - 用
netstat -tlnp | grep :33061验证端口是否真在监听该 IP,而不是只监听127.0.0.1
用 mtr 测网络抖动,别只看 ping 通不通
节点间 TCP 连通 ≠ GCS 消息可靠投递。MGR 对 RTT 抖动极其敏感,Paxos 投票超时阈值默认约 5 秒,σ > 20ms 就可能触发误判。
- 执行
mtr --report --count 100 节点B_IP,重点关注两列:Loss%(>0.5% 危险)、Stdev(标准差 >20ms 极大概率引发 GCS 超时) - 防火墙或云厂商中间设备若启用了 idle timeout(如 AWS NLB 默认 350 秒),会导致 GCS 连接被静默中断,telnet 端口仍通但心跳包丢弃
- 检查
sysctl net.ipv4.tcp_keepalive_time,若小于 300 秒,需配合group_replication_flow_control_mode = QUOTA缓冲突发流量
group_replication_exit_state_action 设成 offline_mode 会假死
节点进程还在,MySQL 服务也正常响应,但 GCS 已断开、事务被拒绝、状态显示 OFFLINE——看起来像“掉线”,其实是“活着但拒工”。
- 执行
SELECT VARIABLE_VALUE FROM performance_schema.global_variables WHERE VARIABLE_NAME = 'group_replication_exit_state_action';确认当前值 - 若为
offline_mode,仅重启 mysqld 不起作用;必须手动执行STOP GROUP_REPLICATION;再START GROUP_REPLICATION; - 想让故障后自动重试,确保
group_replication_autorejoin_tries≥ 3(默认是 0,等于不重试)
最容易被忽略的是:GCS 心跳中断从来不是孤立现象,它总是和 DNS、静态 IP、网络抖动三者之一强绑定。盯着 MEMBER_STATE 状态反复切来切去,不如直接抓 error.log 里那条 gcs: timeout,然后按顺序查这三项——90% 的频繁离线都止步于此。











