停机时间可压至5分钟内,需弃用mysqldump全量导出与自然主从追平,改用gtid+增量补偿+流量灰度协同推进;须规避跨机房网络延迟硬伤,调优tcp层、校验gtid状态、实施双写校验与分批灰度切流。

停机时间能压到 5 分钟以内,前提是别用 mysqldump 直接导全库,也别等主从同步“自然追平”再切——跨机房迁移必须绕过网络延迟这个硬伤,用 GTID + 增量补偿 + 流量灰度三者咬合推进。
为什么 mysqldump 在跨机房场景下必然超时
200GB 数据用默认单线程 mysqldump,导出+传输+导入轻松破 10 小时;即使上 mydumper -t 8,在 RTT 40ms、带宽受限的跨机房链路上,TCP 重传和 Nagle 算法会让实际吞吐跌到理论值的 30%。更关键的是:mysqldump 期间业务写入完全停滞,一导完立刻面临“旧库最后 5 分钟写入怎么补”的问题——这不是优化能解决的,是方法论错位。
- 必须放弃“全量 dump → 停写 → 导入 → 切流”这种离线范式
-
max_allowed_packet和wait_timeout调得再大,也救不了设计层面的停机刚性 - 云厂商 VPC 间或 IDC 跨城专线,真实丢包率常达 0.1%~0.5%,
mysqldump的每个 packet 都可能触发秒级卡顿
GTID 主从复制不是开个参数就自动跑通
直接执行 SET GLOBAL gtid_mode = ON 会报错 ERROR 1789,且业务 SQL 可能因 ENFORCE_GTID_CONSISTENCY = ON 突然失败(比如含 CREATE TEMPORARY TABLE 的存储过程)。GTID 是必要条件,但不是充分条件。
- 先设
enforce_gtid_consistency = WARN,盯/data/mysql/error.log3 天,确认无GTID consistency violation日志 - 按顺序执行四步切换:
OFF → OFF_PERMISSIVE → ON_PERMISSIVE → ON,中间必须等ONGOING_ANONYMOUS_TRANSACTION_COUNT = 0 - 从库必须开启
log_slave_updates = 1和binlog_format = ROW,否则 GTID 链路断裂,级联复制失效 -
CHANGE MASTER TO MASTER_AUTO_POSITION = 1后,要验证Retrieved_Gtid_Set和Executed_Gtid_Set是否持续收敛,而非只看Seconds_Behind_Master
网络层不调优,复制延迟永远卡在 300 秒以上
跨机房复制卡顿,80% 源于 TCP 层,而非 MySQL 配置。单纯加 slave_parallel_workers 只会让 IO 线程更饿——它等不到数据,worker 再多也空转。
- 从库配置
slave_compressed_protocol = 1(MySQL 5.7.9+),实测降低 40% 传输负载,无需主库改动 - 主从双方都执行:
sysctl -w net.ipv4.tcp_nodelay = 1(禁 Nagle)、sysctl -w net.ipv4.tcp_congestion_control = bbr(提升高延迟链路带宽利用率) - 用
iperf -c 主库IP -t 60测真实吞吐,若远低于主库binlog写入速率(如主库每秒写 6MB,iperf 只跑出 2MB),说明带宽已打满,需扩容或压缩 - 避免
binlog_format = STATEMENT:跨机房下RAND()、NOW()等非确定函数会导致主从数据不一致
真正控制停机在 5 分钟内,靠的是流量灰度而非技术完美
GTID 复制追平后,仍有最后 10 秒左右的事务间隙。这时候不能靠“等待”,而要用应用层双写+校验+切流来兜底。技术再稳,网络抖动和时钟漂移也会制造那几条漏掉的数据。
- 提前上线双写逻辑:新旧库同时写,写新库走异步重试队列,失败进本地事务表记录
- 切流前运行一次全量比对(用
pt-table-checksum或自研校验),重点扫最近 2 小时变更 - 读流量先灰度 5%,观察错误率和延迟;确认无异常后,10 分钟内分三批切完读,最后 3 分钟切写
- 旧库保留 72 小时只读,DNS 缓存 TTL 设为 60 秒,确保回滚可秒级生效
最易被忽略的是:GTID 切换完成 ≠ 复制稳定,Seconds_Behind_Master = 0 也不代表数据已落盘——必须查 Exec_Master_Log_Pos 是否等于主库当前 File/Position,且 Slave_SQL_Running_State 是 Slave has read all relay log。这个状态差,才是那几分钟停机真正的边界。











