replicate-do-db仅匹配USE后的语句,跨库操作失效;其非数据库级开关,而是依赖当前会话的USE上下文,且GTID模式下必须重启生效,不可动态修改。

replicate-do-db 只匹配 USE 后的语句,跨库操作会失效
这个参数不是“只要 SQL 操作了指定库就同步”,而是看当前 session 是否执行过 USE db_name。比如你在 USE app_db 下执行 INSERT INTO log_db.audit_log VALUES (...),这条语句仍会被复制——因为“当前库”是 app_db,而 log_db 不在 replicate-do-db 列表里,规则压根没触发。
常见错误现象:
- 从库上发现本该被过滤的库(如
tmp_db、monitoring)仍有数据写入 -
SHOW SLAVE STATUS\G显示Replicate_Do_DB: app_db,但log_db的变更仍在同步
根本原因:应用代码或 ORM 常用显式库名语法(db1.table1),绕过了 USE 依赖逻辑。
replicate-do-db 和 replicate-wild-do-table 混用时优先级混乱
如果配置里同时存在 replicate-do-db = app_db 和 replicate-wild-do-table = app_db.users,MySQL 会按“更精确的规则优先”处理,即后者生效;但一旦你加了 replicate-ignore-db = tmp_db,行为就不可预测——replicate-ignore-db 是黑名单,replicate-do-db 是白名单,两者逻辑冲突,MySQL 不保证执行顺序。
实操建议:
- 彻底弃用
replicate-ignore-db,它在 MySQL 8.0.26+ 已被标记为deprecated - 只保留一组白名单规则:
replicate-wild-do-table(推荐)或replicate-do-table - 若必须按库控制,确保所有 DML 都在
USE后执行,并禁用跨库语法(如禁止INSERT INTO other_db.t)
GTID 模式下修改 replicate-do-db 必须重启从库,不能动态生效
开启 gtid_mode=ON 后,MySQL 要求所有复制过滤参数(包括 replicate-do-db)必须在从库首次启动复制前就写进配置文件。运行中执行 SET GLOBAL replicate_do_db = 'app_db' 会报错:Variable 'replicate_do_db' is a read only variable。
这意味着:
- 不能靠
STOP SLAVE; SET GLOBAL ...; START SLAVE;热更新规则 - 改完
my.cnf后必须完整重启 MySQL 进程 - 重启后需检查
SHOW VARIABLES LIKE 'replicate%'确认加载成功,再START SLAVE
容易被忽略的一点:GTID 环境下,即使你只改了一行 replicate-wild-do-table,也必须重启——没有例外。
mysqldump 初始化时漏掉 --ignore-table,会导致从库残留垃圾数据
用 mysqldump --all-databases 初始化从库时,如果没加 --ignore-table,系统库(mysql、sys)、监控库(percona)、临时库(tmp_db.%)的结构和数据全都会倒进去。后续主从复制可能因权限表冲突、触发器缺失或字段类型不一致卡在 SQL thread stopped。
正确做法:
- 导出时显式过滤:
mysqldump --all-databases --ignore-table=mysql.proxies_priv --ignore-table=tmp_db.% -u root -p > init.sql - 通配符只支持表名位置:
tmp_db.%合法,%.users非法 - 导出后 grep 验证:
grep -n "CREATE TABLE.*tmp_db" init.sql,确认无残留
最麻烦的是:这些残留数据不会立刻报错,而是在某次主库执行 DROP DATABASE tmp_db 或 ALTER TABLE mysql.user 时才暴露——那时同步已中断数小时,排查成本陡增。


















