MySQL原生不支持自动故障转移,必须依赖MHA、Orchestrator、InnoDB Cluster或ProxySQL等外部组件实现;切换成功的关键在于GTID一致性、复制源重定向和应用连接池刷新。

MySQL 原生不支持自动故障转移,主从复制本身只是数据同步机制,不具备高可用(HA)决策能力;要实现自动故障转移,必须依赖外部工具或中间件。
MySQL 主从复制本身没有自动选主逻辑
主从复制仅保证 binlog 从主库写入、从库重放,IO_THREAD 和 SQL_THREAD 的状态(如 Seconds_Behind_Master)需人工监控。MySQL 不会因主库宕机而自动将某从库提升为新主,也不会自动修改其余从库的 CHANGE REPLICATION SOURCE TO 配置。
- 常见错误现象:
SHOW REPLICA STATUS/G显示Replica_IO_Running: No或Replica_SQL_Running: No,但没人干预,复制就一直停着 - 主库宕机后,应用若仍连原主地址,会直接报错
Lost connection to MySQL server,不会“自动切到从库” - 即使配置了读写分离中间件(如
ProxySQL),它默认也不具备主库故障后的自动提主 + 重配从库能力,需额外脚本或插件支持
常用自动故障转移方案及关键差异
真正起作用的是外围组件,它们通过心跳、复制延迟、角色状态等判断是否触发切换,并执行一系列原子操作:停写、选主、重置复制拓扑、更新路由。
-
MHA(Master High Availability):Perl 编写,成熟稳定,支持在线切换和自动 failover,但依赖 SSH 和mysqlbinlog解析,已多年未更新,对 MySQL 8.0+ 新认证插件兼容性需验证 -
Orchestrator:Go 编写,Web 界面友好,支持自动恢复、拓扑可视化、自定义钩子(如调用curl通知运维),但自身单点,建议配合Consul或etcd做高可用 -
MySQL InnoDB Cluster(基于Group Replication):官方方案,内置自动选主(group_replication_member_expel_timeout控制驱逐)、自动故障检测与恢复,但要求全栈使用 MySQL 5.7.17+ / 8.0+,且不兼容传统异步复制拓扑 -
ProxySQL + 自定义脚本:轻量灵活,适合已有架构;需自己实现健康检查(如查SELECT @@read_only)、failover 流程(调用STOP REPLICA; RESET REPLICA ALL;等),容易遗漏gtid_purged同步或relay_log_recovery设置
自动切换中最容易被忽略的三个技术点
很多 HA 方案失败不是因为选主逻辑错,而是后续数据一致性保障没做全。
- GTID 一致性:切换前必须确保所有从库已追平
Executed_Gtid_Set,否则新主上执行的新事务可能在部分从库重复或丢失;WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS是安全等待的关键函数 - 复制源重定向:新主提升后,其他从库需执行
CHANGE REPLICATION SOURCE TO SOURCE_HOST='new_master_ip',但SOURCE_AUTO_POSITION=1必须开启,否则 GTID 模式下会报错Client requested master to start replication from position > file size - 应用连接池未刷新:即使中间件切换成功,应用端的数据库连接池(如
HikariCP中的connection-test-query)若缓存旧主地址或未启用autoReconnect=true,仍会持续报错,需配合 DNS TTL 缩短或 VIP/SDN 地址漂移
-- 示例:Orchestrator 触发 failover 后,手动验证新主 GTID 追平情况 SELECT @@global.gtid_executed AS current_gtid, (SELECT Executed_Gtid_Set FROM performance_schema.replication_connection_status WHERE Channel_Name = 'group_replication_applier') AS applier_gtid;
自动故障转移不是开个开关就能用的功能,它是一组协同动作的集合:检测、决策、执行、验证、回滚预备。任何一环缺位,都可能导致脑裂、数据丢失或服务长时间中断。最常出问题的地方,往往不在“怎么切”,而在“切完之后,数据还对不对、下游还连不连得上”。
