网络恢复了,组却回不来:MySQL 9.7.4 修掉的 Group Replication 分区恢复死循环
一个典型的现场:机房网络抖动几分钟,Group Replication 组丢了 quorum;网络恢复后,ping、端口、路由全部正常,但组没有自己恢复:写入一直挂起,错误日志里反复出现同一行:
MY-013781: Error sending connection delegation command
这条路径在 MySQL 9.7.4(2026-10-20)中被修掉了,Bug #39767762。发布说明见 MySQL 9.7.4 Release Notes。
connection delegation 是哪一环
它属于 group_replication 的通信栈,是成员之间建立点对点连接前的协商步骤:成员需要连接对端时,先发一条 delegation command,由对端按自己配置的 endpoint 完成握手。它处理「谁去连谁、连哪个地址」,不是复制数据通道本身。
在 9.7.4 之前,这次 publication 尝试是阻塞式的。当它卡住或失败时,重连循环就会反复卡在同一步,无法回到正常的重连处理流程。
为什么「网络好了」不等于「组能自己回来」
组的自愈依赖重连循环持续推进:重新拿到多数派、产生新视图、成员进入 ONLINE。这条链上任何一步被卡死,后面的步骤都不会发生。
Bug #39767762 的问题就在这一步:delegation 用阻塞方式发布,失败后没有把控制权交回重连逻辑,循环就在原地反复重复。底层网络早已恢复,但组仍然处于 quorum 丢失状态。
为什么是阻塞而不是报错
写事务提交前要经过组通信确认。组成员停在重连循环、视图不更新时,这条路径不会主动返回失败,只会等待,所以客户端看到的是语句长时间挂起、连接超时,而不是一条明确的错误码。
怎么确认是这条路径
先看错误日志有没有同一行反复出现(路径按实际环境的 error_log 变量):
grep -n 'MY-013781' /var/log/mysql/error.log
grep -n 'Error sending connection delegation command' /var/log/mysql/error.log
再看成员视图,重点看 MEMBER_STATE:出现 ERROR、UNREACHABLE 卡住不动,基本就说明组没有恢复:
SELECT MEMBER_HOST, MEMBER_PORT, MEMBER_STATE, MEMBER_ROLE, MEMBER_VERSION
FROM performance_schema.replication_group_members;
对照成员统计,观察队列是否还在推进;如果数字长时间不变,就说明组通信确实停了:
SELECT MEMBER_ID,
COUNT_TRANSACTIONS_IN_QUEUE,
COUNT_TRANSACTIONS_REMOTE_IN_APPLIER_QUEUE
FROM performance_schema.replication_group_member_stats\G
顺便核对地址配置,后面多网卡场景要用到:
SHOW STATUS LIKE 'group_replication%';
SELECT @@group_replication_local_address, @@group_replication_group_seeds;
如果日志里 MY-013781 在循环出现、成员视图停在非 ONLINE 状态、队列不推进,三条同时成立,就可以判断为这个 bug。
9.7.4 改了什么
connection delegation 改成单次非阻塞的 publication 尝试:发一次,不成就返回,把重试交回正常的重连处理。重连循环因此能继续往前走,而不是停在 delegation 这一步。升级到 9.7.4 后,同样场景下组能自己收敛。
另一个坑:多网卡主机、同一 SQL 端口
同一台多网卡主机上跑多个成员、用不同 IP、但 SQL 端口相同,会出现成员加不进去的情况。
原因是本地成员原先按「所有本地接口」识别,两个绑定在不同 IP 上、监听同一 SQL 端口的实例会被当成同一个本地成员。修复后,本地成员按配置的 endpoint 识别,不同 IP 加同一 SQL 端口可以区分开。
但 XCom 层的要求没变:localAddress 端口必须各不相同。所以配置要写成这样:
# 成员 A
group_replication_local_address = "192.0.2.11:33061"
group_replication_group_seeds = "192.0.2.11:33061,192.0.2.12:33062"
# 成员 B(同一台多网卡主机)
group_replication_local_address = "192.0.2.12:33062"
group_replication_group_seeds = "192.0.2.11:33061,192.0.2.12:33062"
SQL 端口可以相同,XCom 端口不能。
同一版本里的其他 GR 修复
9.7.4 还修了这些:消息解码限制(Bug #39905199)、消息发送方校验(Bug #39851456)、插件卸载时的 UDF 生命周期处理(Bug #39838541)、恢复状态校验(Bug #39832216)、peer address 处理(Bug #39654054)。排查 GR 问题时,可以一并核对版本。