主库必须开启binlog并设唯一server-id;从库需精准指定binlog文件名和位置启动复制;start slave后须检查io/sql线程状态及seconds_behind_master;严禁为降延迟调低innodb_flush_log_at_trx_commit。

主库必须开启 binlog 并设置唯一 server-id
MySQL 主从同步依赖 binlog 记录写操作,主库不启用就无法复制。确认 my.cnf 中包含以下配置:
-
log-bin = /var/lib/mysql/mysql-bin(路径需存在且 MySQL 有写权限) -
server-id = 1(整数,全局唯一,不能为 0) -
binlog-format = ROW(推荐,避免语句级复制在从库执行出错)
改完重启 MySQL,执行 SHOW VARIABLES LIKE 'log_bin'; 和 SHOW VARIABLES LIKE 'server_id'; 验证是否生效。常见错误是只改了配置但没重启,或 server-id 在多实例中重复。
从库执行 CHANGE MASTER TO 时要对准主库的 binlog 位置
不是随便连上就能同步,必须告诉从库从哪条日志、哪个偏移量开始读。通常流程是:
- 主库执行
FLUSH TABLES WITH READ LOCK;(短暂停写) - 执行
SHOW MASTER STATUS;,记下File和Position - 用
mysqldump --all-databases --master-data=2导出并恢复到从库(自动写入 CHANGE MASTER TO 语句) - 或手动执行:
CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=154, ...
如果位置填错,从库会报 Could not find first log file name in binary log index file 或跳过数据。注意:MASTER_LOG_POS 是整数,不是字符串,别加引号。
START SLAVE 后要立刻检查 Seconds_Behind_Master 和 IO/SQL 线程状态
启动复制只是开始,真正同步是否正常得看线程运行情况:
- 执行
SHOW SLAVE STATUS\G,重点看:Slave_IO_Running: Yes、Slave_SQL_Running: Yes -
Seconds_Behind_Master为NULL表示 SQL 线程没跑(可能卡在某个事务),为0不代表完全实时(可能是刚追上) - 若出现
ERROR 1062(主键冲突)或ERROR 1032(记录找不到),说明从库数据已偏离,不能直接SET GLOBAL sql_slave_skip_counter=1跳过——这会掩盖数据不一致问题
高可用场景下,这种错误必须人工核对主从数据差异,跳过仅用于临时应急。
主从延迟大时,不要盲目调大 innodb_flush_log_at_trx_commit
有人为“加速从库”把主库的 innodb_flush_log_at_trx_commit 改成 0 或 2,这是危险操作:
- 值为 0:事务提交后 log 可能丢失,主库 crash 会导致 binlog 和 InnoDB 数据不一致 → 从库同步失败或数据错乱
- 值为 2:虽比 0 安全,但仍有小概率丢 log,且不能解决根本延迟(延迟多因从库单线程重放慢、大事务、磁盘 I/O 差)
- 真正有效的办法是:升级 MySQL 到 5.7+ 启用
slave_parallel_workers,或拆分大事务,或用pt-heartbeat监控延迟阈值触发告警
主从架构里,主库稳定性永远优先于“看起来快一点”。一旦主库 binlog 损坏,整个复制链就断了,修复成本远高于优化几个毫秒。











