replicate-do-db 和 replicate-ignore-db 基于 USE 语句上下文匹配,非数据库级开关;跨库写入或无 USE 时失效,ROW 格式下行为不一致;推荐用 replicate-wild-do-table 按表名通配过滤。

replicate-do-db 和 replicate-ignore-db 的行为陷阱
这两个参数不是“数据库级开关”,而是基于 USE 语句的上下文匹配。如果 SQL 没有显式执行 USE db_name,或者跨库写入(如 INSERT INTO other_db.t1 SELECT * FROM main_db.t2),replicate-do-db 就会失效——从库直接跳过整条语句,哪怕目标表在白名单里。
常见错误现象:SHOW SLAVE STATUS\G 显示 Seconds_Behind_Master: 0,但数据明显缺失;或主库写 main_db,从库却同步了 log_db 的日志表。
- 只对基于语句的复制(
binlog_format = STATEMENT)严格生效;在ROW格式下,MySQL 5.7+ 会尝试按实际修改的表判断,但仍有兼容性风险 - 多个库需重复配置,不能用逗号分隔:
replicate-do-db = db1和replicate-do-db = db2才有效 - 忽略规则(
replicate-ignore-db)优先级高于白名单,冲突时以 ignore 为准
真正可靠的过滤方式:replicate-wild-do-table
用通配符按表名过滤,绕过 USE 依赖,是生产环境更可控的选择。例如只同步 user_db 下的用户表,忽略日志和临时表:
replicate-wild-do-table = user_db.users replicate-wild-do-table = user_db.profiles replicate-wild-ignore-table = user_db.log_%
注意:replicate-wild-do-table 是“必须匹配任一规则才执行”,而 replicate-wild-ignore-table 是“匹配即跳过”,两者可共存,ignore 仍具更高优先级。
- 通配符仅支持
%(任意字符)和_(单字符),不支持正则 - 表名匹配区分大小写,取决于文件系统和
lower_case_table_names设置 - DDL 语句(如
CREATE TABLE user_db.cache_2024)也会被匹配,需确认是否符合预期
过滤规则生效时机与验证方法
所有 replicate-* 参数必须在从库启动前写入配置文件(my.cnf),或通过 SET GLOBAL 动态设置后执行 STOP SLAVE; START SLAVE; 才会重新加载。单纯 SET GLOBAL 不触发规则重载。
安装、修复、更新或打包一个基于 Python 和 PyMySQL 实现的 Windows `mysql` 命令。适用于用户希望在 PowerShell/CMD 中输入 `mysql` 时重定向到 Python 实现、需要交互式输入 MySQL 连接信息、需要同步到当前用户本地 bin 目录,或需要将该能力封装成可公开复用的 Codex skill。
验证是否生效,不要只看 Seconds_Behind_Master,应检查:
-
SHOW SLAVE STATUS\G中的Replicate_Do_DB、Replicate_Ignore_DB字段是否显示预期值 - 开启从库的
log_slave_updates = OFF(默认),避免过滤后的事件又被写入从库 binlog 导致二次传播 - 用
mysqlbinlog解析主库 binlog,确认待过滤语句确实存在;再查从库 relay log(SHOW SLAVE STATUS的Relay_Log_File)是否包含该事件
替代方案:用 GTID + 应用层过滤或专用同步工具
当过滤逻辑复杂(比如按字段值、时间范围、或需转换结构),硬编码在 MySQL 配置里会越来越难维护。这时该考虑:
- 停用原生复制,在应用层双写,或用 Canal/Maxwell 抽取 binlog 后做自定义路由和过滤
- 启用 GTID(
gtid_mode = ON)后,可用CHANGE MASTER TO ... IGNORE_SERVER_IDS配合中间节点实现链式过滤,但拓扑变复杂 - Docker 或 Kubernetes 环境下,用
gh-ost或pt-online-schema-change做变更时,要特别注意它们生成的临时表是否被过滤规则误伤
最易被忽略的一点:从库的 sql_log_bin = OFF 会影响所有写入是否记入 binlog,但它不改变复制过滤行为本身——过滤只发生在 SQL thread 解析 relay log 阶段,和当前会话是否记 binlog 无关。










