replicate-do-db在row格式下不生效,因其依赖use上下文而行格式日志无此信息;推荐改用replicate-wild-do-table按库表全路径精确匹配,且需重启mysql生效。

replicate-do-db 在 ROW 格式下完全不生效
MySQL 的 replicate-do-db 和 replicate-ignore-db 仅在 binlog_format = STATEMENT 模式下按当前 USE 库名匹配,一旦启用 ROW(当前主流推荐格式),这些参数就彻底失效——因为行格式日志里不记录 USE 上下文,从库 SQL 线程根本无法判断“语句本意属于哪个库”。
常见错误现象:主库执行 INSERT INTO app_log.audit_log(未 USE app_log),从库启用了 replicate-do-db = app_log,结果该语句被跳过,数据丢失。
- 验证当前格式:
SELECT @@binlog_format; - 若返回
ROW,replicate-do-db配置形同虚设,必须改用表级规则 - DDL 语句(如
CREATE TABLE)始终以 STATEMENT 格式写入 binlog,即使全局是 ROW,所以库级过滤对 DDL 仍可能意外触发,但不可靠
replicate-wild-do-table 的匹配逻辑很严格
replicate-wild-do-table 是目前最可靠的过滤方式,但它不是“模糊搜索”,而是精确的「库名.表名」全路径匹配,通配符 % 和 _ 只作用于表名部分,库名不能含通配符。
例如配置 replicate-wild-do-table = user_service.user_%,它能匹配 user_service.user_profile,但不会匹配 order_service.user_log,哪怕表名也以 user_ 开头。
- 库名含下划线时必须转义:
app\_db.%,否则app_db.%中的_被当作通配符处理 - 大小写敏感:若主库
lower_case_table_names = 0,从库也必须设为0,否则MyDB.t1不会匹配mydb.t1 - 多规则按顺序匹配,第一条命中即执行,后续规则不再检查
所有复制过滤参数都不能热加载
replicate-* 类参数全部属于 mysqld 启动时加载的静态配置,写进 my.cnf 的 [mysqld] 段后,必须重启 MySQL 进程才生效。运行时 SET GLOBAL 对它们无效,且 MySQL 不报错,容易误判已生效。
典型错误操作:SET GLOBAL replicate_do_db = 'app'; → 报错 Unknown system variable 'replicate_do_db';或执行 CHANGE REPLICATION FILTER → 仅影响新建通道,旧 SQL 线程仍用旧规则。
- 正确流程:停复制 → 修改
my.cnf→systemctl restart mysqld→START SLAVE; - 验证是否加载:
SHOW VARIABLES LIKE 'replicate%';(注意这只是配置值,不代表运行时行为) - MySQL 8.0.23+ 可查
performance_schema.replication_applier_filters获取实际生效的过滤器
跨库操作和无 USE 语句是最大陷阱
业务代码中大量存在不带库前缀的 SQL(如直接 UPDATE users SET ...)或跨库操作(如 UPDATE db1.t1 JOIN db2.t2),这两种场景会让所有基于库名的过滤(replicate-do-db、replicate-ignore-db)完全失效,甚至引发数据不一致。
更隐蔽的是:没有 USE 且没写库名前缀的语句,在 MySQL 内部被视为「无默认数据库」,此时 replicate-do-db 规则一律不匹配,整条语句被跳过——看起来复制正常,实则漏数据。
- 不要依赖应用层保证
USE,它极易被 ORM 或连接池忽略 - DDL 必须显式
USE才可能被库级规则捕获,但风险极高,应统一用replicate-wild-do-table+ 显式库表名 - 上线前务必用真实业务语句测试:停 SQL_THREAD 后手动执行几条典型跨库/无前缀语句,观察
Exec_Master_Log_Pos是否推进











