mysql主从架构本身不会出现脑裂,脑裂仅发生于双主或多写场景;所谓“主从脑裂”实为误配双主、从库被直连写入或super_read_only未生效等配置错误所致。

MySQL主从架构本身不会出现脑裂——脑裂只可能发生在**双主(Master-Master)或集群多写场景**中。如果你在所谓“主从”环境里观察到两个节点同时接受写入、数据不一致、客户端写入丢失等现象,那大概率是误配成了双主,或人为绕过读写分离逻辑直连了本该只读的从库。
为什么主从架构下会“看起来像脑裂”
这不是真正的脑裂,而是配置错误或应用层失控导致的写入混乱:
- 应用未强制走读写分离中间件(如 ProxySQL、ShardingSphere),部分请求直连了从库
UPDATE或INSERT - DBA 手动执行
SET GLOBAL super_read_only = OFF后忘记恢复,使从库长期处于可写状态 - 监控缺失,
Slave_SQL_Running为No多日未被发现,从库已落后大量事务,此时切流量过去就等于写入“历史版本” - 使用了
log_slave_updates = ON且未设replicate_ignore_db,导致从库又把自身写入同步回原主库,形成环形复制和主键冲突(报错Error_code: 1062)
确认是否真发生了双写:查 show master status 和 show slave status\G
在疑似“双主”的两个节点上分别执行:
SHOW MASTER STATUS;
看 File 和 Position(或 Executed_Gtid_Set)是否持续前进;再执行:
SHOW SLAVE STATUS\G
重点检查三项:
-
Slave_IO_Running和Slave_SQL_Running是否都为Yes -
Seconds_Behind_Master是否稳定为0(GTID 模式下看Retrieved_Gtid_Set与Executed_Gtid_Set是否一致) -
Relay_Master_Log_File和Exec_Master_Log_Pos对应的主库 binlog 位置,是否在主库show master status的范围内
如果某节点的 Executed_Gtid_Set 包含了不属于上游主库的事务 ID(比如有 uuid:1-100 但主库只有 uuid:1-50),说明它自己执行过写操作——这就是双写铁证。
预防关键:用 super_read_only + 权限隔离 + 自动化校验
真正防住“类脑裂”,靠的不是复杂仲裁,而是三层硬约束:
- 所有从库启动时默认启用:
super_read_only = ON,且禁止应用账号拥有SUPER权限(否则可绕过) - 应用连接池必须区分
writeHost和readHost,中间件(如 MyCat、ProxySQL)开启auto-failover并配置read_only=1健康检查 - 每日定时跑校验脚本,比对主从库关键表的
CHECKSUM TABLE结果,异常立即告警(注意:大表慎用,可用pt-table-checksum分块)
已经双写了怎么办:优先止损,再追平
不要急着 START SLAVE 或跳过事务。先停写,再判断:
- 若从库写入的是测试/日志类无业务意义的数据,可直接
RESET SLAVE ALL,重做基于备份的恢复 - 若从库写入了真实业务数据(如订单表),需人工比对 binlog:用
mysqlbinlog --base64-output=DECODE-ROWS -v解析从库的mysql-bin.*,提取其独有的 DML,评估是否可合并回主库(通常不可逆,建议标记为脏数据) - 严禁使用
SET GLOBAL sql_slave_skip_counter = 1跳过 GTID 事务,会导致GTID_EXECUTED不一致,后续无法重建复制
最易被忽略的一点:很多团队以为只要关掉从库写权限就安全了,却忘了 MySQL 8.0 默认 read_only = OFF 时,super_read_only 是无效的——必须两者同时设 ON 才真正锁死写入。











