MySQL复制中如何用 replicate-do-db
和 replicate-ignore-db
控制库级过滤
这两个参数只在
STATEMENT格式复制下按「当前数据库」生效,
ROW格式下基本失效——因为行格式不记录
USE db_name,从库无法判断语句本意操作的是哪个库。
常见错误现象:
INSERT INTO other_db.t1 ...在主库执行时没切换库,但目标表在 other_db,从库却因
replicate-do-db=mydb被跳过,数据丢失。 仅当所有 DML 都显式
USE mydb且不跨库操作时,
replicate-do-db才可靠 避免混用
STATEMENT和
ROW格式;若必须做库级过滤,统一用
ROW+ 表级规则更稳妥 多个库需过滤时,每项单独写一行配置,不能用逗号分隔
用 replicate-wild-do-table
实现模糊表名匹配
这是最常用也相对可靠的过滤方式,支持通配符
%和
_,对
STATEMENT和
ROW均有效,且基于实际修改的表名匹配,不依赖当前库上下文。
例如只同步
user_service库下以
user_开头的表:
replicate-wild-do-table = user_service.user_%
注意点:
通配符只作用于表名部分,库名不能含%(即不支持
%.t1) 如果主库有
user_service.user_profile和
order_service.user_log,后者不会被匹配——
replicate-wild-do-table是「库名.表名」全路径匹配 多个规则按顺序逐条匹配,第一条命中即执行,后续忽略;未命中则跳过该事件
为什么 binlog-do-db
不等于复制过滤
binlog-do-db是主库参数,控制哪些库的更改写入 binlog;它不是复制过滤器,而是日志裁剪开关。一旦启用,连
SHOW BINLOG EVENTS都看不到被排除库的操作,GTID 也会断连,从库无法追平。
典型误用场景:想让从库少同步点数据,就在主库加
binlog-ignore-db=test,结果导致: 主从 GTID 集合不一致,
SELECT MASTER_GTID_WAIT()失效 切换主库或搭建新从库时,缺失的 binlog 无法补全
mysqlbinlog --database=test解析不到任何事件,调试困难
结论:复制过滤逻辑必须放在从库侧,主库应保留完整 binlog。
GTID 模式下过滤的兼容性陷阱
GTID 要求事务在所有节点上「完全一致地执行或跳过」,而过滤规则是单边从库行为。MySQL 5.7+ 允许在 GTID 环境下使用
replicate-*参数,但存在两个关键限制:
replicate-ignore-table类规则在 GTID 下仍可用,但
replicate-do-db在
ROW格式中几乎无效,慎用 跳过的事务仍会占用 GTID,从库
gtid_executed包含这些空跳 ID,但
gtid_purged不包含——这会导致
RESET MASTER后无法再挂新从库 若用
mysqldump --set-gtid-purged=ON导出带过滤的从库,生成的
SET @@GLOBAL.GTID_PURGED可能漏掉被跳过的 GTID,恢复后主从 GTID 集合错位
真正安全的选择是:GTID 环境下优先用
replicate-wild-do-table,避免库级参数,且不要在生产从库上随意
RESET MASTER或
CHANGE MASTER TO ... GTID_SET。
