手动搭建MySQL MHA高可用架构:从主库宕机到自动切换实战
1. 为什么手动搭建MHA依然值得学1.1 从一次主库宕机说起凌晨两点监控告警响了主库连接数直接掉零。当时我们那套业务用的是单点MySQL没有做任何高可用。运维同学从被窝里爬起来手动切从库、改配置、重启服务前后折腾了四十多分钟。那四十分钟里所有写操作全部失败订单堆积、用户投诉、客服电话被打爆。事后复盘问题不在于“有没有备份”而在于“切换太慢、太依赖人”。这件事之后我开始认真研究MySQL的高可用方案。市面上方案不少但MHAMaster High Availability是我认为最适合中小团队手动搭建、也最能让人真正理解主从切换底层逻辑的一套架构。它不像某些商业方案那样是个黑盒你能清楚看到每一步在干什么出了问题也知道从哪儿查。这篇文章就是把我自己搭MHA的完整过程拆开讲。MHA的核心价值在于主库挂了之后能在几十秒内自动完成故障检测、日志补齐、从库提升、其他从库重新指向新主库这一整套动作把原本需要人工介入几十分钟的活儿压缩到半分钟以内。适合谁看有一定Linux和MySQL基础、想给自己的业务加一层高可用保障、又不想一上来就上复杂分布式方案的开发和运维同学。小白也能跟因为我会把每个参数为什么这么配都讲清楚。1.2 MHA到底解决了什么问题先把概念说透。MHA是一套由日本开发者维护的开源工具集它本身不是MySQL的插件而是运行在管理节点上的一组Perl脚本配合每个MySQL节点上的agent程序工作。它的工作模式分两块Manager节点负责监控和决策Node节点负责执行具体的切换动作。它解决的核心问题是主库单点故障。传统主从架构里主库一挂从库虽然数据还在但没人告诉应用该连哪儿也没人把从库提升成新主库。MHA做的事情就是持续探测主库心跳一旦发现主库不可达立刻从所有从库中挑一个数据最全的通过对比relay log和binlog的位点把它提升为新主库然后把其余从库重新挂到新主库下面最后可选尝试拉起原主库作为新从库。这里有个关键点很多人忽略MHA能最大程度保证数据不丢。它会在切换前从宕机主库上如果SSH还能连上把还没同步到从库的binlog差异部分抓下来补到新主库上。这个动作叫“日志补齐”是MHA区别于简单脚本切换的核心竞争力。当然如果主库彻底宕机、SSH都连不上那这部分差异就补不回来了这也是为什么MHA官方建议配合半同步复制使用。2. 搭建前的架构设计与环境规划2.1 节点角色怎么分配动手之前先把机器规划好不然后面改来改去很痛苦。我这次用的是四台机器虚拟机即可角色分配如下角色主机名说明Manager管理节点mha-manager跑MHA Manager负责监控和切换主库mysql-master初始主库写节点从库1mysql-slave1候选主库优先级高从库2mysql-slave2候选主库优先级低为什么Manager要单独一台因为Manager本身如果和MySQL混部主库挂了可能把Manager一起带崩监控就失效了。管理节点必须独立这是铁律。如果资源紧张Manager可以和某台从库混部但绝不能和主库混部。从库数量建议至少两个。一个从库也能切但没有冗余切换后新架构依然脆弱。两个从库的好处是一个提升为主库另一个继续做从库架构立刻恢复成一主一从还有余量。2.2 版本选择与依赖清单版本这块我踩过坑必须说清楚。MHA对MySQL版本和操作系统都有要求MySQL建议5.7或8.0。MHA 0.58版本对8.0支持较好但要注意8.0默认的caching_sha2_password认证插件MHA可能不认需要改成mysql_native_password。操作系统CentOS 7或Rocky Linux 8都行我用的是Rocky 8。关键是Perl环境要全MHA是Perl写的缺模块会直接报错。SSH互信Manager到所有Node、Node之间都要配SSH免密。MHA靠SSH来远程执行命令和拷贝binlog这个不通后面全白搭。依赖清单我列一下装的时候一次性搞定# 所有节点都需要的依赖 yum install -y perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch \ perl-Parallel-ForkManager perl-Time-HiRes perl-ExtUtils-MakeMaker \ perl-Data-Dumper perl-Digest-MD5注意perl-Parallel-ForkManager这个模块特别容易漏MHA Manager启动时会用它做并行操作缺了会报“Cant locate Parallel/ForkManager.pm”。我第一次搭就是卡在这儿查了半天。2.3 网络与端口规划端口方面MySQL用默认3306MHA Manager本身不监听端口它是主动去连MySQL和SSH。但要注意防火墙Manager要能访问所有Node的3306和22端口Node之间也要能互相访问3306和22。我图省事直接把内网网段全放通了生产环境建议按需开放。主机名解析也要配好/etc/hosts里把四台机器的IP和主机名对应写上。MHA配置里用主机名比用IP更清晰切换日志也好读。3. 主从复制环境的手动搭建3.1 主库配置与账号准备MHA是建立在主从复制基础上的所以第一步得先把一主两从的复制跑通。先改主库的my.cnf[mysqld] server-id1 log-binmysql-bin binlog_formatROW gtid_modeON enforce_gtid_consistencyON log_slave_updatesON这里几个参数解释一下。binlog_formatROW是MHA推荐的因为行复制在数据一致性上更可靠切换时位点计算也更准。gtid_modeON开启GTID好处是切换后从库找位点不用再算binlog文件名和position直接靠GTID自动定位极大降低切换出错概率。log_slave_updatesON是给从库用的让从库也把收到的更新写进自己的binlog这样从库才能作为候选主库继续向下游同步。改完重启MySQL然后创建复制账号和MHA管理账号-- 复制账号 CREATE USER repl% IDENTIFIED BY Repl_2024#Pass; GRANT REPLICATION SLAVE ON *.* TO repl%; -- MHA管理账号需要较大权限 CREATE USER mha% IDENTIFIED BY Mha_2024#Pass; GRANT ALL PRIVILEGES ON *.* TO mha% WITH GRANT OPTION; FLUSH PRIVILEGES;提示MHA管理账号权限要给足因为它要执行CHANGE MASTER TO、RESET SLAVE、SET GLOBAL read_only等操作。生产环境可以细化权限但搭建阶段先给全跑通再收紧。3.2 从库配置与复制启动两个从库的my.cnf类似只是server-id不同[mysqld] server-id2 # slave1用2slave2用3 log-binmysql-bin binlog_formatROW gtid_modeON enforce_gtid_consistencyON log_slave_updatesON read_onlyONread_onlyON让从库只读防止误写。但注意这个参数对拥有SUPER权限的用户无效MHA切换时会临时改这个值所以别用super_read_only否则MHA改不动。配置好后在两个从库上分别执行CHANGE MASTER TO MASTER_HOSTmysql-master, MASTER_USERrepl, MASTER_PASSWORDRepl_2024#Pass, MASTER_AUTO_POSITION1; START SLAVE;MASTER_AUTO_POSITION1就是启用GTID自动定位。执行完用SHOW SLAVE STATUS\G检查确认Slave_IO_Running和Slave_SQL_Running都是YesSeconds_Behind_Master为0。3.3 验证复制与SSH互信复制跑通后在主库建个测试库写点数据看从库能不能同步过来。这一步别省我见过配置看着都对但实际不同步的情况多半是防火墙或账号权限问题。SSH互信配置Manager节点生成密钥公钥分发到所有Node同时每个Node也生成密钥互相分发。简单点可以直接在Manager上对所有节点做免密Node之间也做。验证方法就是ssh mysql-master不输密码能进去。# Manager上执行 ssh-keygen -t rsa -N for host in mysql-master mysql-slave1 mysql-slave2; do ssh-copy-id $host done4. MHA Manager与Node的安装配置4.1 安装MHA软件包MHA分两部分Node节点装mha4mysql-nodeManager节点装mha4mysql-node加mha4mysql-manager。官方没有现成的yum源得下源码包编译或找rpm包。我用的是源码编译虽然慢点但兼容性好。# 所有节点装node tar -zxvf mha4mysql-node-0.58.tar.gz cd mha4mysql-node-0.58 perl Makefile.PL make make install # Manager节点额外装manager tar -zxvf mha4mysql-manager-0.58.tar.gz cd mha4mysql-manager-0.58 perl Makefile.PL make make install装完检查一下命令在不在which masterha_manager、which masterha_check_ssh。这两个命令后面要用。4.2 编写Manager配置文件这是整个搭建的核心。在Manager节点上建/etc/mha/app1.cnf[server default] manager_workdir/var/log/mha/app1 manager_log/var/log/mha/app1/manager.log usermha passwordMha_2024#Pass ssh_userroot repl_userrepl repl_passwordRepl_2024#Pass ping_interval2 master_binlog_dir/var/lib/mysql [server1] hostnamemysql-master candidate_master1 check_repl_delay0 [server2] hostnamemysql-slave1 candidate_master1 check_repl_delay0 [server3] hostnamemysql-slave2 no_master1逐项解释。ping_interval2是每2秒探测一次主库探测越频繁切换越快但网络抖动时容易误判2秒是个平衡点。master_binlog_dir告诉MHA去哪个目录找binlog路径必须和实际一致否则日志补齐会失败。candidate_master1表示这个节点可以作为候选主库。我给两个从库都设了但slave1的优先级更高MHA按配置顺序选。check_repl_delay0是关闭复制延迟检查意思是即使这个从库有延迟也允许它当主库。这个参数有争议设0切换快但可能丢数据设1更安全但延迟大时切不了。我建议只在延迟可控的环境设0否则还是保守点。no_master1表示slave2永远不参与主库竞选纯做从库。这样架构更清晰。4.3 配置校验与启动配置写完别急着启动先用MHA自带的检查工具验证# 检查SSH互信 masterha_check_ssh --conf/etc/mha/app1.cnf # 检查复制状态 masterha_check_repl --conf/etc/mha/app1.cnfcheck_ssh会遍历所有节点两两测试全绿才行。check_repl会检查主从复制、账号权限、binlog格式等输出“MySQL Replication Health is OK”才算过。这两个检查我强烈建议每次都跑。我遇到过check_repl报“binlog format is not ROW”的情况回头查才发现有个从库的my.cnf没改全。这种问题不检查直接启动切换时才发现就晚了。启动Managernohup masterha_manager --conf/etc/mha/app1.cnf \ --remove_dead_master_conf \ --ignore_last_failover \ /var/log/mha/app1/manager.out 21 --remove_dead_master_conf表示切换后把死掉的主库配置从文件里删掉避免下次启动报错。--ignore_last_failover是忽略上次的failover记录否则MHA默认8小时内不重复切换。这两个参数在测试阶段很有用。5. 故障切换实测与日志解读5.1 模拟主库宕机搭好了不测等于没搭。测试方法很简单在Manager运行状态下直接把主库的MySQL进程杀掉或者更彻底点关机。# 在mysql-master上 systemctl stop mysqld然后盯着Manager日志/var/log/mha/app1/manager.log。正常的话几秒内就会看到“Ping(SELECT) failed”之类的探测失败记录接着开始failover流程。5.2 切换过程逐步拆解MHA的切换流程大致分这几个阶段日志里能清楚看到检测阶段连续多次ping失败后判定主库宕机。日志补齐阶段尝试SSH连原主库把差异binlog拷到Manager再应用到新主库。如果SSH连不上跳过这步并记录警告。选主阶段从候选从库中选一个对比GTID或位点选数据最新的。提升阶段对新主库执行STOP SLAVE、RESET SLAVE ALL、SET GLOBAL read_onlyOFF把它变成可写主库。重定向阶段其余从库执行CHANGE MASTER TO指向新主库重新启动复制。收尾阶段写failover记录Manager进程退出MHA Manager默认切换后自己停掉需要配合守护脚本重新拉起或手动重启。整个流程实测下来从杀进程到新主库可写大概20到40秒。比人工快太多了。5.3 切换后验证与恢复切换完成后登录新主库原来的slave1确认SHOW MASTER STATUS; SELECT read_only; -- 应该是0再登录slave2SHOW SLAVE STATUS\G确认它已经指向新主库且复制正常。原主库修好后可以手动把它重新加入集群作为从库。步骤是启动MySQL执行CHANGE MASTER TO指向新主库START SLAVE。注意原主库上可能有新主库没有的数据宕机前没同步的所以重新加入前最好确认数据一致性或者干脆用备份重建。注意MHA切换后Manager进程会退出这是设计如此。生产环境要用masterha_manager配合systemd或supervisor做守护让它退出后自动重启否则第二次故障就没人管了。6. 常见问题排查与避坑经验6.1 高频报错速查表报错信息原因解决Cant locate Parallel/ForkManager.pm缺Perl模块装perl-Parallel-ForkManagerSSH connection failed互信没配好重新分发公钥检查authorized_keys权限binlog format is not ROWbinlog格式不对改my.cnf并重启MySQLMySQL Replication Health is NOT OK复制断了或账号错查SHOW SLAVE STATUS核对账号密码Failed to get master binlogbinlog路径配错核对master_binlog_dir与实际路径Authentication plugin caching_sha2_passwordMySQL8认证插件问题改用户为mysql_native_password6.2 几个容易翻车的细节第一个坑SSH互信只配了单向。MHA不仅Manager要连NodeNode之间也要互相连比如新主库要从原主库拷binlog。我第一次只配了Manager到Node切换时报“SSH to mysql-master failed”。后来补全了所有节点两两互信才通过。第二个坑GTID和位点混用。如果主从用GTIDMHA配置里也要相应调整否则切换时位点计算会出错。我建议要么全GTID要么全位点别混。第三个坑read_only和super_read_only。前面提过MHA切换要改read_only如果开了super_read_only连SUPER用户都写不了切换会卡住。生产环境如果非要开super_read_only得在MHA配置里做特殊处理。第四个坑Manager单点。MHA Manager本身也是单点它挂了就没人监控了。生产环境可以考虑用两个Manager做互备或者用keepalived给Manager做VIP。这个进阶话题以后可以单独聊。6.3 我的实操心得搭MHA最耗时的不是配置而是排查环境问题。我的建议是先把主从复制跑稳再装MHA装完先跑check_ssh和check_repl两个都过了再启动启动后立刻做一次切换测试别等真出事才发现切不了。另外MHA的日志非常详细出问题先看manager.log里面会告诉你卡在哪一步。我大部分问题都是靠日志定位的比瞎猜快得多。还有一点MHA不是银弹。它能解决主库宕机的自动切换但解决不了数据延迟导致的丢失除非配合半同步也解决不了脑裂需要额外机制。把它当成高可用体系里的一环而不是全部。最后分享个小技巧测试切换时可以用masterha_master_switch --master_statealive做在线切换不用真杀进程。这个命令能在主库活着的时候演练切换对生产环境做维护窗口特别有用。

