运维知识
悠悠
2026年7月13日

MHA退场,Orchestrator接棒:Debian 13 + MySQL 8.0高可用迁移全记录

讲真,搭这套环境的时候我头都大了。

之前给公司搭的是经典MHA方案,跑在CentOS 7+MySQL 5.7上,好几年了稳如老狗。但今年IT架构升级,操作系统全部切到Debian 13,数据库统一升到MySQL 8.0.46,这下MHA就彻底歇菜了——倒不是它不能用,是真的"臣妾做不到了"。

MHA这套东西是2016年作者Yoshinori Matsunobu在GitHub上停更的,到现在已经快十年没人维护。MySQL 8.0那一堆新特性它根本不认识,Perl依赖在新系统上也是各种打架,硬装上去不是缺这个模块就是那个版本冲突,搞得人头皮发麻。

后来一狠心,决定上Orchestrator。这玩意儿是GitHub上一个明星项目,用Go语言写的,轻量、活跃、对MySQL 8.0支持好,配套还有个Web界面,拓扑图画得清清楚楚,比MHA那种纯命令行友好太多。用了几天之后,只想感叹一句:早干嘛去了。

这次的环境

先交代一下这次的舞台布景:

管理机:一台Debian 13的机器,装Orchestrator主程序,用它自带的SQLite存拓扑元数据,轻量省事。

MySQL集群:三台Rocky Linux 8的系统,跑MySQL 8.0.46,组个一主两从:

  • 主库 kafka-node1:192.168.198.201
  • 从库1 kafka-node2:192.168.198.202(开了super_read_only)
  • 从库2 kafka-node3:192.168.198.203(开了super_read_only)

Orchestrator的部署其实不难,但MySQL 8.0有几个底层特性是真的会让人卡壳,这也是我今天重点想讲的部分。

第一步:建账号,这一步差点翻车

Orchestrator得有个账号能登到所有MySQL节点上去探活、查拓扑。听起来很常规对吧?但偏偏就这一步,差点把整个项目拖黄了。

原因就是那两个从库开了super_read_only。在MySQL 8.0里,super_read_only=ON之后,连root账号都没法执行写操作了,包括创建用户和授权。我第一次直接登录从库跑CREATE USER的时候,控制台直接甩我一个ERROR 1290 (HY000): The MySQL server is running with the --super-read-only option so it cannot execute this statement,人都给我整麻了。

正确做法是按顺序来:

-- 先把只读保护临时关掉
SET GLOBAL super_read_only = 0;
SET GLOBAL read_only = 0;

-- 用兼容MySQL 8.0客户端的密码插件建账号
CREATE USER 'orchestrator_user'@'192.168.198.%' IDENTIFIED WITH mysql_native_password BY 'OrchPassword123!';

-- 给最小权限,别手贱多授
GRANT SUPER, PROCESS, REPLICATION SLAVE, RELOAD ON *.* TO 'orchestrator_user'@'192.168.198.%';
FLUSH PRIVILEGES;

-- 搞完赶紧把只读保护打开
SET GLOBAL read_only = 1;
SET GLOBAL super_read_only = 1;

注意主库不要执行那两行开关只读的命令,从库才需要。三台机器都得执行一遍,账号密码保持一致。

这里有个小细节,用mysql_native_password而不是默认的caching_sha2_password,是因为Orchestrator客户端兼容性还有些小问题,native_password更稳,踩过坑的老哥们应该都知道。

第二步:在Debian 13上装Orchestrator

Debian 13装东西是真舒服,包管理甩RPM几条街。Orchestrator官方提供了现成的.deb包,直接下下来装就行:

wget https://github.com/openark/orchestrator/releases/download/v3.2.6/orchestrator-cli_3.2.6_amd64.deb
wget https://github.com/openark/orchestrator/releases/download/v3.2.6/orchestrator_3.2.6_amd64.deb

sudo apt install ./orchestrator_3.2.6_amd64.deb ./orchestrator-cli_3.2.6_amd64.deb -y

但Debian有个让人又爱又恨的特性——unattended-upgrades服务默认开启,会自动跑包更新。如果运气不好撞上它正在工作,apt install就会卡在Could not get lock /var/lib/dpkg/lock-frontend这一步报错。

