MySQL 8.0+多源复制中必须用CHANGE REPLICATION FILTER动态为各通道设置过滤器,因my.cnf中的replicate-do-db等参数仅作用于默认通道;该命令需指定FOR CHANNEL,支持REPLICATE_DO_DB或REPLICATE_WILD_DO_TABLE等白名单规则,不支持黑名单混用,且修改立即生效。

多源复制中必须用 CHANGE REPLICATION FILTER 动态设置过滤器
MySQL 8.0+ 多源复制不支持在 my.cnf 里为不同通道配置 replicate-do-db 这类全局参数——它们只作用于默认通道(''),对命名通道无效。真正能按通道隔离过滤规则的,只有运行时命令 CHANGE REPLICATION FILTER。
这个命令必须在从库已配置好多个复制通道(如 'master_a'、'master_b')后执行,且无需重启 mysqld,修改立即生效(下次 START SLAVE 时加载)。
常见错误是试图在配置文件里写:
replicate-do-db = app1 replicate-do-db = app2
这只会让两个库都应用到默认通道,对命名通道完全没影响。
CHANGE REPLICATION FILTER 的语法和参数限制
命令格式固定,必须显式指定 FOR CHANNEL,且只能设置白名单类过滤器(REPLICATE_DO_DB、REPLICATE_WILD_DO_TABLE 等),不支持黑名单组合(如不能同时设 REPLICATE_IGNORE_DB 和 REPLICATE_DO_DB)。
关键约束:
-
REPLICATE_DO_DB仍受 USE 库上下文限制,跨库语句(如INSERT INTO app2.t1在USE app1下执行)会被跳过 -
REPLICATE_WILD_DO_TABLE是更安全的选择,匹配事件中的实际库表名,与当前 USE 无关 - 多个规则用逗号分隔,但 MySQL 不保证顺序;若冲突(如
app1.%和app%.%同时存在),以最具体匹配为准 - 不能混用
REPLICATE_WILD_DO_TABLE和REPLICATE_WILD_IGNORE_TABLE—— 官方明确警告“行为未定义”
实操示例:为两个 Master 分别只同步指定库
假设你已建好两个通道:
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
CHANGE MASTER TO MASTER_HOST='192.168.1.71', ... FOR CHANNEL 'sales';<br>CHANGE MASTER TO MASTER_HOST='192.168.1.72', ... FOR CHANNEL 'log';
现在要让 sales 通道只同步 sales_db,log 通道只同步 log_db:
CHANGE REPLICATION FILTER REPLICATE_DO_DB = (sales_db) FOR CHANNEL 'sales';<br>CHANGE REPLICATION FILTER REPLICATE_DO_DB = (log_db) FOR CHANNEL 'log';
如果想更可靠(避开 USE 依赖),改用通配符表过滤:
CHANGE REPLICATION FILTER REPLICATE_WILD_DO_TABLE = ('sales_db.%') FOR CHANNEL 'sales';<br>CHANGE REPLICATION FILTER REPLICATE_WILD_DO_TABLE = ('log_db.%') FOR CHANNEL 'log';
执行后直接 START SLAVE FOR CHANNEL 'sales'; 即可,不用重启。
验证过滤是否生效的关键检查点
光看 SHOW SLAVE STATUS FOR CHANNEL 'xxx'\G 不够,容易误判。必须确认三件事:
- SQL 线程状态是否为
Slave has read all relay log或Waiting for an event from Coordinator(说明它真正在“读”而不是“跳过”) -
Exec_Master_Log_Pos是否随主库写入持续增长(若卡住,可能是规则太严,整条事件被跳过) - 在从库手动执行一条典型跨库语句(如
USE other_db; INSERT INTO sales_db.order VALUES (1);),再查sales_db.order是否有数据 —— 这直接暴露REPLICATE_DO_DB的 USE 依赖缺陷
最易被忽略的是:多源复制下,每个通道的过滤器完全独立,但所有通道共用同一个 SQL 线程池(除非启用 slave_parallel_workers > 0 并配置 slave_parallel_type = LOGICAL_CLOCK)。这意味着一个通道的过滤逻辑错误,不会影响另一个通道,但排查时容易误以为是全局问题。










