mysql跨机房同步本质是主从复制的异地延伸,需在“数据不丢”和“服务不卡”间取舍;应启用gtid+半同步、延迟从库、过滤复制,并通过proxysql或熔断机制隔离网络抖动,全程强制ssl加密。

MySQL跨机房同步本质是主从复制的异地延伸
跨机房同步不是新协议,而是把标准的MySQL主从复制部署在不同物理位置的机房之间。关键差异在于网络延迟、丢包和带宽限制会直接放大复制链路的脆弱性——Seconds_Behind_Master飙升、IO_THREAD频繁断连、Retrieval failed from network错误频发,都是典型症状。
必须接受一个现实:跨机房场景下,强一致性无法兼顾高可用。你得在“数据不丢”和“服务不卡”之间做显式取舍。
用GTID + 半同步复制降低丢数据风险
传统基于binlog position的复制在跨机房断连重连时容易错位;GTID能自动定位日志起点,避免人工计算Exec_Master_Log_Pos出错。但光靠GTID不够,还需开启rpl_semi_sync_master_enabled=ON和rpl_semi_sync_slave_enabled=ON,强制至少一个从库落盘才返回客户端成功。
-
半同步不是万能:超时时间rpl_semi_sync_master_timeout建议设为10000(10秒),太短会导致频繁退化为异步,太长则拖慢主库响应 - 从库必须配置
relay_log_recovery=ON,否则宕机重启后可能丢失中继日志,导致复制中断 - 不要在跨机房链路中启用
slave_compressed_protocol=ON——压缩反而增加CPU开销,而带宽瓶颈通常不在传输层而在网络RTT
过滤复制+延迟从库应对误操作兜底
跨机房链路一旦出问题,修复窗口极小。最实际的做法不是追求零延迟,而是主动引入可控延迟:CHANGE MASTER TO MASTER_DELAY = 3600让从库滞后1小时。这样人为DROP TABLE或UPDATE误操作后,还有时间拦截并跳过该事务。
同时用replicate_do_db或replicate_rewrite_db过滤掉测试库、日志表等非核心数据,减少无效流量和复制压力。
- 过滤规则在
my.cnf中配置后需重启MySQL,运行时用STOP SLAVE; SET GLOBAL ...; START SLAVE不生效 -
MASTER_DELAY只对SQL线程生效,IO线程仍实时拉日志,所以磁盘空间监控不能只看Relay_Log_Space - 延迟从库无法用于读扩展——它连
SELECT都比主库旧,别把它加进读负载均衡池
用ProxySQL或自研中间件隔离网络抖动影响
原生复制对TCP连接异常极其敏感:ERROR 2013 (HY000): Lost connection to MySQL server during query这类报错背后往往是机房间专线瞬断。直接暴露给应用层会引发雪崩。更稳妥的方式是在主库前加一层ProxySQL,配置mysql-monitor模块持续探测从库健康状态,并设置weight动态降权故障节点。
如果不用中间件,至少要在应用侧实现连接池级熔断:检测到连续3次COMMIT超时就标记该从库不可用,10分钟内不再路由查询过去。
-
ProxySQL的mysql_replication_hostgroups表必须显式插入主从关系,仅靠SHOW SLAVE STATUS无法自动发现拓扑 - 跨机房心跳检测间隔别设太密(如
monitor_interval=1000),否则大量PING请求本身就会占满小带宽链路 - 所有跨机房复制通道必须走
SSL(MASTER_SSL=1),否则运营商QoS策略可能优先丢弃未加密的复制流量
真正难的从来不是配通复制,而是当两个机房之间出现单向丢包、时钟漂移超过500ms、或者某台机器突然启用TCP BBR拥塞控制时,你的监控能不能在30秒内准确定位是网络问题还是MySQL自身bug。