解决思路很简单粗暴:

# 找到占用锁的进程
ps -ef | grep apt
# 干掉它
sudo kill -9 <PID>
# 清理锁文件
sudo rm -f /var/lib/dpkg/lock-frontend /var/lib/dpkg/lock /var/cache/apt/archives/lock
# 然后重新装
sudo apt install ./orchestrator_*.deb -y

这种坑就是典型的"基础操作",但就是经常被人问起,所以单独提一下。

第三步:配置文件是个大工程

装完之后,配置文件才是真正的战场。Orchestrator的配置文件默认在/etc/orchestrator.conf.json,是用JSON格式写的,可读性比MHA的ini好不少。

直接上我的配置:

{
  "Debug": true,
  "ListenAddress": ":3000",

  "MySQLTopologyUser": "orchestrator_user",
  "MySQLTopologyPassword": "OrchPassword123!",
  "MySQLTopologyCredentialsConfigFile": "",

  "BackendDB": "sqlite",
  "SQLite3DataFile": "/var/lib/orchestrator/orchestrator.db",

  "InstancePollSeconds": 5,
  "DiscoverByShowSlaveHosts": true,

  "ReasonableReplicationLagSeconds": 10,
  "ProblematicReplicationLagSeconds": 30,

  "FailMasterApprovalRequired": false,
  "RecoveryPeriodBlockSeconds": 60,

  "RecoverMasterClusterFilter": "*",
  "RecoverIntermediateMasterClusterFilter": "*",

  "SeedInjectedPool": "192.168.198.201:3306,192.168.198.202:3306,192.168.198.203:3306",
  "HostnameResolveMethod": "none"
}

几个关键配置我单独拎出来说:

"InstancePollSeconds": 5:Orchestrator每5秒去探一次活,这个频率我觉得比较合理,太快了浪费资源,太慢了检测不及时。

"BackendDB": "sqlite":用SQLite存元数据,单机够用了。如果Orchestrator要做高可用,那就得用MySQL后端。

"DiscoverByShowSlaveHosts": true:让Orchestrator去通过SHOW SLAVE HOSTS命令发现从库,这是MySQL 8.0之后的推荐做法。

"FailMasterApprovalRequired": false:自动故障转移,不需要人工审批。如果你们公司流程严格,建议改成true,等人确认了再切。

"RecoverMasterClusterFilter": "*":所有集群都允许自动恢复。

重点来了——最下面那两个配置,是我这次能够"破案"的关键。

"SeedInjectedPool":直接告诉Orchestrator集群的种子IP有哪些,让它主动去探,而不是被动等主库汇报。

"HostnameResolveMethod": "none":禁掉主机名反查,因为MySQL 8.0的report_host经常出问题,这一关关了反而清爽。

第四步:那两个让我熬到凌晨两点的坑

配完之后启动服务,浏览器打开http://管理机IP:3000,一看拓扑图,差点一口老血喷在屏幕上——整个集群一片橙红,状态显示DeadMasterAndReplicas,意思就是主库是个孤岛,从库连不上。

于是就有了接下来长达四个小时的破案之旅。

坑一:克隆出来的虚拟机,Server_Id和UUID撞了

这次的从库是用模板克隆出来的,我没改server-id就直接用了。结果在主库执行SHOW REPLICAS;的时候,从库记录老是一会儿有一会儿没有,状态完全不对。

这就是经典的"克隆虚拟机没清UUID"的问题。Linux系统上用模板克隆虚拟机,MySQL的auto.cnf文件会被原样复制,导致所有从库的server_uuid完全一样,复制关系直接乱套。

解决方法倒也简单粗暴:

# 在每台机器的my.cnf里给server-id一个明确的值
[mysqld]
server-id=101  # 主库
# server-id=102  # 从库1
# server-id=103  # 从库2

然后去从库上把auto.cnf删掉重启MySQL:

rm -f /var/lib/mysql/auto.cnf
systemctl restart mysqld

重启之后MySQL会自动生成一个新的UUID,复制关系也就恢复正常了。这事儿其实在MHA时代就经常遇到,不算新坑,但每次都能让人烦一下。

