异地灾备必须依赖主从复制(change replication source to)实现rpo保障,辅以mysqldump+rsync归档兜底rto;严禁直接rsync /var/lib/mysql,因innodb活跃状态下文件不一致会导致恢复失败。

异地灾备必须用主从复制,不能只靠 rsync 备份文件
rsync 直接同步 /var/lib/mysql/ 目录在生产环境几乎必然失败——InnoDB 表空间处于活跃状态时,文件内容不一致,恢复后大概率报错 Tablespace is missing for table 或 MySQL 启动失败。只有 MySQL 完全停止时才可能成功,但业务无法接受停机。
真正可用的异地灾备必须依赖 CHANGE REPLICATION SOURCE TO 构建主从链路,辅以 binlog 实时同步或定期逻辑备份归档。主从解决 RPO(恢复点目标)问题,mysqldump + rsync 解决 RTO(恢复时间目标)兜底和误操作回滚能力。
- 中小库(mysqldump --single-transaction --routines --triggers --databases db1 db2 生成一致性逻辑备份
- 大库优先用
mysqlpump(原生并行)或mydumper(需安装),避免单线程卡死 - 备份前加
FLUSH LOGS(可选),便于后续 binlog 恢复定位起点
跨云主从配置必须补全心跳、重试、超时三参数
混合云环境(如阿里云杭州主库 → 腾讯云北京从库)走公网或跨厂商专线时,CHANGE REPLICATION SOURCE TO 默认配置扛不住偶发丢包或 NAT 超时。IO 线程中断后 Seconds_Behind_Master 骤升甚至卡死,且不会自动恢复。
必须显式设置以下三项:
-
MASTER_HEARTBEAT_PERIOD = 30.0:强制主库每 30 秒发一次心跳,比默认 0(禁用心跳)更早发现链路异常 -
MASTER_RETRY_COUNT = 86400:避免一次连接失败就停掉 SQL 线程,给足一天重试窗口 -
slave_net_timeout = 60:把 IO 线程等待响应上限从默认 3600 秒砍到 60 秒,“快断快重连”,不傻等一小时
注意:auto-reconnect 已被 MySQL 官方弃用,且对复制线程完全无效,绝对不要依赖。
GTID 模式下 server_id 和时区必须人工核对
混合云里主从常分属不同云平台,初始化时极易忽略基础配置一致性。一旦 server_id 冲突或系统时间偏差 >1 秒,GTID 复制会直接报错中断,且错误信息不直观(比如 Could not parse relay log event entry 往往是时区/格式问题引发的连锁反应)。
- 执行
SELECT @@server_id确保主从值唯一,不能都为 1 或都为空 - 用
SELECT UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(UTC_TIMESTAMP())核查主从本地时间与 UTC 偏差,>1 秒必须同步 NTP(尤其注意腾讯云 CVM 默认关 NTP) - 确认
gtid_mode=ON且enforce_gtid_consistency=ON在主从两端都生效,缺一不可 -
binlog_format必须为ROW,语句级日志在跨云网络抖动下极易导致主从数据不一致
恢复演练必须验证导入可行性,不能只看 rsync 成功
很多团队把 rsync 成功当成“灾备就绪”,结果真出事才发现:mysqldump 导出时用了 --set-gtid-purged=ON,但目标 MySQL 未开启 GTID;或者导出文件含 CREATE DATABASE,但目标实例已存在同名库且字符集不一致,source 报错退出。
实操要点:
- 异地接收端收到备份文件后,必须立即运行
sha256sum -c backup_*.sql.sha256,输出OK才算有效 - 在测试机上用空实例执行
mysql -u root -p ,观察是否报错、是否缺失存储过程或触发器 - 若使用 GTID,恢复前先执行
RESET MASTER和SET GLOBAL gtid_purged = 'xxx'(值来自 dump 文件头) - 演练频率建议至少每季度一次,且必须覆盖切换、回切、binlog 追加等完整路径
最容易被忽略的是:灾备从库开启 read_only=OFF 和 log_slave_updates=ON 的时机——不是灾备时开,而是日常就该开着;否则演练时才发现权限锁死、无法升主,已经晚了。











