mysql如何配置复制过滤器_数据过滤与选择性同步

3次阅读

mysql复制中库级过滤应避免replicate-do-db/replicate-ignore-db,因其在row格式下失效;推荐用replicate-wild-do-table实现库表全路径匹配,gtid环境下更需谨慎,禁用reset master以防gtid错位。

mysql如何配置复制过滤器_数据过滤与选择性同步

MySQL复制中如何用 replicate-do-dbreplicate-ignore-db 控制库级过滤

这两个参数只在 STATEMENT 格式复制下按「当前数据库」生效,ROW 格式下基本失效——因为行格式不记录 USE db_name,从库无法判断语句本意操作的是哪个库。

常见错误现象:INSERT INTO other_db.t1 ... 在主库执行时没切换库,但目标表在 other_db,从库却因 replicate-do-db=mydb 被跳过,数据丢失。

  • 仅当所有 DML 都显式 USE mydb 且不跨库操作时,replicate-do-db 才可靠
  • 避免混用 STATEMENTROW 格式;若必须做库级过滤,统一用 ROW + 表级规则更稳妥
  • 多个库需过滤时,每项单独写一行配置,不能用逗号分隔

replicate-wild-do-table 实现模糊表名匹配

这是最常用也相对可靠的过滤方式,支持通配符 %_,对 STATEMENTROW 均有效,且基于实际修改的表名匹配,不依赖当前库上下文。

例如只同步 user_service 库下以 user_ 开头的表:

replicate-wild-do-table = user_service.user_%

注意点:

  • 通配符只作用于表名部分,库名不能含 %(即不支持 %.t1
  • 如果主库有 user_service.user_profileorder_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-dbROW 格式中几乎无效,慎用
  • 跳过的事务仍会占用 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 MASTERCHANGE MASTER TO ... GTID_SET

text=ZqhQzanResources