必须先让从库拥有和主库完全一致的初始数据快照,否则START SLAVE后必然出现主键冲突、数据错乱或复制中断;因为CHANGE MASTER TO仅指定binlog起始位置,不负责数据初始化,空库或脏数据会导致INSERT重复、UPDATE/DELETE找不到行而报错1062或1032。

必须先让从库拥有和主库完全一致的初始数据快照,否则 START SLAVE 后必然出现主键冲突、数据错乱或复制中断。
为什么不能直接 CHANGE MASTER TO 就启动复制?
因为 CHANGE MASTER TO 只告诉从库“从哪个 binlog 文件和位置开始拉日志”,它不负责初始化数据。如果从库是空的,或者已有脏数据,主库后续的 INSERT 会因主键重复失败;UPDATE 或 DELETE 则可能找不到对应行,SQL 线程直接报错停止。
常见错误现象包括:
-
Last_SQL_Errno: 1062(主键冲突) -
Last_SQL_Errno: 1032(找不到要更新/删除的行) -
Seconds_Behind_Master: NULL且Slave_SQL_Running: No
用 mysqldump 做一致性快照的实操要点
这是中小规模(50GB 以内)、业务可短暂停写时最稳妥的方式。关键不是“导出”,而是“导出时锁定哪部分、怎么记录位置”。
- 必须加
--single-transaction:对 InnoDB 表开启一致性快照,避免锁表太久;但对 MyISAM 无效,需换方案 - 必须加
--master-data=2:导出 SQL 时自动在注释里写入CHANGE MASTER TO所需的MASTER_LOG_FILE和MASTER_LOG_POS,位置精确到事务提交点 - 务必带上
--triggers --routines --events:否则存储过程、事件等对象不会被复制,从库功能缺失 - 导入从库前,先执行
SET sql_log_bin = 0;,防止导入语句被写进从库 binlog 形成环路
大库或不能停写时,用 FLUSH TABLES WITH READ LOCK 要小心
这个命令会阻塞所有写操作,直到你显式 UNLOCK TABLES。线上系统慎用,尤其有长事务时,可能卡住整个业务。
- 执行顺序必须是:
FLUSH TABLES WITH READ LOCK;→SHOW MASTER STATUS;→ 立即记下File和Position→ 再 开始mysqldump或物理拷贝 - 锁住期间不能断开 MySQL 连接,否则自动释放锁,位置就失效了
- 从库导入后,
CHANGE MASTER TO的MASTER_LOG_FILE和MASTER_LOG_POS必须严格等于SHOW MASTER STATUS输出值 - 解锁前,确认从库已成功导入且未报错,再执行
UNLOCK TABLES;
物理备份(如 xtrabackup)适合什么场景?
当数据库超过 100GB、无法接受分钟级锁表、或要求 RPO ≈ 0 时,物理备份是更优解。但它依赖额外工具,且恢复后必须手动指定起始位点。
-
xtrabackup备份时会自动生成xtrabackup_binlog_info,里面就是精确的binlog文件名和位置 - 恢复到从库后,不能直接
START SLAVE,必须先用该文件里的值执行CHANGE MASTER TO - 注意:8.0+ 的加密表空间、原子 DDL 等特性可能要求
xtrabackup版本 ≥ 8.0.30,低版本会跳过部分元数据
最容易被忽略的是:无论用哪种方式初始化,server-id 在从库配置文件中必须与主库不同,且全集群唯一;否则 IO 线程能连上,但 SQL 线程会拒绝执行任何事件——这个错误不会报错,只会静默停滞,SHOW SLAVE STATUS 里 Seconds_Behind_Master 永远为 0,但数据早已不同步。


















