当 MariaDB 主库宕机,从库还在复制,业务却已经中断——这是每个 DBA 都怕遇到的场景。本文围绕 MariaDB主从复制 的故障切换,从实际问题切入,边操作边解释,帮助你安全地提升从库、恢复写入。
故障发生:先确认主库真的不可用
不要一看到连接超时就切换。先确认主库是否真的宕机,还是只是网络抖动或负载过高。常见的检测方法:
- 尝试 SSH 登录主库,观察系统负载和进程状态。
- 在从库上执行
SHOW SLAVE STATUS,查看Seconds_Behind_Master是否持续增长。 - 检查监控系统,确认主库的存活探针是否连续失败。
如果主库进程还在,但写入卡死,可能只是锁竞争,此时强制切换可能导致数据丢失。只有在确认主库物理宕机、或无法在可接受时间内恢复时,才考虑切换。
切换前:确保从库数据尽量新
切换的核心风险是丢失主库上尚未复制到从库的事务。在理想情况下,主从延迟为 0,但现实中总有延迟。切换前,你需要评估从库的滞后程度:
SHOW SLAVE STATUSG
关注 Relay_Master_Log_File 和 Exec_Master_Log_Pos,对比主库的 binlog 位置。如果从库已经应用了主库最后的 binlog,那么数据损失很小;否则,你需要接受一个事实:从库可能缺失部分数据。
如果业务允许,可以尝试从主库的 binlog 中抢救缺失的事务,但这个过程复杂且不一定成功。更实际的做法是:在切换后,通过比对数据或回放 binlog 来尽量恢复。
执行切换:提升从库为主库
确认从库数据可接受后,按以下步骤操作:
- 在从库上停止复制:
STOP SLAVE; - 记录复制停止的位置:
SHOW SLAVE STATUS;记下Relay_Master_Log_File和Exec_Master_Log_Pos,以备后续恢复。 - 重置从库身份:
RESET SLAVE ALL;清除复制信息。 - 启用写入:
SET GLOBAL read_only = OFF;(如果之前开启了只读) - 将应用连接指向新主库。
注意:RESET SLAVE ALL 会清除所有复制配置,执行前务必确认。如果从库原本配置了级联复制,还需要更新下游从库的源信息。
切换后:重建复制拓扑
新主库开始服务后,需要让其他从库重新指向它。对于每个从库:
- 在新主库上创建复制用户(如果还没有)。
- 在从库上执行
CHANGE MASTER TO指定新主库的地址、日志文件和位置。 - 启动复制:
START SLAVE; - 检查
SHOW SLAVE STATUS确保Slave_IO_Running和Slave_SQL_Running均为 YES。
如果原主库只是暂时故障,后来恢复了,不要直接把它加回集群,否则会造成脑裂。需要先将其作为从库重新初始化,或者彻底下线。
常见误区与取舍
- 误区:切换前不检查数据一致性。 如果从库落后太多,切换后数据丢失严重,可能引发业务事故。建议定期校验主从数据一致性。
- 误区:盲目使用半同步复制。 半同步可以降低数据丢失风险,但会增加写入延迟,需要根据业务权衡。
- 取舍:自动切换 vs 手动切换。 自动切换(如使用 MHA、Orchestrator)响应快,但误判风险高;手动切换更可控,但需要人工介入。建议在业务允许的情况下,使用自动切换工具并配合完善的监控。
- 误区:忽略应用层的重连机制。 切换后应用必须能自动重连到新主库,否则业务依旧中断。需要在连接池或驱动层面配置多地址和故障转移。
日志与监控:故障切换的必备支撑
故障切换过程中,日志和监控至关重要。根据 OWASP 日志安全速查表,应用日志应包含安全事件,而数据库切换属于关键操作,也应记录。你可以记录切换时间、操作人、切换前后主从状态等。OpenTelemetry 日志规范强调日志与 trace、metrics 的关联,在切换时,你可以将数据库操作的 trace ID 写入日志,便于后续排查。Python 的 logging 模块提供了灵活的分层日志机制,如果你的应用使用 Python,可以配置专门的数据库日志记录器,记录复制状态和切换命令。
监控方面,建议监控主从延迟、复制线程状态、binlog 位置等,并设置告警。当延迟超过阈值或复制线程停止时,立即通知运维。
总结
MariaDB 主从复制故障切换不是简单的几条命令,而是一个需要谨慎决策的过程。核心要点是:确认故障、评估数据损失、安全提升、重建拓扑、配置监控和日志。每一步都有取舍,没有万能方案,必须结合业务实际。
参考资料
延伸阅读
