MySQL异地灾备恢复必须明确RTO与RPO,不能仅依赖CHANGE REPLICATION SOURCE TO切主;需校验GTID一致性、禁用relay_log_purge、解析relay log补全事务,并安全重置复制拓扑。

MySQL异地灾备的恢复方案不能只盯着“能恢复”,而要明确 RTO(秒级还是分钟级)和 RPO(是否允许丢事务)。跨地域场景下,单纯靠 CHANGE REPLICATION SOURCE TO + 从库提升为主库,大概率在真实故障时失败——因为网络抖动、GTID不一致、binlog缺失、权限错配等问题会集中爆发。
恢复前必须验证 GTID 一致性
异地主从复制一旦跨公网或长距离专线,Seconds_Behind_Master 经常失真(比如卡在 Retrieved_Gtid_Set 和 Executed_Gtid_Set 不匹配),此时直接 STOP SLAVE; RESET SLAVE ALL; 再切主,极可能跳过未执行的事务。
- 必须用
SELECT * FROM performance_schema.replication_applier_status_by_coordinator;查看实际已应用的 GTID 范围 - 对比主库
SELECT @@GLOBAL.GTID_EXECUTED;和从库SELECT * FROM mysql.gtid_executed;,确认差集为空 - 若存在 gap,优先用
mysqlbinlog --base64-output=DECODE-ROWS -v解析缺失 binlog 并手工回放,而不是强行跳过
切换时禁用自动清空 relay log 的行为
默认 STOP SLAVE 会触发 relay log 清理,但异地灾备中 relay log 往往是唯一可用的“最后几秒”数据载体。尤其当主库已不可达、从库 IO_THREAD 停止但 SQL_THREAD 还在追平时,relay log 里可能存着尚未应用的关键事务。
- 切换前执行
SET GLOBAL relay_log_purge = OFF;,防止 relay log 被自动删除 - 检查
SHOW SLAVE STATUS\G中的Relay_Log_File和Relay_Log_Pos,记录当前位点 - 如需人工干预,用
mysqlbinlog relay-log-file | mysql -u root -p补全剩余事务
从库提升为主库后,必须重置复制拓扑
原主库恢复后若直接加回集群,大概率因自增 ID 冲突、GTID 重复或 binlog 位置错乱导致同步中断。这不是“能不能加”,而是“怎么安全加”。
- 新主库上执行
RESET MASTER;(仅限确定原主库永久下线)或SET GLOBAL GTID_PURGED = 'xxx';(保留原主库已执行的 GTID 集合) - 原主库恢复后,不能用旧
CHANGE REPLICATION SOURCE TO指令,必须先RESET SLAVE ALL;,再用新主库的SHOW MASTER STATUS输出重新配置 - 若使用
auto_increment_increment/auto_increment_offset做多活避让,切换后需确认新主库的 offset 值与原架构一致,否则写入会撞主键
真正难的不是命令怎么写,而是每次切换前能否快速判断:当前从库的 relay log 是否完整、GTID 是否可对齐、业务表是否有未提交的 XA 事务残留。这些细节不提前压测并固化检查清单,灾备恢复就会变成一场高风险的手工抢救。


