相关新闻

Oracle 19c RAC on Linux 7.6 安装实战:从环境检查到静默建库

Oracle 19c RAC on Linux 7.6 安装实战:从环境检查到静默建库

简介:面向需要在Red Hat Enterprise Linux 7.6上部署Oracle 19c RAC的DBA与运维工程师,这份安装手册将环境准备与集群配置拆分为可逐步跟做的阶段,涵盖OS环境检查、关闭THP并开启Hugepages、依赖包与内核参数设置、时钟同步等前置任务&#x…

2026/10/14 17:00:18 阅读更多 →
RoboMaster硬件实战笔记:从电源纹波到EMC防护的四道硬门槛

RoboMaster硬件实战笔记:从电源纹波到EMC防护的四道硬门槛

1. 这份讲义不是“教材”,而是一份硬件工程师的现场笔记“Robomaster硬件基础讲义V0.2.1”——光看这个标题,很多人第一反应是:又一份高校课程PPT?或者某支参赛队内部传阅的速查手册?其实都不是。我第一次见到它&#…

2026/10/14 17:00:18 阅读更多 →
ECU逆向工程全流程管理:从评估基线到量产落地的方法论

ECU逆向工程全流程管理:从评估基线到量产落地的方法论

去年又一个项目让我深刻体会到:ECU逆向这活儿,真正卡死团队的不是技术难度,而是流程失序。当时我们只是在一个老平台上做兼容件开发,结果评估阶段少抓了一组唤醒信号,量产前才暴露出来,拆台架、改硬件、迁固…

