replicate_do_db易出错,因其仅依赖USE上下文而非SQL实际操作对象;推荐用replicate_wild_do_table=db1.%等表级通配规则,并确保binlog_format=ROW。

直接在从库配置 replicate_do_db 或 replicate_ignore_db 是最常用做法,但必须清楚:它们只按当前会话的 USE 数据库判断,不看 SQL 实际操作对象 —— 这是导致同步中断的头号隐患。
为什么 replicate_do_db 容易出错
MySQL 不解析 SQL 语句本身,而是依赖客户端执行 USE db_name 后的上下文来匹配过滤规则。比如你在主库上先 USE work,再执行 DROP USER 'guest'@'localhost',即使该操作只影响 mysql 系统库,MySQL 仍会认为它属于 work 库,并尝试同步到从库 —— 而从库上很可能没有这个用户,直接报错中断复制。
这类问题在运维操作(如账号管理、系统表清理)中高频出现,且难以复现。
-
replicate_do_db和replicate_ignore_db优先级低于表级规则,但逻辑脆弱 - 多个库用逗号分隔时,不能有空格:
replicate_do_db=db1,db2✅,replicate_do_db=db1, db2❌ - 它们对跨库语句(如
INSERT INTO db2.t SELECT * FROM db1.t)完全失效
更可靠的做法:用 replicate_wild_do_table 按库+通配符过滤
真正稳定的方式是绕过库级判断,直接锁定表名模式。例如只同步 db1 下所有表,就写:
replicate_wild_do_table = db1.%
这条规则会匹配任何以 db1. 开头的表名(如 db1.table_01、db1.log_01),无论执行时是否 USE db1。
- 支持通配符:
db1.table_%只同步db1中表名以table_开头的表 - 可叠加多条:
replicate_wild_do_table = db1.%+replicate_wild_do_table = db2.test_01 - 若要忽略系统库,务必加:
replicate_wild_ignore_table = mysql.%、replicate_wild_ignore_table = performance_schema.% - 修改后需重启 MySQL 或执行
STOP SLAVE; START SLAVE;生效
ROW 格式二进制日志是前提
replicate_wild_do_table 等表级过滤器仅在 binlog_format=ROW 模式下可靠工作。如果主库用的是 STATEMENT 或 MIXED,部分跨库 DML(如 UPDATE db2.t SET x=1 WHERE id IN (SELECT id FROM db1.t))可能被错误放行或拦截。
- 检查主库格式:
SELECT @@binlog_format;,不是ROW就得改 - 修改主库配置:
binlog_format=ROW,然后重启或动态设置(需 SUPER 权限) - 注意:
ROW日志体积更大,但这是精准过滤的必要代价
真正麻烦的不是配置几行参数,而是跨库操作和 binlog 格式这两点容易被忽略 —— 一旦出错,Last_SQL_Error 里往往只显示一条失败语句,根本看不出是过滤逻辑误判导致的。所以线上环境务必提前用 replicate_wild_ignore_table 把 mysql、information_schema 这类系统库兜住。


















