mysqldump --master-data=2 的作用是导出时自动在sql文件开头插入带注释的 change master to 语句,精确记录导出瞬间的二进制日志文件名和位置(master_log_file 和 master_log_pos),确保主从复制起始点与数据快照严格一致;它需配合 flush tables with read lock 使用以保证位置准确,且 =2 比 =1 更安全,因语句被注释,避免导入时意外执行。

可以做到,但必须用 mysqldump --master-data 配合 FLUSH TABLES WITH READ LOCK,且锁表时间要足够短——业务写入量越大,越要小心锁表窗口。
为什么不能直接 RESET MASTER 后再导出?
因为 RESET MASTER 会清空所有 binlog 并重置文件编号(如从 mysql-bin.000005 变成 mysql-bin.000001),而你导出的数据快照对应的是旧 binlog 的某个 position。如果主库在锁表前/后有新写入,又没记录准确位置,从库启动复制时就会找不到日志或跳过数据。
常见错误现象:Slave_IO_Running: No,报错 Could not find first log file name in binary log index file 或 Client requested master to start replication from position > file size。
关键点在于:导出时必须拿到「与数据完全一致」的 binlog 文件名和 position,而不是 reset 后的起始值。
mysqldump --master-data=2 是核心救命参数
这个参数会让 mysqldump 在 SQL 文件开头自动插入一条带注释的 CHANGE MASTER TO 语句,里面包含导出瞬间的 MASTER_LOG_FILE 和 MASTER_LOG_POS。导入到从库后,这条语句会被执行(只要没加 --skip-extended-insert 等干扰选项)。
使用时注意:
-
--master-data=1写的是可执行语句;=2写的是带--注释的语句,更安全(导入时不会意外执行,需手动启用) - 必须搭配
FLUSH TABLES WITH READ LOCK使用,否则 position 不准 - 不要加
--single-transaction和--master-data一起用——前者对 MyISAM 无效,且可能让 position 滞后于实际锁点 - 导出完成后,**立刻**在主库执行
UNLOCK TABLES,锁表时间应控制在秒级
从库导入后,别手动 CHANGE MASTER TO
很多人导入 all-databases.sql 后,还去查 SHOW MASTER STATUS、再手写 CHANGE MASTER TO,这是错的——此时主库的 binlog 已推进,position 完全不匹配导入快照。
正确做法是:
- 确认 dump 文件里确实有类似
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000007', MASTER_LOG_POS=123456789;的注释行 - 导入时用
mysql -u root -p ,默认会跳过注释行,不执行 - 导入完成后,在从库执行:
SOURCE /path/to/dump.sql(或把注释行去掉后单独执行那条CHANGE MASTER TO) - 或者更稳妥:导入前先
STOP SLAVE,导入后直接START SLAVE—— 因为--master-data=2的注释在导入时不生效,你得自己触发一次
漏掉这步,START SLAVE 会沿用旧的 binlog 位置,大概率报错 Could not parse relay log event entry 或直接跳过大量数据。
GTID 模式下要额外清理 gtid_purged
如果你的 MySQL 是 5.6+ 且启用了 GTID(gtid_mode=ON),光靠 --master-data 不够。因为从库导入后,gtid_executed 是空的,但主库的 gtid_purged 可能已包含大量事务,导致从库拒绝同步。
必须在从库导入完成、CHANGE MASTER TO 前执行:
SET GLOBAL gtid_purged = 'xxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:1-12345';
其中值来自主库导出时的 SHOW MASTER STATUS 输出里的 Executed_Gtid_Set 字段(不是 gtid_executed)。这个值一旦设错,从库就再也无法追上主库,而且无法回退。
最容易被忽略的地方:GTID 模式下 RESET SLAVE 不清空 gtid_purged,必须显式设置;而 RESET SLAVE ALL 才会重置它——但你不能随便用 ALL,它会删掉主库连接信息,反而增加配置负担。