2026/10/14 17:00:18 阅读更多 →

最新新闻

IntelliJ IDEA 的Qoder CN 插件报错“暂时无法同步代码库索引选择”怎么解决?完整排查与修复指南

IntelliJ IDEA 的Qoder CN 插件报错“暂时无法同步代码库索引选择”怎么解决?完整排查与修复指南

摘要 本文针对在IDEA中使用Qoder CN时出现的报错,给出官方说明与实战解决步骤。官方指出需启用代码库索引:可点击“创建”手动启用,或切换“自动索引”。实战中,先登录Qoder CN且不要输入提示词,再进入设置—>Qode…

2026/10/14 17:36:00 阅读更多 →
PTZ-C8T6.zip 云台控制 C 工程解析:编译、协议与避坑指南

PTZ-C8T6.zip 云台控制 C 工程解析:编译、协议与避坑指南

简介:PTZ-C8T6.zip 是一份面向嵌入式开发初学者与 STM32 学习者的云台控制项目工程源码,基于 STM32F103 系列芯片与 HAL 库构建,适合用于课程设计、毕业设计或电赛类云台控制方案的参考与二次开发。压缩包共 98 个文件,约 675KB&a…

2026/10/14 17:36:00 阅读更多 →
Python 读取 Excel 并写入 zip:自动化报表打包实战

