mysql 8.0+ 必须使用 change replication source to(非 change master to),需显式指定 for channel,执行前须 stop replica,source_host 必须可解析,多源自增冲突需统一 auto_increment_increment 并差异化 offset,从库表应设 read only,禁用 replica_parallel_workers 更稳定。

必须用 CHANGE REPLICATION SOURCE TO,不是 CHANGE MASTER TO
MySQL 8.0+ 已完全移除 CHANGE MASTER TO,继续用会直接报错 ERROR 1064 (42000)。所有通道配置必须用新语法,并显式指定 FOR CHANNEL 'xxx'。
- 通道名不能重复、不能为空,推荐用语义化命名,比如
chan_us_east、chan_sg_prod,避免master1这类易混淆名称 - 执行前必须先停复制:
STOP REPLICA;,否则可能触发ERROR 3080 (HY000)(并发修改元数据冲突) -
SOURCE_HOST必须能被从库 DNS 解析——填localhost、未绑定的 Docker 内网 IP 或不可达域名,IO 线程会卡在Connecting to master
auto_increment_offset 和 auto_increment_increment 必须全局对齐
多主一从最常爆的 Duplicate entry 'X' for key 'PRIMARY',90% 出在这里:两个主库各自插入自增主键,值撞了;更糟的是,如果从库自己还手动 INSERT 过该表,auto_increment 计数器就彻底乱了。
- 所有主库设相同
auto_increment_increment(如10),再配不同auto_increment_offset(如1、2、3…) - 从库对应表必须设为
READ ONLY:ALTER TABLE t1 READ ONLY = 1;,防止误写入破坏序列 - 禁用从库自身生成自增值:
SET GLOBAL auto_increment_offset = 0;+SET GLOBAL auto_increment_increment = 1;(仅限从库)
别开 replica_parallel_workers,它在多源下反而拖后腿
开启并行复制本意是提速,但在多源场景中,每个通道独占 worker 队列,一旦某个通道延迟(比如网络抖动、大事务未提交),其他通道的 worker 会被协调线程阻塞,表现为所有通道 Seconds_Behind_Source 突然飙升,而 CPU/IO 却很低。
- 实测中,
replica_parallel_workers = 0反而更稳;若真要开,建议只设1,且确保各主库 binlog 落盘策略一致(如都开sync_binlog = 1) - 务必确认
relay_log_purge = ON,否则 relay log 不自动清理,磁盘迟早占满 - 检查每个通道状态用:
SHOW REPLICA STATUS FOR CHANNEL 'chan_us_east'\G,重点关注Retrieved_Gtid_Set是否连续、Executed_Gtid_Set是否跟上
GTID 模式下,replica_gtid_policy = OFF 是临时止血手段,不是常态
当某通道因冲突卡住(比如主库双写同一条记录),START REPLICA 会失败,错误里带 Could not execute Write_rows_v1 event。此时可手动跳过:SET GTID_NEXT = 'ANONYMOUS'; BEGIN; COMMIT; SET GTID_NEXT = AUTOMATIC;,但前提是已关掉 replica_gtid_policy。
- 临时跳过前,先停通道:
STOP REPLICA FOR CHANNEL 'chan_sg_prod'; - 跳过后立刻重置:
SET GLOBAL replica_gtid_policy = ON;,否则后续事务无法按 GTID 正确定位 - 真正该做的是前置规避:应用层分库路由、或用
REPLICATE_DO_DB做通道级库过滤,避免同表多源写入
多源复制本身不校验逻辑一致性,它只是机械地拉日志、回放 SQL。最容易被忽略的点是:你认为“只读从库”很安全,但只要没设 READ ONLY,或者 DBA 手动执行过 INSERT,自增序列和 GTID 映射就可能永久错位——这种问题往往在切换主库或重建从库时才暴露。











