不能靠“配置多源复制”直接汇总多个库——它仅并行拉取并回放各主库binlog,不自动重命名表、不合并同名表、不处理主键冲突;需先启用多源通道,再手动解决库表映射与数据聚合问题。

不能靠“配置多源复制”直接把多个库汇总成一个库——多源复制只是让一个从库同时拉多个主库的 binlog 并分别回放,它不自动重命名表、不合并同名表、不处理主键冲突。你真正要做的,是先让多源通道跑起来,再手动解决库表映射和数据聚合问题。
确认 MySQL 版本与核心参数是否就绪
低于 5.7.17 的版本存在 FOR CHANNEL 解析缺陷,容易报错 ERROR 1235;8.0.23+ 必须用 CHANGE REPLICATION SOURCE TO,CHANGE MASTER TO 已弃用但兼容。关键检查项:
-
SELECT VERSION();返回至少5.7.17(推荐5.7.28+或8.0.33+) -
SHOW VARIABLES LIKE 'log_bin';必须为ON(从库也得开 binlog) -
SHOW VARIABLES LIKE 'server_id';必须是非零且全局唯一(所有主库 + 从库不能重复) -
master_info_repository和relay_log_info_repository必须设为TABLE,否则通道元数据无法持久化,重启后丢失
为每个主库创建独立 channel 并配置连接
漏写 FOR CHANNEL 或复用空名/非法字符名(如含空格、斜杠),会导致静默失败或报错 ERROR 1238。每个主库必须绑定语义化通道名,且全程大小写敏感:
CHANGE REPLICATION SOURCE TO SOURCE_HOST = '192.168.1.10', SOURCE_USER = 'repl_a', SOURCE_PASSWORD = 'p@ssw0rd!', SOURCE_PORT = 3306, SOURCE_AUTO_POSITION = 1 FOR CHANNEL 'order_master';
CHANGE REPLICATION SOURCE TO SOURCE_HOST = '192.168.1.11', SOURCE_USER = 'repl_b', SOURCE_PASSWORD = 'p@ssw0rd!', SOURCE_PORT = 3306, SOURCE_AUTO_POSITION = 1 FOR CHANNEL 'user_master';
注意:SOURCE_AUTO_POSITION = 1 强烈建议启用(即 GTID 模式),避免后期主库切换导致 position 错位;密码含特殊字符必须原样单引号包裹,MySQL 不做 URL 解码。
启动与验证必须按 channel 逐个操作
START REPLICA(或旧版 START SLAVE)不带 FOR CHANNEL,只启动默认通道(空字符串名),其余通道完全不动——这是最常卡住的地方。状态检查同理:
- 启动:用
START REPLICA FOR CHANNEL 'order_master';和START REPLICA FOR CHANNEL 'user_master'; - 查状态:
SHOW REPLICA STATUS FOR CHANNEL 'order_master'\G,不能只看SHOW REPLICA STATUS - 批量监控:
SELECT CHANNEL_NAME, SOURCE_UUID, SERVICE_STATE FROM performance_schema.replication_connection_status;
若 IO_Running: No,优先查主库 repl 用户是否允许该从库 IP 连接、防火墙是否放行、host 是否用了 'repl'@'%' 而非具体 IP;若 SQL_Running: No 且报 Table 'xxx' doesn't exist,说明目标从库上还没 CREATE DATABASE,多源复制默认不建库建表。
同名库表冲突必须提前干预,不能等报错再处理
比如 shop_db.orders 和 finance_db.orders 同时同步到从库,会因 ERROR 1050 (42S01): Table 'orders' already exists 卡死。解决方案不是“配置一下就合并”,而是明确选择一种路径:
- 用
replicate-rewrite-db = 'shop_db->shop_master'重写库名(需在 my.cnf 中配置并重启,且仅作用于库级) - 更灵活的是 per-channel 过滤:
CHANGE REPLICATION FILTER replicate_do_table = ('shop_db.orders') FOR CHANNEL 'shop_chan'; - 若真要合表(如都进
all_orders),必须在从库上手动建好目标表,并用mysqldump --no-create-info导入数据后,再通过INSERT ... SELECT或VIEW聚合——多源复制本身不提供 SQL 聚合能力
GTID 模式下若卡在 Waiting for master to send event,大概率是 gtid_executed 集合不一致,检查导入初始数据时是否用了 --set-gtid-purged=ON,而非 --master-data=2。











