数据库主库故障时业务如何快速切换?核心答案只有一句话:提前做好高可用架构设计,把切换动作变成自动化脚本,靠演练把恢复时间压到30秒以内,而不是等故障发生后再去查文档、敲命令。
业界有个共识:主库宕机后,业务不可用的每一秒都是真金白银的损失,今天咱们不聊理论,直接掰开揉碎讲清楚,主库挂了以后,从发现到恢复,每一步怎么做。
故障发生后,先判断是”假死”还是”真死”
主库连不上了,别急着切换,先花10秒钟搞清楚状态,很多时候是虚惊一场。
- 网络抖动:应用连不上数据库,但数据库进程还活着,这种情况盲目切换,等于自己给自己制造故障。
- 服务器宕机:SSH连不上,ping不通,基本可以确认物理机挂了。
- 进程崩溃:MySQL进程没了,但服务器还活着,还有抢救余地。
- 磁盘写满:只读不写,应用报错”disk full”,这属于可恢复故障,优先清理磁盘。
判断命令就三招:
ping 数据库IP ssh 数据库IP mysql -h数据库IP -uroot -p -e "select 1"
前两步不通,直接进入切换流程,第三步通但执行慢,大概率是负载问题,再观察几秒。
数据库高可用方案选型,直接决定切换速度
行业共识是:没有一种方案能应对所有场景,但多数生产环境的选择集中在以下几种,不同方案对应不同的恢复时间,也对应不同的价格,这里直接给结论。
MHA:老牌方案,成熟但已停止维护
MHA(Master High Availability)是早期用得最多的方案,原理是基于半同步复制做故障检测和自动切换,优势是部署简单,文档多,踩坑经验随手能搜到,劣势也很明显:没有统一管理节点,存在脑裂风险,且已经停止更新。
如果你还在用MHA,建议尽快评估迁移,这类方案适合对切换时间要求不高的内部系统,切换时间通常在30秒到1分钟。
基于半同步复制+脚本:成本最低的快速切换方案
很多团队没有专门的高可用组件,就用MySQL自带的半同步复制,配合自己写的检测脚本,检测脚本循环执行select 1,连续3次失败就触发切换。
核心切换逻辑就这几步:
# 在某台从库上执行 stop slave; change master to master_host='旧主库IP', ...; # 反向同步,回切用 reset slave all; # 提升为新的主库 set global read_only=0;
这种方案够用,但脚本质量决定了可靠性,多数团队栽在脚本没处理”主库其实没死,只是慢”的场景。
数据库高可用方案价格差异:从免费到几十万
聊到选型,必须说预算。数据库高可用方案价格从完全免费到每年几十万的商业版都有,差异主要在服务保障和自动化程度。
| 方案类型 | 接入成本 | 恢复时间 | 适用场景 |
|---|---|---|---|
| 自研脚本+复制 | 低 | 30秒-2分钟 | 小型业务,允许手动介入 |
| MHA | 低 | 20-40秒 | 传统架构,维护能力强的团队 |
| Orchestrator | 中等 | 10-30秒 | 中大型MySQL集群,支持拓扑管理 |
| MGR/InnoDB Cluster | 中等 | 5-15秒 | 对一致性要求高的新业务 |
| 分布式数据库(如TiDB) | 较高 | 秒级自动恢复 | 大规模、高并发核心业务 |
自研和MHA适合预算紧的团队,Orchestrator是当前性价比很高的选择,MGR适合对数据一致性敏感的业务,分布式数据库则是彻底解决问题,不过技术栈变重了。
MySQL主从切换方案具体操作步骤
不管用哪种工具,手动切换的底层逻辑都一样,这里给一套经过验证的操作路径,建议你照着走一遍,把输出记录下来作为应急预案。
切换前的参数检查
登录可能成为新主的从库,执行:
show slave status\G; -- 确认 Slave_IO_Running: Yes -- 确认 Slave_SQL_Running: Yes -- 记录 Master_Log_File 和 Read_Master_Log_Pos
这两项不是Yes,说明从库同步滞后,此时切换会丢数据,需要先补齐再操作。
提升从库为主库的关键步骤
# 第一步:停掉旧主库的写入(如果还能连上) mysql -h旧主库 -e "set global read_only=1;" # 第二步:在从库上停止同步并重置 mysql -h新主库 -e "stop slave; reset slave all;" # 第三步:开启读写 mysql -h新主库 -e "set global read_only=0;" # 第四步:检查新主库的日志坐标 mysql -h新主库 -e "show master status;"
最后一步的坐标要记好,其他从库重新指向新主库时要用到。
其他从库重新指向新主库
mysql -h其他从库 -e " change master to master_host='新主库IP', master_user='repl', master_password='xxx', master_log_file='记录的值', master_log_pos=记录的值; start slave; "
应用连接的切换,别忽略代理层
数据库层面切完了,应用还连着旧IP,等于白切,生产环境标配是使用代理层,推荐ProxySQL或MaxScale。
以ProxySQL为例,修改后端节点状态:
mysql -h127.0.0.1 -P6032 -uadmin -padmin update mysql_servers set hostgroup_id=0 where hostname='旧主库IP'; update mysql_servers set hostgroup_id=2 where hostname='新主库IP'; load mysql servers to run; save mysql servers to disk;
这样做的好处是应用感知不到后端变化,连接数也不中断。
主从切换失败怎么办?这几类情况最棘手
切换不是每次都能成功,预案里得包含失败回退策略,数据库主从切换失败怎么办,业内专家指出关键是要快速判断能否回退,而不是反复试错。
从库数据落后太多
从库的Seconds_Behind_Master一直跳动,说明追不上主库,此时强行切换会丢大量事务,业务数据对不上账,建议放弃切换,等待旧主库恢复,或者接受丢失最后一段时间的数据。
脑裂后双写
主库没死透,网络分区导致新主库和旧主库同时接收写入,这时候要立刻把旧主库强制只读:
mysql -h旧主库 -e "set global super_read_only=1; set global read_only=1;"
然后对比两边的gtid_executed,确定差异事务,选择保留数据更完整的一方。
VIP切换不生效
用Keepalived做虚拟IP的场景,漂移失败多半是ARP缓存或防火墙拦截,在应用服务器上执行:
arping -I eth0 -c 5 -s 新VIP 网关IP
实在不行,就手动在交换机上改ARP表,或者用ip addr add临时绑定新VIP。
Redis主从切换和MySQL有什么不同
缓存层主库挂掉,切换逻辑更简单,但要注意缓存穿透问题。Redis主从切换常用的手段是SENTINEL failover手动触发,或直接改客户端配置指向新主库。
redis-cli -p 26379 sentinel failover mymaster
切换后,新主库的maxmemory策略如果是allkeys-lru,冷数据会被自然淘汰,热点数据需要业务慢慢预热,这是正常现象,别慌。
数据库高可用常见问题Q&A
问:数据库高可用方案一般要花多少钱?
成本差距很大,纯开源方案(自研脚本+MHA+Keepalived)零软件成本,主要是服务器和运维人力,Orchestrator开源免费,商业支持付费,云数据库RDS自带高可用,价格比自建贵,但省心,按年购买通常有折扣,具体数据库高可用方案价格需要结合实例规格和地域,一二线城市机房和偏远地域的带宽成本差异明显,多数中型公司选型时会把Orchestrator + ProxySQL这套组合作为性价比标杆。
问:主从切换后,旧主库重新上线要不要当从库重新同步?
需要,而且必须重新同步,旧主库因为故障期间可能继续接收了写入(脑裂),不能直接挂回集群,正确做法是把旧主库的data目录备份并清空,重新用xtrabackup或mysqldump全量备份,然后change master指向新主库,追平后作为从库运行。
问:数据库高可用切换演练多久做一次比较合适?
至少一个季度一次,核心系统建议每月一次,演练要模拟真实故障,包括拔网线、kill进程、断电三种方式,很多团队发现,故障真正发生时,脚本和文档里的步骤往往对不上,这就是演练太少导致的,每次演练后更新预案文档,记录耗时和不顺手的环节。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/773134.html


