14_MySQL 高可用与容灾架构 —— MGR / InnoDB Cluster / Keepalived+VIP / 双主 / 读写分离 / 两地三中心

14_MySQL 高可用与容灾架构 ------ MGR / InnoDB Cluster / Keepalived+VIP / 双主 / 读写分离 / 两地三中心

系列定位 :《MySQL 数据库全栈运维实战系列》第 14 篇,与《Oracle 数据库全栈运维实战系列(VMware 版)》同构对标(Oracle 14 高可用容灾:RAC + DG)。适用版本 :MySQL 8.0(5.7 差异随文标注)。官方文档:MySQL 8.0 Reference Manual、Group Replication / InnoDB Cluster / MySQL Router 章节。
衔接说明 :第 13 篇已在 VMware 虚机上完成 GTID 主从复制与 InnoDB Cluster 双节点部署(系列核心篇)。本篇不再重复部署细节,而是把已部署的组件体系化:从"能用的主从"升级为"可切换、可读写分离、可容灾"的高可用架构,并与 Oracle RAC / DG 的能力做同编号对照。


一、高可用与容灾全景(一张图看懂)

图 1

层次 组件 类比 Oracle 解决的问题
接入层 Keepalived+VIP / MySQL Router / ProxySQL SCAN VIP / Listener 故障切换 应用连哪个地址、主挂了自动切
同城高可用 InnoDB Cluster(MGR 单主) RAC 节点 实例级故障、秒级自动选主
数据复制 组复制 vs 异步复制 RAC Cache Fusion vs DG Redo 传输 强一致 vs 异地容灾
异地容灾 异地灾备库(异步复制) Data Guard 机房级故障、城市级灾难

核心差异 :Oracle 用 RAC(共享存储 + Cache Fusion)做同城高可用,用 Data Guard(Redo 传输)做异地容灾;MySQL 没有共享存储集群 ,高可用全部基于复制实现------MGR 提供强一致组复制(对标 RAC 的"节点故障自动切换"),异地 binlog 异步复制对标 DG。


二、高可用方案选型对比

方案 一致性 切换方式 RTO 适用规模 类比 Oracle
异步主从(GTID) 最终一致 手动 / 脚本 分钟级 读多写少、可接受少量延迟 DG 最大性能模式
半同步复制 接近强一致 手动/脚本 秒级~分钟级 数据不能丢的场景 DG 最大可用模式
Keepalived+VIP 双主/主从 依赖底层复制 VRRP 自动漂移 秒级 中小规模、单机主从 Listener 切换
MGR 单主(InnoDB Cluster) 强一致(Paxos) 自动选主 秒级 中大规模、高可用核心 RAC 节点故障切换
MGR 多主 强一致(冲突检测) 无主概念 秒级 极少用(写冲突风险) ---
两地三中心 同城强一致 + 异地异步 同城自动、异地手动 同城秒级/异地分钟级 金融级 RAC + DG 组合

选型结论 :生产核心库优先 InnoDB Cluster(MGR 单主) ;对成本敏感且可接受手动切换的,用 GTID 主从 + Keepalived+VIP ;异地容灾一律在 MGR/主从基础上额外挂一个异地异步从库(MGR 组内不做跨城,跨城用异步复制)。


三、环境准备(VMware 虚机)

节点 角色 建议配置 用途
db1 / db2 / db3 MGR 三节点 4C8G / 100G 同城集群(至少 3 节点才能容忍 1 节点故障)
dr1 异地灾备 4C8G / 100G 异地异步从库(另一 VMware 宿主/数据存储)
接入节点 MySQL Router / ProxySQL / Keepalived 2C4G 可与应用同机或独立

VMware 注意事项 (高可用专题重点):1. 节点必须分布在不同宿主机/数据存储 :MGR 三节点若跑在同一 ESXi 宿主机上,宿主机宕机 = 集群全灭,失去高可用意义。生产演练至少保证 db1/db2 在不同 ESXi。2. 时间同步强制 :组复制对时间敏感,所有虚机必须开 VMware Tools 时间同步(或配置 chrony/NTP 指向同一 NTP),时间偏差过大会导致选主异常、GTID 混乱。3. 网卡模式与 IP :Keepalived 的 VIP 需要桥接/仅主机网段支持二层广播(VRRP 多播 224.0.0.18),NAT 模式下 VRRP 多播可能不通,建议用桥接或自定义网段。4. 磁盘控制器/IO :MGR 三节点并发写盘,建议厚置备(thick eager zeroed)或 SSD 直通,避免 thin 置备在写放大时抖动影响组提交。5. 快照回滚坑 :对已加入 MGR 的节点做 VMware 快照再回滚,会导致 GTID 位点与组内不一致,必须 RESET MASTER 后重新 clone 加入,切勿直接回滚快照当恢复手段。6. 内存预留:生产建议给虚机预留全部内存(Reservation),避免 ballooning 导致 MySQL 被回收触发组复制超时。

