主从复制中断且主库binlog被PURGE时必须重建从库;验证binlog确已丢失后,用mysqldump加--master-data=2和--single-transaction等关键参数备份,导入后根据实时主库位点或GTID配置复制,并检查server-id、read_only及数据一致性。

主从复制中断后,只要主库 binlog 已被 PURGE 或从库报 Could not find first log file name,就必须重建从库——修不如建,跳错、重设 position、手动补日志全是徒劳。
确认 binlog 确实不可用,再动手
别一看到 SHOW SLAVE STATUS\G 里 Slave_SQL_Running: No 就 rush 进去 dump。先验证 binlog 是否真丢了:
- 在主库执行
SHOW BINARY LOGS;,比对最老的Log_name是否早于从库Relay_Master_Log_File(来自SHOW SLAVE STATUS\G);如果已不存在,就是真丢了 - 查主库配置:
SELECT @@expire_logs_days, @@binlog_expire_logs_seconds;,结合中断时间判断是否被自动清理 - 翻
mysqld错误日志,搜Could not open log file,排除路径或权限问题 - 如果是 GTID 模式,执行
SELECT MASTER_POS_WAIT('nonexistent-bin.000001', 0, 1);,若返回NULL或超时,说明日志不可达
用 mysqldump 做一致性备份,参数不能少
mysqldump 是中小规模库最稳妥的选择,但漏掉关键参数会导致后续 CHANGE MASTER TO 失败或数据不一致:
- 必须加
--master-data=2:把CHANGE MASTER TO语句作为注释写进 dump 文件,含当前MASTER_LOG_FILE和MASTER_LOG_POS - 必须加
--single-transaction:对 InnoDB 表做一致性快照,避免锁表;但对 MyISAM 无效,若库中混有 MyISAM 表,需改用--lock-all-tables - 不要加
--skip-lock-tables:它会让--master-data记录的位置和实际数据状态错位 - 推荐加上
--routines --triggers --events,否则存储过程、触发器、事件不会导出 - 命令示例:
mysqldump -u root -p --all-databases --master-data=2 --single-transaction --routines --triggers --events > full.sql
导入后配置复制,别直接抄 dump 里的 CHANGE MASTER
dump 文件里 -- CHANGE MASTER TO ... 注释行只对“dump 时刻的主库”有效。主库可能已在你传输、导入期间持续写入,所以不能无脑执行那行:
- 导入前,在主库立刻执行
FLUSH TABLES WITH READ LOCK;,再SHOW MASTER STATUS;,记下实时File和Position - 导入完成后,在从库执行
STOP SLAVE;,然后CHANGE MASTER TO MASTER_HOST='xxx', MASTER_USER='repl', MASTER_PASSWORD='xxx', MASTER_LOG_FILE='mysql-bin.0000xx', MASTER_LOG_POS=123456789;—— 这里的文件名和位置必须是你刚在主库上拿到的 - 如果是 GTID 模式,跳过
MASTER_LOG_FILE/POS,改用:RESET SLAVE;→SET GLOBAL gtid_purged = 'xxx';(值来自主库SELECT @@gtid_executed;)→CHANGE MASTER TO MASTER_HOST='xxx', MASTER_AUTO_POSITION = 1; - 最后
START SLAVE;,立刻检查SHOW SLAVE STATUS\G中Slave_IO_Running和Slave_SQL_Running是否都为Yes
重建后最容易被忽略的三件事
重建完成不代表万事大吉,这三个点没处理好,从库可能几分钟后又挂:
-
server_id必须唯一:检查从库my.cnf里server-id是否与主库及其他从库冲突,重复会导致IO thread启动即失败 - 从库必须设为只读:
SET GLOBAL read_only = ON;,并写入配置文件,否则误写会引发主从数据分裂 - 验证不是只看
Seconds_Behind_Master = 0,要跑CHECKSUM TABLE或用pt-table-checksum对关键表做校验,特别是datetime字段或带默认值的列,容易因时区或 SQL mode 不一致导致隐性差异


















