mysql 8.0双向复制必须严格配置:server-id全局唯一(如1和2,禁用默认值1),auto-increment-increment统一设为2、offset错开(a为1生成奇数,b为2生成偶数),gtid_mode=on与enforce_gtid_consistency=on必须同时启用并重启生效,log_slave_updates=on确保双向binlog转发,binlog_format强制设为row。

server-id 和 auto-increment 必须错开,不能靠“默认值”蒙混
MySQL 8.0 双向复制不是两台机器互相认个主就行,server-id 必须全局唯一,且不能是默认的 1(尤其 Docker 或云主机场景下,多实例极易撞车)。auto-increment-increment 和 auto-increment-offset 是防主键冲突的第一道防线:两节点都设 auto-increment-increment = 2,但 NodeA 设 auto-increment-offset = 1(生成 1,3,5…),NodeB 设 auto-increment-offset = 2(生成 2,4,6…)。漏掉任一参数,INSERT 不指定 ID 就会直接报 Duplicate entry '1' for key 'PRIMARY'。
gtid_mode=ON 不是可选开关,必须和 enforce_gtid_consistency=ON 同时生效
gtid_mode = ON 单独开启毫无意义——它依赖 enforce_gtid_consistency = ON 来过滤不安全语句(比如 CREATE TABLE ... SELECT、事务内建临时表)。若后者为 OFF,MySQL 会拒绝启动 GTID 模式,并报错:ERROR 1782 (HY000): You must set enforce_gtid_consistency=ON before enabling GTID mode。两者必须同时写入 my.cnf 的 [mysqld] 段,且 MySQL 8.0 不支持在线动态开启,改完必须重启。
log_slave_updates=ON 是双向链路成立的前提,不是“从库可选功能”
没有 log_slave_updates = ON,从库收到主库 binlog 并执行后,不会把该事件再写进自己的 binlog。结果就是:A → B 的复制能跑,但 B → A 的链路根本收不到任何事件,SHOW SLAVE STATUS 中 Retrieved_Gtid_Set 始终为空。这不是网络或权限问题,是配置缺失导致复制通道物理断裂。所有参与双向复制的节点,无论角色如何切换,都必须启用此项。
binlog_format=ROW 是 GTID 强制要求,别信 MIXED 或 STATEMENT 能兼容
GTID 要求严格行格式,binlog_format = ROW 是硬性前提。设成 MIXED 或 STATEMENT 会导致 enforce_gtid_consistency = ON 直接拒绝执行 DDL/DML,连基本写入都会失败。验证方式很简单:SHOW VARIABLES LIKE 'binlog_format'; 必须返回 ROW;否则即使其他参数全对,复制也起不来。
server_uuid 必须天然不同(由 auto.cnf 自动生成),但人为改 server-id 错了,或者忘了重启 MySQL 让 gtid_mode 真正加载,就会让整个双向链路在启动阶段就静默失败。











