mysql_switchover.sh脚本专为MySQL 8.0一主一从GTID架构设计,不适用于双主架构;强行使用会导致角色冲突、GTID集重叠和循环复制等严重问题。

mysql_switchover.sh 脚本不能直接用于双主架构——它专为「一主一从」GTID切换设计,强行套用会因角色冲突、GTID集重叠、循环复制等问题导致复制中断甚至数据错乱。
双主不是“两个主库跑着就行”,而是需要严格规避自增冲突、环路写入、状态同步混乱这三类问题。下面说清楚怎么做、为什么这么定、以及哪些地方一动就崩。
双主必须关掉 auto_increment_increment 和 auto_increment_offset?
不是“必须关”,而是必须显式设对。MySQL默认值是 auto_increment_increment = 1、auto_increment_offset = 1,双主下不改就会出现主A和主B都插入 ID=1、ID=2……造成主键冲突。
正确做法是两节点配成互补序列:
- 主A:
auto_increment_increment = 2,auto_increment_offset = 1→ 生成 1,3,5,7… - 主B:
auto_increment_increment = 2,auto_increment_offset = 2→ 生成 2,4,6,8…
这两项必须写进 my.cnf 并重启生效,动态 SET 只对当前会话有效,且从库复制线程不继承该会话设置,极易漏掉。
GTID 模式下双主如何避免循环复制?
即使开了 log_slave_updates,双主之间也会把对方的事务再 relay 回去,形成无限循环。核心解法只有两个:
- 在每台主库上创建专用复制用户,并限制其只读取对方 binlog 中“非本机产生的事务”——靠
replicate_ignore_server_ids实现(MySQL 8.0.23+ 支持) - 更通用稳妥的做法:用
replicate_rewrite_db或replicate_do_table做逻辑过滤,但要求业务表名/库名有明确区分边界 - 禁用
log_slave_updates是常见错误操作:这样旧主切回从角色后,无法被其他节点接入,高可用链就断了
验证是否生效:在主A执行 INSERT 后,查主B的 SELECT @@global.gtid_executed;,结果里不应包含主A的 server_uuid 对应的事务段;反之亦然。
mysql_switchover.sh 能否改造成双主切换脚本?
不能轻量改造。原脚本假设“只有一个主、一个从”,所有检查逻辑(如 get_mysql_value 查询 SELECT @@gtid_executed、RESET SLAVE ALL 执行顺序、锁文件机制)都基于单向复制流设计。
双主切换本质是“角色翻转 + 过滤策略重载 + VIP 切换”,需额外处理:
- 切换前必须停掉双方的写入(或通过应用层灰度),否则 GTID 集会持续增长,新角色无法准确定位同步点
- 切换后要重新配置
CHANGE REPLICATION SOURCE TO的SOURCE_AUTO_POSITION = 1,并确保SOURCE_SERVER_UUID指向当前真正的上游 - 原脚本没有 VIP 管理逻辑,而双主高可用必然依赖 Keepalived 或类似工具绑定虚拟 IP,这部分必须外挂或重写
真要自动化,建议直接用 MHA 或 Orchestrator,它们原生支持双主拓扑识别与安全切换路径。
客户端连接双主时,jdbc:mysql:loadbalance:// 和 jdbc:mysql://[host1],[host2] 有何区别?
前者是 Connector/J 的负载均衡模式,SQL 线程自动分发读请求到两个节点,但不保证故障转移——如果 host1 宕机,后续连接仍可能持续尝试它,直到超时;后者是故障转移模式(failover),连接串中第一个地址失败后,立即尝试第二个,但所有写操作默认发往第一个地址。
关键细节:
- 使用 failover 模式时,必须配合应用层判断主从角色,否则写请求打到只读从库会报错
ERROR 1290 (HY000) - 两种模式都不解决“双主同时可写”带来的数据冲突问题,业务仍需自己控制写入口(例如通过中间件或 VIP 统一路由)
- 连接串里不能混用不同端口的实例(如
:3306和:3307),否则驱动解析失败,报错Malformed database URL
真正落地时,别只盯着脚本和连接串——双主的脆弱点从来不在配置行数,而在 server_uuid 是否全局唯一、gtid_purged 是否清理干净、以及任意一次手动 SET GLOBAL gtid_executed 是否误清了未同步事务。


















