mysql 5.7的replicate-rewrite-db不支持多源复制,仅全局生效且对各channel无效;设为set global后所有通道共用同一映射,易致同名库冲突;替代方案包括:主库使用不同库名、手动建库+replicate_do_table过滤、或由单一ddl master统一下发变更。

replicate-rewrite-db在多源复制中根本不起作用
MySQL 5.7 的 replicate-rewrite-db 不支持多源复制(Multi-Source Replication)的 channel 级别配置。它只能在全局生效,且仅对单源复制有效;一旦启用多源,该参数会被忽略,所有通道都按原始库名执行 DDL/DML,replicate-rewrite-db 完全不参与路由或重写逻辑。
为什么 SHOW SLAVE STATUS 里看不到 rewrite 效果
因为 rewrite 规则压根没被加载进任何 channel 的上下文。你执行 CHANGE REPLICATION FILTER replicate_rewrite_db = ((master_db, slave_db)) FOR CHANNEL 'chan1' 会直接报错 ERROR 1238 (HY000): Variable 'replicate_rewrite_db' is a GLOBAL variable and should be set with SET GLOBAL —— 它根本不接受 channel 限定。而设成 SET GLOBAL replicate_rewrite_db = ... 后,所有通道仍共用同一套映射,无法区分来源,导致不同 master 的同名库写入冲突时仍报 Error 'Can't create database 'test'; database exists' 或 ERROR 1050 (42S01): Table 'xxx' already exists。
真正可用的替代方案只有三类
必须绕过 rewrite 机制,从源头隔离或结构改造入手:
- 在每个 master 上使用**不同库名**:如
order_us、order_jp,从库无需改名,靠业务约定识别来源 - 用
replicate_ignore_db+ 手动建库建表:例如STOP SLAVE FOR CHANNEL 'master2'; SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; START SLAVE FOR CHANNEL 'master2';跳过CREATE DATABASE,再提前在从库手动创建带前缀的库(如order_master2),然后通过replicate_do_table显式指定表级同步目标 - DDL 统一由中间层下发:禁用所有 master 的
log_slave_updates,只允许一个“DDL Master”生成变更,其余 master 只负责业务写入;这样从库收到的 DDL 永远来自单一源头,避免重复建库建表
最容易被忽略的坑:replicate_do_table 不能跨库重定向
replicate_do_table 只能控制「是否应用某张表的事件」,不能把 master1.order 的变更重定向到 slave.order_v1。它不改变语句中的库名和表名,只是开关过滤器。所以即使你设了 replicate_do_table = 'order_v1.order',但主库 binlog 里是 INSERT INTO order ...,从库仍会尝试往 order 表写,而不是 order_v1.order —— 这个误解让很多人白调半天配置。











