数据库高可用:MySQL主从复制、MHA、Orchestrator、Galera Cluster
数据库高可用这个话题,说简单也简单,说复杂能把人绕进去。
我见过不少团队,买几台服务器搭个主从复制就觉得万事大吉了。
结果主库一挂,从库还卡在 relay log 里,业务直接挂了半小时。
今天咱们就把这块掰开揉碎了讲。
从最基础的主从复制开始,再到自动故障转移工具 MHA、Orchestrator,最后聊聊 Galera Cluster 这种多点写入的方案。
1. 主从复制,逃不掉的基础
MySQL 主从复制,说白了就是主库把 binlog 推给从库,从库按顺序回放。
常见的异步模式,主库写完 binlog 就返回客户端,不关心从库收没收到。
半同步的话,至少要一个从库确认收到 binlog,主库才会 commit。
我习惯在线上用 半同步 + GTID 的组合。
GTID 能让你清楚地知道每个事务的全局 ID,切换的时候不会丢数据。
核心配置要点
- 主库开 binlog,设置 server-id,开 GTID
- 从库配置 change master to,指定主库的 GTID_PURGED
- 开启半同步插件 rpl_semi_sync_master/slave
-- 主库
SET GLOBAL gtid_mode=ON;
SET GLOBAL enforce_gtid_consistency=ON;
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
SET GLOBAL rpl_semi_sync_master_enabled=1;
-- 从库
CHANGE MASTER TO
MASTER_HOST='10.0.1.10',
MASTER_USER='repl',
MASTER_PASSWORD='xxx',
MASTER_AUTO_POSITION=1;
START SLAVE;
⚠️ 记住一点:从库的 server-id 不能和主库重复,否则 binlog 会混乱。
我曾经碰到过有人两台机器配了相同 ID,导致数据错乱,查了半天才定位到。
2. MHA,经典的自动故障转移
MHA(Master High Availability)是日本人写的工具,挺老牌了。
它的思路是:部署一个 Manager 节点,持续监控主库。当主库挂了,挑一个最新数据的从库做新主,然后让其他从库重新指向新主。
工作流程大致这样:
- Manager 检测到主库不可用
- 从所有从库中选一个 relay log 最完整的作为候选
- 把其他从库缺失的 relay log 补到候选节点上
- 候选节点 apply 完所有 relay log 后提升为新的主库
- 剩余从库 change master to 新主库
- 可选:漂移虚拟 IP(VIP)对外提供服务
我曾经在生产环境用 MHA,遇到过一个大坑:relay log 补不全。
原因是某个从库的 relay log 已经损坏,MHA 没办法从那里拿日志。后来我调整了配置,开启 relay_log_purge=0,并定期备份 relay log,才解决问题。
MHA 的配置比较简单,需要写一个配置文件,里面写明所有节点信息。
[server default]
manager_workdir=/var/log/mha
manager_log=/var/log/mha/manager.log
ssh_user=root
repl_user=repl
repl_password=xxx
ping_interval=3
[server1]
hostname=10.0.1.10
candidate_master=1
[server2]
hostname=10.0.1.11
candidate_master=1
[server3]
hostname=10.0.1.12
no_master=1
注意 candidate_master 和 no_master 的用法。
MHA 虽然稳定,但有个硬伤:它自己不是高可用的。Manager 挂了就没人管切换了。你需要另外跑一份备用 Manager 或者用 Keepalived 做 VIP。
3. Orchestrator,现代化的拓扑管理
Orchestrator 是近几年比较火的方案,它有 Web 界面,能展示集群拓扑,支持自动/手动切换。
最让我喜欢的是它的 Raft 一致性协议——Orchestrator 自身可以组成 3 或 5 节点的 Raft 集群,不会单点挂。
对比 MHA 的优势:
| 维度 | MHA | Orchestrator |
|---|---|---|
| 自身高可用 | 需手动实现 | 自带 Raft 集群 |
| 切换方式 | 自动 + 手动 | 自动 + 手动 + API |
| 可视化 | 无 | Web 拓扑图实时展示 |
| 数据丢失风险 | relay log 补不全会丢 | 通过 GTID 保证一致性 |
| 部署复杂度 | 较低 | 中等(需要 Raft 环境) |
部署 Orchestrator 需要先在每台机器上跑一个 agent 或者直接暴露 MySQL 的端口给 Orchestrator 节点。
它通过解析 SHOW SLAVE STATUS 和 SHOW MASTER STATUS 来构建拓扑图。
# 重要配置项
"Topology": "gtid",
"DetectClusterAliasQuery": "SELECT IFNULL(@@global.port,3306)",
"MasterFailoverDetectInterval": 5,
"RecoveryPeriodBlockSeconds": 60
嗯,这里要注意:Orchestrator 的自动恢复策略比较激进,建议先在测试环境调好 RecoveryPeriodBlockSeconds,避免网络抖动导致频繁切换。
曾经踩过的坑:有一次我把 Orchestrator 部署在低配机器上,Raft 集群之间心跳超时,Orchestrator 误判网络分区,触发自动切换。结果把整个集群的主库踢了一遍,业务中断了好几分钟。所以 Orchestrator 节点本身一定要稳定,且网络延迟要低。
4. Galera Cluster,同步复制多点写入
Galera Cluster 是 Percona XtraDB Cluster(PXC)和 MariaDB Galera 的核心技术。
它最大的特点是:所有节点都可以写入,而且数据是同步的——事务只要在一台节点 commit 了,其他节点肯定也能读到。
为什么能做到?
Galera 用了 certification-based replication:每个节点在 commit 之前,会把写集广播给所有节点,所有节点做认证检查,通过就一起 commit,否则 rollback。
这种机制带来几个限制:
- 写入性能受最慢节点的影响(全同步嘛)
- 网络要求高—延迟抖动可能导致流控
- 不支持 MyISAM,只支持 InnoDB
- 表必须有主键,否则同步会出问题
# 典型配置 /etc/my.cnf
[mysqld]
wsrep_provider=/usr/lib64/galera/libgalera_smm.so
wsrep_cluster_address="gcomm://10.0.1.10,10.0.1.11,10.0.1.12"
wsrep_node_name="node1"
wsrep_node_address="10.0.1.10"
wsrep_cluster_name="mycluster"
wsrep_sst_method=xtrabackup-v2
wsrep_sst_auth="sst_user:password"
启动集群的方式要记住:第一台节点用 --wsrep-new-cluster 启动,后面加入的节点正常 start 就行。如果搞反了,会报错说找不到集群。
选型建议:
- 如果业务能接受秒级的故障转移,数据一致性要求没那么高,主从复制 + MHA/Orchestrator 就够了
- 如果要求强一致性,而且允许写入量中等(比如几百 QPS),Galera 很合适
- 别把 Galera 放在跨地域的节点上,网络延迟会搞死你
5. 总结一下我的选择思路
个人习惯:
- 小团队、单机房、对运维能力要求不高 → 主从 + Orchestrator(因为 Orchestrator 有 UI,切换透明)
- 传统企业、已有 MHA 积累 → 继续用 MHA,但注意补 relay log 的坑
- 互联网金融、要求强一致、写并发不高 → Galera Cluster 或者 Percona XtraDB Cluster
- 超大规模集群、复杂拓扑 → Orchestrator 配合 MySQL 8.0 的组复制(Group Replication)