多源复制仅并行拉取回放binlog,不自动重命名表、合并同名表或处理主键冲突;需手动配置通道、统一row+gtid、校验版本与参数,并在应用层解决库表映射与数据聚合。

不能靠“配置多源复制”直接把多个分库汇总成一个库——它只负责并行拉取和回放 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_order', SOURCE_PASSWORD = 'p@ssw0rd!', SOURCE_PORT = 3306, SOURCE_AUTO_POSITION = 1 FOR CHANNEL 'order_shard';
CHANGE REPLICATION SOURCE TO SOURCE_HOST = '192.168.1.11', SOURCE_USER = 'repl_user', SOURCE_PASSWORD = 'p@ssw0rd!', SOURCE_PORT = 3306, SOURCE_AUTO_POSITION = 1 FOR CHANNEL 'user_shard';
注意:
-
SOURCE_AUTO_POSITION = 1强烈建议启用(即 GTID 模式),避免主库切换时 position 错位 - 密码含特殊字符必须原样单引号包裹,MySQL 不做 URL 解码
-
SOURCE_HOST必须可被从库 DNS 解析,不能填localhost或未绑定的内网 IP(常见于 Docker 网络) - 建通道前先执行
STOP REPLICA;,否则可能因并发修改报ERROR 3080
必须统一 binlog_format 为 ROW 且开启 GTID
STATEMENT 或 MIXED 会导致非确定性语句(如 NOW()、UUID()、自增插入)在从库重放结果不一致,最终数据分裂。MySQL 不会报错,但 Seconds_Behind_Source 会持续增长,或出现 Waiting for dependent transaction to commit 等异常状态。
- 检查命令:
SHOW VARIABLES LIKE 'binlog_format';,输出必须是ROW - 主库上执行:
SET PERSIST binlog_format = 'ROW';,然后重启mysqld - GTID 必须开启:
gtid_mode = ON且enforce_gtid_consistency = ON - 配置时必须写
SOURCE_AUTO_POSITION = 1,否则报ERROR 3077:“When @@GLOBAL.GTID_MODE = ON, all replication channels must use AUTO_POSITION”
启动后必须手动处理库表映射与数据聚合
多源复制本身不提供任何数据合并能力。比如两个分库都有 orders 表,你不能指望它们自动合到从库的同一个 orders 表里——要么提前改名(如 order_shard_01.orders → shard01_orders),要么用复制过滤器隔离库级空间:
- 启动指定通道:
START REPLICA FOR CHANNEL 'order_shard';(START REPLICA;只启默认空通道) - 用通道级过滤:在从库上执行
CHANGE REPLICATION FILTER REPLICATE_REWRITE_DB = ((order_shard, order_agg)) FOR CHANNEL 'order_shard'; - 禁用并行复制:
replica_parallel_workers = 0,否则某个通道延迟会阻塞其他通道 - 所有上游主库的
auto_increment_increment设为相同值(如10),auto_increment_offset各不相同(如1,2,3…),并确保从库对应表设为READ ONLY - 定期检查:
SHOW REPLICA STATUS FOR CHANNEL 'order_shard';中的Seconds_Behind_Source和Retrieved_Gtid_Set,发现 GTID 跳跃大概率已丢事务
最易被忽略的是:你真正要汇总的不是“复制通道”,而是“业务数据逻辑”。通道只是搬运工,表名冲突、主键重叠、时间字段不一致、字符集差异……这些都得在应用层或同步后 ETL 阶段显式处理,MySQL 一句都不会帮你拦。











