别用replicate_do_db,它在MySQL 8.0.26+已弃用且行为反直觉;应改用replicate_wild_do_table,必须写入从库my.cnf并重启mysqld,且主库binlog_format须为ROW才生效。

replicate_do_db 在 MySQL 8.0 中根本不可靠
别用 replicate_do_db,它在 MySQL 8.0.26+ 已被标记为 deprecated,且行为反直觉:它不看 SQL 实际操作哪个库,只依赖当前会话是否执行过 USE db_name。比如你在 USE app_db 下执行 INSERT INTO log_db.audit_log VALUES (),这条语句仍会被同步——因为“当前库”是 app_db,而 log_db 不在白名单里,规则压根没触发。
常见错误现象包括:
-
SHOW SLAVE STATUS\G显示Replicate_Do_DB: app_db,但monitoring库的数据仍在写入 - ORM 或应用代码常用显式库名语法(如
INSERT INTO metrics.log_01),直接绕过USE上下文 - GTID 模式下,
SET GLOBAL replicate_do_db = 'app_db'会报错:Variable 'replicate_do_db' is a read only variable
必须用 replicate_wild_do_table + binlog_format=ROW
真正可控的过滤方式是表级通配符规则,它匹配事件中显式出现的 db_name.table_name,与 USE 无关,且仅在 binlog_format=ROW 下可靠生效。
配置示例(写入从库 /etc/my.cnf 的 [mysqld] 段):
replicate_wild_do_table = app1.%<br>replicate_wild_do_table = app2.users<br>replicate_wild_ignore_table = mysql.%<br>replicate_wild_ignore_table = performance_schema.%<br>replicate_wild_ignore_table = information_schema.%
注意细节:
- 格式必须是
db_pattern.table_pattern,中间是英文点号,不是下划线或斜杠 -
%匹配任意字符(包括空),_匹配单个字符;如需字面量下划线,写成app\_prod.% - 多个规则必须分行写,不能用逗号或空格分隔
- 修改后必须重启
mysqld进程,STOP SLAVE; START SLAVE;不生效
GTID 模式下改配置必须重启,没有例外
开启 gtid_mode=ON 后,所有复制过滤参数(包括 replicate_wild_do_table)都必须在从库首次启动复制前就写进配置文件。运行中修改配置文件后,不重启就执行 START SLAVE,MySQL 会继续使用旧规则。
验证是否加载成功:
- 重启后执行
SHOW VARIABLES LIKE 'replicate%';,确认replicate_wild_do_table值已更新 - 再执行
START SLAVE;,然后查SHOW SLAVE STATUS\G,观察Replicate_Wild_Do_Table字段是否匹配预期 - 主库执行一条跨库语句(如
INSERT INTO app1.t1 SELECT * FROM tmp.test),检查从库对应表是否同步、被忽略库是否真的没数据
最容易被忽略的两个硬性前提
就算你把 replicate_wild_do_table 写得再准,漏掉下面任一条件,过滤都会失效:
- 主库的
binlog_format不是ROW:执行SELECT @@binlog_format;,如果不是ROW,必须在主库设binlog_format=ROW并重启或动态设置(需 SUPER 权限) - 从库没重启:改完
my.cnf后只执行STOP SLAVE; START SLAVE;是无效的,必须完整重启mysqld
这两点不出问题,replicate_wild_do_table 才真正可控;一旦出问题,Last_SQL_Error 里往往只显示一条失败语句,根本看不出是过滤逻辑崩了。


















