主从复制本身不等于高可用,必须叠加故障检测与自动切换
MySQL 主从复制只是单向数据同步机制,
START SLAVE启动后,它不会主动感知主库宕机,也不会自动把从库提为新主。所谓“高可用”,本质是「主库挂了,业务无感切到新主」,这需要额外组件介入——比如
Orchestrator、
MHA或基于
ProxySQL + Consul的自建方案。只配好
CHANGE MASTER TO和
relay_log,同步再稳,也做不到高可用。
避免 GTID 模式下因 gtid_purged
不一致导致的复制中断
启用 GTID 后,从库重启或重搭时若
gtid_purged与主库缺失 binlog 区间不匹配,
START SLAVE会直接报错
Cannot replicate because the master purged required binary logs。实际操作中容易忽略两点: 主库执行
RESET MASTER后,必须手动导出并注入当前
gtid_executed到从库(用
SET GLOBAL gtid_purged = '...') 从库做
mysqldump --set-gtid-purged=ON备份时,要确认主库 binlog 未被
expire_logs_days清理掉对应部分 跨版本升级(如 5.7 → 8.0)时,
gtid_mode必须分步开启(OFF → OFF_PERMISSIVE → ON_PERMISSIVE → ON),否则从库无法识别新格式 GTID
半同步复制不是银弹,rpl_semi_sync_master_timeout
设置不当反而拖垮写入
开启
rpl_semi_sync_master_enabled = ON后,若超时参数
rpl_semi_sync_master_timeout设得过大(比如默认 10000ms),主库在等从库 ACK 时会长时间阻塞事务提交,导致应用端
INSERT/UPDATE延迟飙升。真实生产环境建议: 设为
1000(1 秒),超时即退化为异步,保障主库可用性优先 配合监控
Rpl_semi_sync_master_yes_tx与
Rpl_semi_sync_master_no_tx状态变量,及时发现从库长期失联 不要在所有从库上都强制半同步——可指定 1 台核心从库启用,其余保持异步,兼顾可靠性与吞吐
切换后的从库需重置复制起点,否则可能重复执行或跳过事务
主库故障后,人工或工具将某台从库提升为主库(例如执行
STOP SLAVE; RESET SLAVE ALL;),此时它已不再是“从库”角色。但若其他剩余从库仍按旧主的 binlog 位置继续拉取,就会出问题: 原主已不可达,
CHANGE MASTER TO MASTER_HOST='old_ip'必然失败 即使指向新主,若未用
CHANGE MASTER TO MASTER_AUTO_POSITION = 1(GTID 模式)或未手动校准
MASTER_LOG_FILE/
MASTER_LOG_POS,大概率出现
Could not execute Write_rows_v1 event类冲突 更稳妥做法:提升新主后,对其他从库统一执行
CHANGE MASTER TO ... MASTER_AUTO_POSITION = 1,并确保新主已开启
log_slave_updates
真正难的不是同步数据,而是让所有节点对“谁是主、从哪开始同步”达成一致——这个一致性边界,MySQL 自己不管,得靠外部协调器或严格的操作流程兜底。
