GaussDB 集群两节点宕机 CM 不可用:幸存节点绕过 CM 手动拉起数据库实战

GaussDB 集群两节点宕机 CM 不可用:幸存节点绕过 CM 手动拉起数据库实战

wdhlzy
2026-09-07 / 0 评论 / 6 阅读 / 正在检测是否收录...

GaussDB 集群两节点宕机 CM 不可用:幸存节点绕过 CM 手动拉起数据库实战

快速答案:CM 服务不可用时,绕过 CM 直接执行 gs_ctl start -D 数据目录 即可手动拉起数据库;注意 RPO > 0(可能丢数据),操作前需确认业务可接受。

一、故障背景

某 GaussDB 生产集群采用一主两备架构,共三个节点(192.168.204.50、192.168.204.51、192.168.204.52)。突发故障导致 50、51 两个节点同时宕机,集群管理(CM)服务整体不可用,幸存节点 52 上的数据库进程也处于停止状态,业务完全中断。

在 CM 服务不可用的情况下,常规的 cm_ctl 集群级启动命令无法执行,需要绕过 CM,直接在幸存节点上用 gs_ctl 手动拉起数据库进程,先恢复业务,再逐步修复集群。

二、故障现象

  • 50、51 节点宕机,无法正常提供服务
  • CM 服务(CMServer、ETCD)在三个节点上全部处于 Down 状态
  • 幸存节点 52 上的数据库进程(gaussdb)未运行
  • cm_ctl start 命令报错,无法通过 CM 启动数据库

三、应急恢复操作

3.1 加载环境变量

在幸存节点 52 上,切换到数据库安装用户(本例为 Ruby),加载 GaussDB 环境变量:

source env_gauss

3.2 尝试通过 CM 启动(失败)

首先尝试常规方式通过 CM 启动数据库:

cm_ctl start -D /data/cluster/var/lib/engine/data/dn_6001

由于 CM 服务不可用,命令报错:

ERRDETAIL: data/ERRCAUSE: The cmdline entered by the user is incorrect.

3.3 绕过 CM,直接用 gs_ctl 启动

CM 不可用时,直接使用 gs_ctl 命令启动数据库进程,指定数据目录:

gs_ctl start -D /data/cluster/var/lib/engine/data/dn_6001

启动成功,输出如下:

[gs_ctl]: gs_ctl started,datadir is /data/cluster/var/lib/engine/data/dn_6001
[gs_ctl]: waiting for server to start...
[gs_ctl]: done
[gs_ctl]: server started (/data/cluster/var/lib/engine/data/dn_6001)

gs_ctl 启动成功与 CM 状态查询:CMServer 和 ETCD 全部 Down,但数据库已拉起

从截图可以看到,cm_ctl query -Cvid 显示三个节点的 CMServer 和 ETCD 全部处于 Down 状态,cm_ctl 无法连接 cm_server,但数据库进程已经通过 gs_ctl 成功拉起。

四、读写验证

数据库启动后,通过 gsql 连接,执行建表、插入、查询、删除操作,确认数据库可正常读写:

CREATE TABLE test_rw (id int);
INSERT INTO test_rw VALUES (1);
SELECT * FROM test_rw;
--  id
-- ----
--   1
-- (1 row)
DROP TABLE test_rw;

gsql 读写验证:建表、插入、查询、删除全部正常

读写测试通过,数据库可对外提供正常服务。

五、当前集群状态分析

5.1 数据库进程状态

ps -ef | grep gaussdb | grep -v grep

gaussdb 主进程正常运行,数据目录为 /data/cluster/var/lib/engine/data/dn_6001

5.2 HA 状态与主备复制

gs_ctl query -D /data/cluster/var/lib/engine/data/dn_6001

输出:

HA state:
    local_role           : Normal
    static_connections   : 2
    db_state             : Normal
    detail_information   : Normal

Senders info:
No information
Receiver info:
No information

HA 状态查询:local_role 和 db_state 均为 Normal,Senders/Receiver 无信息

关键信息:

  • local_role: Normaldb_state: Normal:数据库实例状态正常
  • Senders info: No informationReceiver info: No information:主备复制链路已断开,没有发送者和接收者
  • 当前 52 节点为独立运行的单点数据库,不再具备高可用能力

六、方案优缺点分析

优点

  • 业务恢复时间短:数据库在数分钟内重新可用,最大限度减少业务中断时间
  • 操作简单:仅需单条 gs_ctl start 命令即可拉起服务,不依赖 CM
  • 不依赖故障节点:在 50、51 节点无法恢复的情况下,仍能通过幸存节点提供服务

缺点与风险

  • 数据丢失(RPO > 0):50、51 节点上已提交但未同步到 52 节点的数据将永久丢失。这是绕过 CM 手动拉起的最大代价,恢复前必须确认业务方可接受数据丢失
  • 单点故障:集群失去高可用能力,当前 52 节点为单点,若再次宕机则服务彻底中断
  • 后续重建成本高:50、51 节点修复后,必须以 52 节点为基准执行全量重建(gs_ctl build),原有数据将被覆盖,重建期间影响性能
  • CM 需手动恢复:CM 服务(CMServer、ETCD)无法自动恢复,需要手动重新启动并重建集群管理

七、后续恢复步骤

业务恢复后,按以下顺序逐步修复集群:

  1. 修复 50、51 节点硬件/系统故障,确保节点可正常启动
  2. 以 52 节点为基准,对 50、51 执行全量重建

    gs_ctl build -D /data/cluster/var/lib/engine/data/dn_6001 -b full
  3. 重建完成后启动 CM 服务,恢复集群管理能力
  4. 验证主备复制状态,确认 Senders/Receiver 信息正常
  5. 执行主备切换测试,确认高可用能力恢复

八、经验总结

  1. CM 不可用时,gs_ctl 是最后手段gs_ctl 直接操作数据库实例,不经过 CM,是 CM 故障时的应急救命命令
  2. 先确认数据可接受丢失再操作:绕过 CM 拉起幸存节点意味着 RPO > 0,必须与业务方确认
  3. 记录数据目录路径gs_ctl start -D 必须指定正确的数据目录,本例为 /data/cluster/var/lib/engine/data/dn_6001
  4. 恢复后第一时间做读写验证:建表、插入、查询、删除,确认数据库真正可用
  5. 应急恢复不等于最终恢复:手动拉起只是临时方案,必须尽快完成节点重建和 CM 恢复,回到高可用状态

常见问题(FAQ)

CM 服务不可用时怎么启动数据库?

绕过 CM,直接在幸存节点执行 gs_ctl start -D 数据目录,即可手动拉起数据库进程。

手动拉起会丢数据吗?

会。宕机节点上已提交但未同步到幸存节点的数据将永久丢失(RPO > 0),操作前必须确认业务方可接受。

手动拉起后集群还能恢复高可用吗?

可以。故障节点修复后,以幸存节点为基准执行 gs_ctl build -b full 全量重建,再启动 CM 服务即可恢复。

gs_ctl 和 cm_ctl 有什么区别?

gs_ctl 直接操作数据库实例,不依赖 CM;cm_ctl 是集群级命令,需要 CM 服务正常运行。CM 故障时只能用 gs_ctl。

怎么验证数据库恢复正常?

用 gsql 连接,执行建表、插入、查询、删除操作确认读写正常;再用 gs_ctl query 查看 HA 状态。

\n

2

评论

博主关闭了所有页面的评论