坑二:主库上SHOW REPLICAS;的Host字段是空的

server-id修好之后,复制是跑起来了,但Orchestrator的网页还是显示主库孤岛。我又跑去主库手敲SHOW REPLICAS;一看——这下数据是有了,两条从库记录安安静静躺在那,但Host那一列全是空字符串

这就是MySQL 8.0埋的一个不大不小的雷。

8.0开始,MySQL默认不上报自己监听的物理IP了,report_host参数默认是空的。这在MHA时代影响不大,因为MHA可以靠SSH或者别的手段拿到主机的IP,但Orchestrator主要靠主库自己汇报,从库信息是从主库的SHOW REPLICAS;结果里拿的,Host字段一空,它就摸不到从库在哪儿了。

正经的解决方案是在每台从库的my.cnf里加:

report_host=192.168.198.202  # 写本机IP

然后重启MySQL。但这种方法有一个前提:IP不能变。如果你们环境是DHCP或者经常漂,那就比较蛋疼。

我当时图省事,直接用了一个更暴力的办法——在Orchestrator的配置里强行注入种子池:

"SeedInjectedPool": "192.168.198.201:3306,192.168.198.202:3306,192.168.198.203:3306",
"HostnameResolveMethod": "none"

加上这两行之后,Orchestrator就不再依赖主库的SHOW REPLICAS;汇报了,而是自己主动拿这三个IP去连、去探活。然后它内部会对每个节点跑SHOW SLAVE STATUS;,比对各个节点的Master_Log_FileRead_Master_Log_Pos,自己把拓扑关系拼出来。

这个方案虽然土,但在内网环境、IP固定的情况下相当好用,不用每台机器都改my.cnf。

第五步:收网验证

配置改完,Orchestrator服务也得重启一下让它读新配置:

sudo systemctl restart orchestrator

然后主动触发一次拓扑发现:

orchestrator -c discover -i 192.168.198.201:3306
orchestrator -c discover -i 192.168.198.202:3306
orchestrator -c discover -i 192.168.198.203:3306

这一步其实就是告诉Orchestrator:"兄弟,起来干活了,这三台机器给你。"

最后再回到浏览器刷新http://管理机IP:3000——

——整个拓扑图终于绿了!

主库kafka-node1稳稳地待在左侧,下方两根绿色的连线分别牵引到kafka-node2和kafka-node3两个从节点,所有状态都是健康的绿色Health状态。之前那一堆橙红色的DeadMaster告警全部消失,图形化的集群状态一目了然。

那一刻,真的有种"养了三个月的娃终于会叫爸爸了"的成就感(bushi)。

写在最后

整套方案折腾下来,最大的感受就是:MHA的时代真的结束了。不是说它不好用,是它真的老了,配套的东西都跟不上了。Orchestrator这种Go语言写的现代化工具,配合Web界面、JSON配置、对MySQL 8.0的原生支持,才是当下的最优解。

这次踩到的几个坑,本质上都是MySQL 8.0相比5.7的一些"小脾气"——比如默认的super_read_onlyreport_host默认值变化、UUID机制等。这些小坑单个看都不大,但堆在一起就足以让人怀疑人生。

如果你们公司也准备从MHA迁到Orchestrator,希望这篇文章能帮你少走点弯路。

如果觉得有帮助,记得点赞、转发、在看走一波,这是对我最大的支持。有问题随时在公众号后台留言,看到都会回复的。

想第一时间收到推送可以关注我的公众号:耕云躬行录,里面都是实打实的运维干货,没啥花里胡哨的东西。

个人博客地址:躬行笔记https://www.fuzhoupyy.work ),内容更系统一些,可以收藏起来慢慢看。

下期准备写Orchestrator的故障切换实战,包括手动切换、自动化切换、切换过程中的数据一致性验证这些,有兴趣的可以先关注一下,别走丢啦~

文章目录

博主介绍

热爱技术的云计算运维工程师,Python全栈工程师,分享开发经验与生活感悟。
欢迎关注我的微信公众号@运维躬行录,领取海量学习资料

微信二维码