复制代码
# /etc/my.cnf(MGR 三节点公共配置,差异项用 server_id 区分)
[mysqld]
server_id = 1                            -- 解释:每个节点唯一,db1=1 db2=2 db3=3
gtid_mode = ON                           -- 解释:MGR 强制开启 GTID(对标 Oracle DG 强制归档)
enforce_gtid_consistency = ON
log_bin = mysql-bin
binlog_format = ROW                      -- 解释:组复制要求 ROW
binlog_row_image = FULL
log_replica_updates = ON                 -- 解释:8.0 从库也要写 binlog(5.7 为 log_slave_updates)
transaction_write_set_extraction = XXHASH64  -- 解释:写入集提取,冲突检测依赖
loose-group_replication_group_name = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"  -- 解释:必须是合法 UUID,全组一致
loose-group_replication_local_address = "192.168.10.51:33061"  -- 解释:组通信地址,每节点改 IP
loose-group_replication_group_seeds = "192.168.10.51:33061,192.168.10.52:33061,192.168.10.53:33061"
loose-group_replication_start_on_boot = OFF   -- 解释:先手动启动,避免开机自动加入造成脑裂
loose-group_replication_ single_primary = ON   -- 解释:单主模式(8.0 实际参数名为 group_replication_single_primary_mode)

四、MGR 单主集群原理与实操(官方:Group Replication)

4.1 组复制选主流程

图 2

关键约束 :MGR 需要多数派 (3 节点容忍 1 节点故障;5 节点容忍 2 节点故障)。2 节点集群不满足容错------挂任何一个都凑不齐多数派,集群整体只读,这是与 Oracle RAC(2 节点可正常工作)的重要差异。

4.2 启动组复制(节点 1)

复制代码
-- ① 安装插件(解释:group_replication 插件只需装一次)
INSTALL PLUGIN group_replication SONAME 'group_replication.so';

-- ② 创建复制账号(解释:组复制内部通信账号,全组一致)
SET SQL_LOG_BIN = OFF;
CREATE USER 'rpl_user'@'%' IDENTIFIED BY 'Rpl@Pass2026';
GRANT REPLICATION SLAVE ON *.* TO 'rpl_user'@'%';
SET SQL_LOG_BIN = ON;

-- ③ 配置单主引导(解释:仅主节点执行,其余节点不执行 BOOTSTRAP)
SET GLOBAL group_replication_bootstrap_group = ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group = OFF;

4.3 从节点加入(节点 2、3)

复制代码
-- ① 同样安装插件、建账号(解释:账号密码与主节点一致)
INSTALL PLUGIN group_replication SONAME 'group_replication.so';

-- ② 用 GTID 自动定位复制源(解释:8.0 推荐 CHANGE REPLICATION SOURCE 语法,5.7 为 CHANGE MASTER)
CHANGE REPLICATION SOURCE TO
    SOURCE_USER='rpl_user',
    SOURCE_PASSWORD='Rpl@Pass2026',
    SOURCE_HOST='192.168.10.51',
    SOURCE_PORT=3306,
    SOURCE_AUTO_POSITION=1;          -- 解释:GTID 自动位点,无需手动 file/pos

-- ③ 启动组复制(解释:不做 BOOTSTRAP,直接加入已有组)
START GROUP_REPLICATION;

4.4 验证组状态

复制代码
-- 查看集群成员(解释:performance_schema.replication_group_members 是 MGR 第一视图)
SELECT MEMBER_ID, MEMBER_HOST, MEMBER_PORT, MEMBER_STATE, MEMBER_ROLE
FROM performance_schema.replication_group_members;
-- 预期输出:3 行,主为 PRIMARY,其余为 SECONDARY,状态均为 ONLINE

-- 查看主库当前可写(解释:单主模式下仅 PRIMARY 接受写)
SHOW STATUS LIKE 'group_replication_single_primary_mode';
SHOW STATUS LIKE 'group_replication_primary_member';

五、InnoDB Cluster:MGR + MySQL Shell + MySQL Router(官方:InnoDB Cluster)

InnoDB Cluster = 用 MySQL Shell 的 dba API 把上述 MGR 集群托管化 ,再用 MySQL Router 做自动连接路由------这是官方推荐的高可用成品方案,对标 Oracle RAC + SCAN 服务。

图 3

端口 用途 类比 Oracle
6446 读写连接(自动路由到当前主) SCAN 服务(读写)
6447 只读连接(路由到 Secondary) 只读服务
64460 Router 元数据 ---
复制代码
# ① MySQL Shell 创建集群(解释:在主库上执行,相当于把 MGR 封装成 Cluster)
mysqlsh --uri root@192.168.10.51:3306
# JS 模式下:
#   var cluster = dba.createCluster('prodCluster');
#   cluster.addInstance('root@192.168.10.52:3306');   -- 自动 clone 数据后加入
#   cluster.addInstance('root@192.168.10.53:3306');

# ② 引导 MySQL Router(解释:--bootstrap 自动从集群元数据读拓扑)
mysqlrouter --bootstrap root@192.168.10.51:3306 --directory=/usr/local/mysqlrouter
# ③ 启动 Router
mysqlrouter -c /usr/local/mysqlrouter/mysqlrouter.conf &

故障切换自动生效 :主库宕机后,MGR 自动选新主,MySQL Router 每隔几秒从元数据刷新拓扑,把 6446 的新连接路由到新主。应用无需改连接串------这正是它对标 SCAN VIP 的核心价值。

复制代码
-- 验证集群状态(解释:mysqlsh 里执行 cluster.status() 等价查询)
SELECT * FROM mysql_innodb_cluster_metadata.clusters\G

六、Keepalived + VIP 方案(轻量主从,对标 Listener 切换)

对未上 InnoDB Cluster 的中小主从,用 Keepalived 给主库挂一个 VIP,主库宕机时 VIP 自动漂到从库。

图 4

复制代码
# /etc/keepalived/keepalived.conf(主库)
vrrp_script chk_mysql {
    script "/etc/keepalived/check_mysql.sh"   # 解释:检测 3306 是否存活
    interval 2
    weight -20
}
vrrp_instance VI_1 {
    state MASTER                              # 解释:从库填 BACKUP
    interface ens33
    virtual_router_id 51
    priority 100                              # 解释:从库 90
    advert_int 1
    virtual_ipaddress {
        192.168.10.100                        # 解释:应用连接的固定 VIP
    }
    track_script { chk_mysql }
}

# /etc/keepalived/check_mysql.sh(解释:mysql 探测失败则降优先级触发漂移)
#!/bin/bash
mysql -uroot -p"$MYSQL_PWD" -e "SELECT 1" >/dev/null 2>&1 || exit 1
exit 0

坑提醒 :VIP 漂移只是把 IP 切过去,从库此时未必已提升为主 (只读)。生产上必须在 notify_master 脚本里自动 STOP REPLICA; RESET MASTER; 提升从库为可写,否则应用连上的是只读库。这个"VIP 漂了但库还只读"是 Keepalived 方案最常见的事故。


七、读写分离架构

图 5

实现方式 原理 适用
应用层路由 代码里 master/slave 数据源 简单、耦合代码
MySQL Router 6446 写 / 6447 读 官方、零业务侵入
ProxySQL 基于规则路由(见第 16 篇) 复杂规则、缓存、审计
复制代码
-- 从库只读设置(解释:读写分离下从库必须只读,防止误写)
SET GLOBAL super_read_only = ON;     -- 8.0:连 SUPER 权限也禁止写
SHOW VARIABLES LIKE 'read_only';

复制延迟问题:读写分离最大的坑是"刚写主库、立刻读从库读不到"。方案:① 关键事务后强制走主库读(hint);② 监控复制延迟,延迟大时把该从库从读池摘除(见第 17/19 篇告警);③ 半同步复制降低延迟窗口。


八、两地三中心(金融级容灾)

图 6

中心 角色 复制方式 恢复目标
主数据中心 生产 MGR 强一致 实例故障秒级切换
同城备份中心 同城容灾 组内成员 / 半同步 机房故障 RTO 分钟级
异地灾备中心 异地容灾 异步 binlog 城市级灾难 RTO 小时级、RPO 秒~分钟

MGR 不建议直接跨城 :组通信跨城市延迟(>5ms)会拖慢组提交、降低吞吐。跨城一律用异步复制单独维护一个异地从库,平时只读/备份,灾难时手动提升(对标 Oracle DG 切换需要 DBA 介入)。

复制代码
-- 异地灾备库配置(解释:异地从库挂在主库下做异步复制,与 MGR 组独立)
CHANGE REPLICATION SOURCE TO
    SOURCE_HOST='192.168.10.51',
    SOURCE_USER='rpl_user',
    SOURCE_PASSWORD='Rpl@Pass2026',
    SOURCE_AUTO_POSITION=1;
START REPLICA;

九、高可用切换演练(验收动作)

复制代码
-- ① 模拟主库宕机(在主库)
-- mysqladmin -uroot shutdown

-- ② 在任一存活节点查新主(解释:30 秒内自动选出新 PRIMARY)
SELECT MEMBER_HOST, MEMBER_ROLE, MEMBER_STATE
FROM performance_schema.replication_group_members
WHERE MEMBER_ROLE = 'PRIMARY';

-- ③ 验证新主可写、旧主恢复后可重新加入
-- 旧主重启后:START GROUP_REPLICATION;(自动追赶并作为 SECONDARY 加入)

十、要点速记

  1. MySQL 没有共享存储集群,高可用全部基于复制:MGR(强一致)+ 异地异步(容灾)。
  2. MGR 至少 3 节点才能容忍 1 节点故障,2 节点凑不齐多数派、故障即只读。
  3. InnoDB Cluster = MGR + MySQL Shell + MySQL Router,6446 写 / 6447 读,应用零改连接串(对标 SCAN)。
  4. Keepalived+VIP 只是漂 IP,必须配合脚本把从库提升为可写,否则漂过去是只读库。
  5. 两地三中心:同城用 MGR 强一致、异地用异步 binlog;MGR 不直接跨城(网络延迟拖慢组提交)。
  6. VMware 上高可用的前提:节点分散到不同 ESXi、NTP 同步、VRRP 二层网络、禁止对集群节点直接快照回滚。

十一、踩坑记录(实测汇总)

# 坑 现象 解决
1 2 节点 MGR 挂一台后整组只读 扩到 3 节点,保证多数派
2 节点都在同一 ESXi ESXi 宕机全组灭 节点分散到不同宿主机
3 时间不同步 选主异常、GTID 混乱 开 chrony + VMware Tools 时间同步
4 VRRP NAT 网段不通 VIP 不漂移 改桥接/自定义网段,放行 224.0.0.18
5 VIP 漂了但从库只读 应用连上只读库报错 notify_master 脚本里自动提升从库
6 log_replica_updates 没开 从库无法加入组复制 8.0 开 log_replica_updates(5.7 log_slave_updates)
7 直接 VMware 快照回滚节点 GTID 与组内不一致 RESET MASTER 后重新 clone 加入
8 异地从库挂在组内 跨城延迟拖垮组提交 异地走独立异步复制,不进组
9 read_only 忘开 误写从库 从库统一 super_read_only=ON
10 内存被 ballooning 组复制超时断连 虚机预留全部内存
11 group_replication_local_address 写错端口 组通信起不来 确认 33061 组通信端口互通
12 多主模式写冲突 同行并发写报错 生产用单主,多主仅特殊场景

十二、参考资料(官方正式文档)

主题 官方链接
MySQL 8.0 Reference Manual https://dev.mysql.com/doc/refman/8.0/en/
Group Replication https://dev.mysql.com/doc/refman/8.0/en/group-replication.html
InnoDB Cluster https://dev.mysql.com/doc/mysql-shell/8.0/en/mysql-innodb-cluster.html
MySQL Router https://dev.mysql.com/doc/mysql-router/8.0/en/
Replication(异步/半同步) https://dev.mysql.com/doc/refman/8.0/en/replication.html
GTID 格式与配置 https://dev.mysql.com/doc/refman/8.0/en/replication-gtids.html

本文章属于《MySQL 数据库全栈运维实战系列》高可用架构篇。欢迎收藏、交流。

相关推荐
freejackman19 分钟前
【实战三】撕开脱敏盲区:深度解析 CASE WHEN 与窗口函数血缘
大数据·数据库·sql
猿人谷26 分钟前
Surrogate Model:让进化算法学会“预测”,为什么它正在成为智能优化的重要技术?
后端·算法·架构
Kari111 小时前
企业级智能体平台怎么选:腾讯云ADP与其他主流技术路线的架构对比
架构·云计算·腾讯云
泯泷1 小时前
AI时代,中层还要替公司传多少次话?
人工智能·架构
Dawson Zhu1 小时前
【LLM推理与Serving⑧】多机多卡Serving:TP/PP/负载均衡与弹性扩缩容全攻略
人工智能·语言模型·架构·aigc·agi
木子欢儿2 小时前
国内 macOS/Linux 安装 rust
linux·运维·服务器·macos·rust
迪菲赫尔曼2 小时前
【基础篇 26】第一次在服务器完成训练:准备数据、断线继续、检查成果与备份
运维·服务器·人工智能·机器学习·计算机视觉
进击的荆棘2 小时前
Linux系统——线程同步与互斥
linux·运维·服务器·策略模式·同步·互斥·posix
.道阻且长.2 小时前
Linux基本开发工具:gdb和cgdb的使用
linux·运维·服务器·开发语言