主库必须开启binlog并设唯一server-id,否则复制失败;常见错误包括未重启MySQL、server-id重复或配置位置错误;实操需验证log_bin和server_id变量值,确保IO/SQL线程正常运行。

主库必须开启 binlog 且设对 server-id
没开 log_bin,从库连日志都拉不到,复制直接失败。常见错误是只改了 my.cnf 但没重启 MySQL,或者配置写错位置(比如写在 [client] 段里)。server-id 必须是整数、全局唯一,主从不能重复——哪怕只是临时测试,也别用默认的 1,否则后续加新从库会冲突。
实操建议:
-
log_bin路径不强制指定文件名,用log_bin = mysql-bin即可,MySQL 会自动生成mysql-bin.000001等序列文件 -
server-id推荐用 IP 最后一段,比如主库 IP 是192.168.1.100,就设server-id = 100 - 必须关闭
read_only = 0(主库要写),但别在从库配这个,否则从库可能意外写入导致数据不一致 - 加
binlog_format = ROW,避免触发器、函数、时间戳等导致的复制错乱
从库要启用 relay log 并禁用 auto-increment 冲突
从库不写 log_bin 也能同步,但若要做级联复制(比如 A→B→C),就得开 log_slave_updates = 1。更关键的是 relay-log——它不是可选参数,MySQL 启动时会自动创建,但显式声明路径能避免日志散落在 datadir 下难排查。
实操建议:
- 明确写
relay-log = relay-bin,让中继日志统一前缀,便于监控和清理 - 必须设
server-id(如101),且与主库和其他从库不重复 - 加上
auto_increment_offset和auto_increment_increment(尤其在双主或未来可能升主时),例如双主场景下主库设auto_increment_increment = 2、auto_increment_offset = 1,从库设offset = 2,防止 INSERT 自增 ID 冲突 - 从库默认应开启
read_only = 1,防误操作;但注意它不影响复制线程执行 SQL,只拦普通用户
binlog_do_db 和 binlog_ignore_db 的坑比想象中多
这两个参数看似方便,实际极易出错。MySQL 不是按“当前 USE 的库”来过滤,而是看 SQL 语句里是否显式写了库名。比如 INSERT INTO test.t1 会被记录,但 USE test; INSERT INTO t1 可能被跳过——取决于 binlog_format 和上下文。
实操建议:
- 生产环境尽量不用
binlog_do_db,改用replicate_do_db(从库端过滤),更可控 - 如果非要用,确保所有 DML 都带库名前缀,否则同步会漏数据
-
binlog_ignore_db对CREATE DATABASE无效,它只过滤 DML 和部分 DDL,想彻底屏蔽某库,得在从库用replicate_ignore_db - 多个库要过滤时,每行写一个,不能用逗号分隔:
binlog_ignore_db = information_schemabinlog_ignore_db = performance_schema
配置完别忘了验证参数是否生效
改完 my.cnf 重启 MySQL 后,光看配置文件不等于生效。常见疏漏是 mysqld 实际加载的不是你编辑的那个文件,或者 systemd 用了 override 配置覆盖了原设置。
实操建议:
- 登录 MySQL 执行
SHOW VARIABLES LIKE 'log_bin';,确认值为ON - 查
SHOW VARIABLES LIKE 'server_id';和SHOW VARIABLES LIKE 'relay_log';,核对数值和路径 - 运行
SHOW MASTER STATUS;(主库)或SHOW SLAVE STATUS\G(从库),看关键字段:主库的File和Position是否非空;从库的Slave_IO_Running和Slave_SQL_Running是否都为Yes - 如果
IO_Running是Connecting,大概率是网络不通、账号密码错、或主库没开skip_networking
真正容易被忽略的,是主从时间不同步导致 GTID 模式下复制中断,以及 SELinux 或 firewalld 拦截了 3306 端口——这两点不报错,但复制永远卡在初始化阶段。


















