mysql 5.7.6起支持多源复制,允许一个从库并行接收多个主库数据,适用于数据汇总、集中备份等场景,需基于gtid或日志位置配置独立通道,且各主库必须server_id唯一、log-bin开启。

CHANGE MASTER TO 配置多个通道前,必须确认 MySQL 版本 ≥ 5.7.5,且从库已启用 log_bin 和唯一 server_id;否则 START SLAVE 会静默失败或报错 ERROR 3079 (HY000)。
确认多源复制基础条件是否满足
不是所有“能连上”的 MySQL 实例都支持多源复制。关键检查项有三个:
-
SELECT VERSION();必须返回5.7.5或更高(如8.0.33);5.6或更低版本不支持FOR CHANNEL -
SHOW VARIABLES LIKE 'log_bin';必须为ON—— 即使是“从库”,多源复制也要求它开启 binlog(用于后续级联或故障切换) -
SHOW VARIABLES LIKE 'server_id';必须是非零、全局唯一值;若多个主库用了相同server_id,复制通道会互相干扰,SHOW SLAVE STATUS中可能显示Seconds_Behind_Master: NULL且无错误提示
漏掉任一条件,后续配置看似成功,实际数据不会流入。
为每个主库单独配置独立复制通道
不能复用同一个 CHANGE MASTER TO 命令覆盖多个主库 —— 每个主库必须绑定唯一通道名,且通道名需全程一致(大小写敏感)。
- 通道名建议语义化,例如
'prod_order'、'prod_user',避免用'channel1'这类无意义命名,否则查performance_schema.replication_connection_status时无法快速定位来源 - 必须显式指定
MASTER_AUTO_POSITION = 1(启用 GTID),否则在主库发生 failover 或 binlog 切换后,从库极易因 position 偏移错位而中断;MASTER_LOG_FILE+MASTER_LOG_POS方式仅适用于一次性初始化,不可长期依赖 - 密码字段不能留空;若主库用户密码含特殊字符(如
@、/),需在 SQL 中用单引号包裹并原样输入,MySQL 不做 URL 解码
示例(两个主库):
CHANGE MASTER TO MASTER_HOST = '10.20.30.101', MASTER_PORT = 3306, MASTER_USER = 'repl', MASTER_PASSWORD = 'p@ssw0rd!', MASTER_AUTO_POSITION = 1 FOR CHANNEL 'sales_db'; CHANGE MASTER TO MASTER_HOST = '10.20.30.102', MASTER_PORT = 3306, MASTER_USER = 'repl', MASTER_PASSWORD = 'p@ssw0rd!', MASTER_AUTO_POSITION = 1 FOR CHANNEL 'user_db';
启动与验证各通道状态
START SLAVE; 默认只启动默认通道(空字符串通道),对多源无效;必须按通道名逐一启动或使用通配符。
- 启动指定通道:
START SLAVE FOR CHANNEL 'sales_db'; - 启动全部已配置通道:
START SLAVE FOR ALL CHANNELS;(MySQL 5.7.9+ 支持) - 验证是否真正运行:
SELECT CHANNEL_NAME, SERVICE_STATE, LAST_IO_ERROR, LAST_SQL_ERROR FROM performance_schema.replication_connection_status;—— 注意看SERVICE_STATE是ON,且错误字段为空;LAST_IO_ERROR非空常意味着网络不通或用户权限不足 - 延迟判断不能只看
Seconds_Behind_Master:该字段在多源下仅反映默认通道,必须查performance_schema.replication_applier_status_by_coordinator或用SHOW SLAVE STATUS FOR CHANNEL 'xxx'\G
避免跨库写入冲突的硬约束
MySQL 多源复制本身不做数据合并逻辑 —— 它只是把不同主库的 binlog 并行应用到同一实例。如果两个主库都向同一个表写入(如都写 orders 表),大概率触发主键/唯一键冲突,SQL 线程会停在报错处(Slave_SQL_Running: No),且不会自动跳过。
- 最稳妥做法:确保各主库写入的库名、表名完全隔离(如
sales_orders、user_orders),从库侧不做重命名或映射 - 若必须合并同名表,必须在应用层或 ETL 层完成分库路由 + ID 生成策略(如 Snowflake ID),数据库层不做干预
- 不要依赖
replicate_rewrite_db:该参数在多源下行为未定义,MySQL 官方文档明确标注 “not supported in multi-source replication”
一旦出现冲突,SET GLOBAL sql_slave_skip_counter = 1 是危险操作,GTID 模式下甚至不可用;应优先查清源头写入逻辑,而非掩盖错误。











