replicate_ignore_db 在 mysql 主从复制中不可靠,仅当 use 指定库名匹配时生效,显式库名操作(如 insert into other_db.t1)完全绕过过滤;官方明确不推荐使用,生产环境易致数据不一致。

replicate_ignore_db 在 MySQL 主从复制中根本不可靠
直接说结论:replicate_ignore_db 在基于语句(SBR)或混合(MBR)格式的复制中,**仅在当前默认数据库(USE db_name)匹配时才生效**;如果 SQL 语句显式指定了库名(如 INSERT INTO other_db.t1 ...),它完全被忽略。官方文档明确标注该参数“not recommended for use”。生产环境误用会导致从库数据不一致,且问题极难排查。
为什么 replicate_ignore_db 会漏过滤
核心原因是 MySQL 复制过滤逻辑只检查「当前默认数据库」,而非语句实际操作的对象库。比如主库执行:
USE app_log; INSERT INTO analytics.users SELECT * FROM app_main.users;
此时 replicate_ignore_db = app_main 不起作用——因为当前默认库是 app_log,而语句里显式写了 app_main.users。
- 所有跨库 DML(
INSERT/UPDATE/DELETE ... FROM other_db.table)都会绕过replicate_ignore_db -
CREATE TABLE other_db.t1同样不会被过滤 - 即使设置了
replicate_ignore_db = test,只要没执行USE test,test 库的变更照常同步
真正有效的替代方案:使用 replicate_do_db 或基于表的过滤
如果必须按库隔离,优先用 replicate_do_db(白名单模式),它对显式库名语句也生效,但需注意作用域限制:
- 只对当前默认库 + 显式带库名的语句生效(比
ignore更可靠) - 多个库需重复配置:
replicate_do_db = db1、replicate_do_db = db2 - 仍无法处理跨库 JOIN 或存储过程内动态 SQL
更稳妥的做法是切换到基于表的过滤:
replicate_wild_ignore_table = 'sys.%' replicate_wild_ignore_table = 'mysql.%' replicate_wild_ignore_table = 'performance_schema.%'
replicate_wild_ignore_table 支持通配符,且对所有含库名前缀的操作都生效(如 INSERT INTO app_log.audit_log),这才是生产环境过滤系统库或日志库的实际标准做法。
配置后必须重启 IO 线程才能生效
修改 my.cnf 中的 replicate_* 参数后,不能只执行 STOP SLAVE; START SLAVE; —— 这只会重启 SQL 线程,IO 线程仍按旧规则拉取 binlog。
- 正确操作是:
STOP SLAVE IO_THREAD;→ 修改配置 →START SLAVE IO_THREAD; - 验证是否生效:
SHOW SLAVE STATUS\G查看Replicate_Ignore_DB字段值 - 检查过滤效果最直接的方式:在主库执行一条跨库语句,然后立刻查从库对应表是否没变化
真正麻烦的是那些已同步过去的脏数据——过滤规则只对未来事件有效,历史数据得手动清理或跳过事件,这点容易被忽略。











