单主模式需显式配置group_replication_single_primary_mode=ON,仅依赖MySQL 8.0.13+默认值不可靠;运行时必须通过SELECT @@group_replication_single_primary_mode和global_status验证是否为1,并结合read_only/super_read_only组合确认主节点。

单主模式必须显式启用 group_replication_single_primary_mode=ON
MySQL 8.0.13+ 默认开启单主模式,但这个“默认”只体现在新集群首次启动时;如果之前运行过多主模式,或配置文件中未明确设值,group_replication_single_primary_mode 可能为 OFF,导致意外进入多主状态。务必在所有节点的 my.cnf 中显式写入:
[mysqld] group_replication_single_primary_mode=ON
不写这行,靠“默认”不可靠——尤其在滚动重启、配置热加载或从备份恢复后,该变量可能回退为 OFF。
常见错误现象:SELECT * FROM performance_schema.global_status WHERE VARIABLE_NAME = 'group_replication_single_primary_mode'; 返回 OFF,但你以为是单主,结果多个节点都在接受写入,很快出现主键冲突或唯一索引报错 ER_DUP_ENTRY。
多主模式不能靠改配置文件直接生效
把 group_replication_single_primary_mode=OFF 写进配置并重启节点,大概率失败:MGR 会拒绝启动,报错 ERROR 3092 (HY000): The server is not configured properly to be an active member of the group。因为多主要求所有节点事务隔离级别为 READ COMMITTED,且 binlog 格式必须为 ROW,还禁用 CREATE TABLE ... SELECT 类语句。
正确做法是先确保所有节点满足前提条件,再用函数切换:
SET GLOBAL transaction_isolation='READ-COMMITTED';SET GLOBAL binlog_format='ROW';- 确认
slave_parallel_type=LOGICAL_CLOCK且slave_parallel_workers>0 - 执行
SELECT group_replication_switch_to_multi_primary_mode();(在任意一个已在线节点上)
注意:该函数会自动将其他节点逐个踢出再重加入,过程约需数秒,期间写入可能短暂阻塞。
切模式时 group_replication_member_weight 只影响单主选主,对多主无效
这个参数在单主模式下决定故障转移时谁接任主节点:值越高越优先。但它在多主模式下完全被忽略——因为所有节点本来就能写。如果你在多主集群里调大某个节点的 group_replication_member_weight,不会让它“更主”,也不会提升其负载权重。
容易踩的坑:
- 误以为调高 weight 能让某节点承担更多写入——实际写入分布由应用路由决定,MGR 层不做负载均衡
- 切到多主后忘了清理
group_replication_member_weight配置,下次切回单主时因值相同导致选主依赖server_uuid字典序,产生非预期主节点 - 在单主集群中把所有节点 weight 都设成 50(默认值),结果主挂了之后选主取决于
server_uuid最小的那个,而该节点磁盘 I/O 或内存可能最弱
验证当前模式不能只看配置文件,要查运行时状态
配置文件写了 ON,不代表当前就是单主。必须查两个地方:
第一,确认系统变量是否生效:SELECT @@group_replication_single_primary_mode; —— 返回 1 才是真 ON。
第二,确认当前主节点是谁:SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME = 'group_replication_primary_member'; —— 返回的是 server_uuid 字符串,不是主机名或 IP。拿这个值去查 SELECT @@server_uuid; 对应的节点,才是当前可写节点。
关键细节:即使在单主模式下,所有节点的 read_only=OFF 状态都可能是 ON(这是 MGR 自动设置的),但只有主节点的 super_read_only=OFF。所以最稳的判断方式是组合查询:
SELECT @@read_only, @@super_read_only, @@server_uuid;
主节点上你会看到 read_only=ON、super_read_only=OFF;从节点则是两者均为 ON。这个组合状态比任何配置或函数返回值都可靠。

