Python 读取 Excel 并写入 zip:自动化报表打包实战

简介:这份资源面向需要处理表格数据的Python学习者与开发者,聚焦Excel文件的读取与写入这一常见任务,帮助解决数据分析、数据清洗与自动化报告中的表格操作问题。压缩包共4个文件,全部为py脚本,整体约6KB,涵…

2026/10/14 17:36:00 阅读更多 →
Terminus(Olares)RabbitMQ 中间件集成实战:用 OlaresManifest.yaml 声明式接入消息队列

Terminus(Olares)RabbitMQ 中间件集成实战:用 OlaresManifest.yaml 声明式接入消息队列

云原生后端运维 【免费下载链接】Terminus Open-Source Personal Cloud OS for Always-On Agents 项目地址: https://gitcode.com/gh_mirrors/terminus2/Terminus 点击查看 免费下载 本篇技术指南基于 Terminus 仓库中 RabbitMQ 集成文档 展开,讲解如何…

2026/10/14 17:36:00 阅读更多 →
九轴姿态解算实战:C语言实现Mahony互补滤波与四元数融合

九轴姿态解算实战:C语言实现Mahony互补滤波与四元数融合

简介:九轴姿态解算源代码是一套面向嵌入式开发、无人机及机器人等场景的C语言实现,融合加速度计、磁力计与陀螺仪数据,用于实时估计物体的横滚、俯仰与偏航角。资源包含4个文件,全部为2个C源文件和2个头文件,压缩包仅5…

2026/10/14 17:36:00 阅读更多 →
C#工业级图形面积周长计算:精度、鲁棒性与性能平衡

C#工业级图形面积周长计算:精度、鲁棒性与性能平衡

1. 项目概述:为什么一个“图形周长、面积计算”功能值得花时间深挖? 你可能第一眼看到“C# 图形周长、面积计算”这个标题,会下意识觉得:“不就是几个数学公式封装成方法吗?勾股定理、πr、底高2……抄一遍就完事。”我…

2026/10/14 17:34:59 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →