MySQL InnoDB Cluster 日常运维与故障场景 (MySQL Shell 8.4)
MySQL难度: 高级耗时: 5 分钟(检查)– 1 小时(添加成员)不是安装指南:针对已在运行的 InnoDB Cluster(Group Replication + MySQL Router,通过 MySQL Shell AdminAPI 搭建)的日常运维和故障恢复,按场景组织的 runbook。选择一个场景卡片:健康检查、添加成员(clone / incremental)和移除成员(含 force)、让掉线成员重新加入、整个集群停机后重新启动 (rebootClusterFromCompleteOutage)、多数派丢失时使用 forceQuorumUsingPartitionOf、计划内切换 primary、添加 Router / 重新 bootstrap、集群选项(consistency、expelTimeout、memberWeight、autoRejoinTries、exitStateAction)以及用 rescan() 处理元数据。每个场景都按 诊断 → 安全措施 → 执行 → 验证 → 后续 的顺序组织。如果是首次搭建集群,请打开 InnoDB Cluster 安装指南;经典 source–replica 复制请看复制运维指南;8.0 → 8.4 迁移请看升级指南。
架构: 3–9 个 MySQL 节点 (single-primary) + MySQL Router
场景
- 集群状态与健康检查(一切正常吗?) — 只读:cluster.status({extended: 1})、成员的角色/状态/版本、应用队列、Router 列表和 error log;不做任何更改,不停机。如果不确定或收到告警,请从这里开始;最后一步会把您引导到正确的场景。
- 添加新成员 (addInstance: clone / incremental) — 您想向集群添加一个新的 MySQL 节点、提高容错能力 (3 → 5),或重新加入一个已被移除的节点。集群保持可写;clone 期间 donor 上会产生磁盘/网络负载,新节点会重启。
- 移除成员 (removeInstance,必要时 force) — 您想把某个节点永久移出集群(硬件退还、缩容),或者节点已丢失,需要从元数据中删除 (force)。移除 secondary 不会停机;移除 primary 会有几秒钟的写入中断。
- 让掉线成员重新加入 (MISSING / ERROR / OFFLINE) — 某个成员重启过、经历了网络中断,或被逐出组 (expelled);多数派仍在运行,应用可以写入。通过 rejoinInstance,该成员补齐缺失的事务后重新加入;集群不会停机。
- 整个集群已停机:重新启动 (rebootClusterFromCompleteOutage) — 由于断电 / 数据中心 / hypervisor 故障等原因,所有节点都关闭后又启动;Group Replication 在任何成员上都没有运行,应用无法写入(停机仍在持续)。集群从数据最新的成员重新启动。
- 多数派丢失 (NO_QUORUM):用剩余成员强制建立 quorum — 大多数成员同时丢失(例如 3 个中的 2 个),剩余成员以 NO_QUORUM 停止写入(写入挂起)。如果确定丢失的成员确实已关闭,则用剩余分区重新运行集群。使用不当会造成 split-brain;只丢失一个成员(多数派仍在)不属于此场景。
- 计划内切换 primary (setPrimaryInstance) — 为了维护(OS 补丁、硬件)、负载均衡或 DR 演练,您想把 primary 角色计划内地移交给指定的 secondary。写入会等待几秒钟,已打开的事务会被完成;Router 会自动路由到新的 primary。
- 添加 Router 或重新 bootstrap — 您想在新的应用服务器上安装 Router、重新 bootstrap Router(版本升级、集群重建、routerErrors 警告),或清理旧的 Router 记录。重新 bootstrap 期间,连接到该 Router 的应用连接会短暂断开。
- 修改集群选项(consistency、expelTimeout、memberWeight…) — 您想调整 failover 一致性、网络抖动时逐出成员的时间、failover 优先级、自动重新加入,或出错时成员的行为。在集群运行时修改,无需重启;consistency 对新会话生效。
- 使元数据与实际组一致 (rescan) — cluster.status() 提到一个不在元数据中的成员,或一条已不在组中的旧记录(手动执行过 START GROUP_REPLICATION、旧成员未删除、服务器被重装)。不停机;只更新元数据。
开始之前
- 要操作的节点上已安装 MySQL Shell … 和 MySQL …;集群是按 InnoDB Cluster 安装指南或等效方式通过 AdminAPI 搭建的(存在元数据)。操作系统 root 可以用本地 mysql 无口令连接。表单中的集群名称从 dba.getCluster().getName() 获取,成员地址从 cluster.status() 拓扑中的 ip:port 行获取。
- 已知 … 账户的口令(每个节点相同)。MySQL Shell 每次连接都提示输入口令;通过 --save-passwords=never 不保存口令。
- 节点之间可以通过 MySQL 端口(……:……, ……)和 Group Replication 通信端口互相访问。
- 新节点上安装的 MySQL … 与集群成员小版本相同(clone 的前提),GTID 已开启,server_id 与其他节点不同,安装指南中的 Group Replication 设置已写入 my.cnf;firewall/SELinux 端口已开放。
- Router 服务器可以通过 MySQL 端口访问各节点…,并且可以访问 repo.mysql.com…。
- 变更审批、维护窗口(如需要)以及与应用团队的沟通均已就绪。
指南阶段
- 状态:集群、成员和 Router(只读) — 获取并保存详细的集群状态 · 用 SQL 检查成员和队列 · 扫描 Group Replication 错误记录 · 检查通过 Router 的 RW/RO 路由 · 解读结果并选择正确的场景
- 1. 诊断:新节点和集群是否就绪? — 检查新节点的版本和标识 · 检查集群状态和成员版本
- 2. 安全措施 — 保存当前拓扑
- 3. 执行:添加成员 — 配置新节点并创建管理员账户 · 从集群一侧检查新节点是否合格 · 把节点加入集群 (…)
- 4. 验证 — 确认新成员为 ONLINE
- 5. 后续 — 更新 Router、监控和资产清单
- 1. 诊断:移除该成员是否安全? — 显示目标成员的状态和剩余容错能力
- 2. 安全措施 — 保存当前拓扑
- 3. 执行:移除成员 — 把成员移出集群… (force)…
- 用 force 移除的节点恢复时 — 在恢复的节点上停止并清除 Group Replication
- 4. 验证 — 验证剩余成员
- 5. 后续 — 奇数成员、Router 与监控
- 1. 诊断:成员为什么掉线,能否重新加入? — 从集群视角查看目标成员的状态 · 显示目标节点上 MySQL 和 Group Replication 的状态 · 检查 errant 事务(目标上有而集群中没有的)
- 2. 安全措施 — 保存当前状态
- 3. 执行:让成员重新加入 — 用 rejoinInstance 让成员重新加入
- 4. 验证 — 确认成员为 ONLINE
- 5. 后续 — 根本原因与自动重新加入
- 1. 诊断:整个集群是否真的已关闭,哪个成员数据最新? — 在每个节点上启动 MySQL 并显示 Group Replication 状态 · 让 Shell 找出数据最新的成员 (dryRun)
- 2. 安全措施 — 保存所有节点的 GTID 集合
- 3. 执行:从数据最新的成员启动集群 — 重新启动集群
- 4. 验证 — 确认所有成员为 ONLINE
- 5. 后续 — Router、应用与根本原因
- 1. 诊断:quorum 是否真的丢失? — 从存活节点显示集群状态
- 2. 安全措施:隔离丢失的成员 — 确认丢失的节点已关闭 (fencing) · 保存剩余分区的状态
- 3. 执行:强制建立 quorum — 用剩余分区建立 quorum
- 4. 验证并找回丢失的成员 — 确认已恢复写入 · 让丢失的成员重新加入 (…)
- 5. 后续 — 复查拓扑
- 1. 诊断:目标是否适合成为 primary? — 检查成员的状态和版本
- 2. 安全措施 — 保存当前状态
- 3. 执行:切换 primary — 把 primary 角色移交给 …