MySQL 8.0+ 多源复制不能自动合并多主库数据,仅支持并行拉取与独立回放;需手动配置通道名、启用ROW格式与唯一server_id,并通过replicate_rewrite_db/table避免表名冲突。

MySQL 8.0+ 多源复制是否真能“合并”多个主库的数据?
不能直接合并。MySQL 的多源复制(Multi-Source Replication)本质是让一个从库同时接收多个主库的 binlog 并分别应用,但它不解决数据冲突、主键重复、表结构不一致等合并逻辑问题。它只是“并行拉取 + 独立回放”,不是 ETL 或 CDC 合并工具。如果你期望的是把 shop_db.orders(来自主库 A)和 logistics_db.orders(来自主库 B)自动合到同一个 all_orders 表里——MySQL 原生做不到。
如何配置多源复制:CHANGE REPLICATION SOURCE TO 是关键
MySQL 8.0.23 起弃用 CHANGE MASTER TO,统一为 CHANGE REPLICATION SOURCE TO,且必须为每个主源指定唯一通道名(channel)。漏掉通道名或重复会导致配置失败或行为不可控。
实操要点:
- 每个主库需开启
binlog_format = ROW和server_id全局唯一 - 从库启用
relay_log_recovery = ON,避免通道间 relay log 损坏互相影响 - 创建通道时必须显式命名,例如:
CHANGE REPLICATION SOURCE TO SOURCE_HOST='192.168.1.10', SOURCE_USER='repl', SOURCE_PASSWORD='xxx', SOURCE_PORT=3306, SOURCE_AUTO_POSITION=1 FOR CHANNEL 'src_shop';
- 启动指定通道:
START REPLICA FOR CHANNEL 'src_shop';,不加FOR CHANNEL默认只启 default channel
为什么 SHOW REPLICA STATUS 看不到所有通道?
SHOW REPLICA STATUS 只显示默认通道(空字符串名)的状态。这是最常踩的坑——你以为复制正常,其实只有其中一个通道在跑。必须指定通道名才能查真实状态:
SHOW REPLICA STATUS FOR CHANNEL 'src_shop';SHOW REPLICA STATUS FOR CHANNEL 'src_log';- 想批量查看?用
performance_schema.replication_connection_status表,字段CHANNEL_NAME和SOURCE_UUID是关键
另外,Seconds_Behind_Source 在多源下意义弱化:它只反映该通道最新事件与本地执行的时间差,无法体现跨通道的数据新鲜度一致性。
主库表名相同但语义不同,从库怎么避免冲突?
如果主库 A 和主库 B 都有 users 表,且你希望它们都同步到从库,就必须重映射表名,否则会写冲突。MySQL 不支持原生“按通道前缀自动重命名”,得靠 replicate_rewrite_db 或 replicate_rewrite_table(5.7+)。
推荐做法(MySQL 8.0.23+):
- 在从库 my.cnf 中配置通道级重写:
[mysqld] replicate_rewrite_db="shop_db->merged_shop_db" replicate_rewrite_db="log_db->merged_log_db"
- 或者更精细地用
replicate_rewrite_table重命名单表:replicate_rewrite_table="shop_db.users->merged_shop_db.shop_users" - 注意:重写规则在 IO thread 拉取后、SQL thread 执行前生效,不影响主库 binlog;但一旦启用,就不能再对目标库做 DDL(如改名),否则可能中断复制
真正难的不是配置,而是业务层要清楚每张“被重命名”的表来源、更新频率、是否允许并发写——MySQL 不管这些,它只管不报错地执行。











