【GaussDB集群起不来的时候,我在cm_agent上卡了两个小时】

📅 2026/7/8 6:07:56
【GaussDB集群起不来的时候,我在cm_agent上卡了两个小时】
引言上周生产环境一套GaussDB集群重启后GTM状态显示Unknowncm_ctl query -Cvpd一看是cm_agent退出了。折腾了两小时才定位到根因——运维同事之前手动kill了一个僵尸进程不小心把cm_agent也带下去了而om_monitor当时刚好在执行周期检测的间隔期cm_agent在那几十秒窗口内没被及时拉起导致本节点GTM心跳中断cm_server判定该节点异常触发了一连串状态告警。这件事让我意识到对GaussDB架构和启动流程的理解不能只停留在文档层面——你得知道看护链条怎么运作、每个组件挂了什么症状、怎么快速定位。这篇文章把GaussDB的六个核心组件和启动流程掰开揉碎了讲都是踩过坑之后的心得。一、六个组件不是背定义而是要知道它挂了会怎样我刚接触GaussDB的时候看文档记了一堆缩写OM、CM、GTM、ETCD、CN、DN。但真正用到生产环境里才发现光知道定义没用你得知道每个组件的职责边界在哪里、它挂了会触发什么连锁反应、恢复需要多久。下面按这个思路重新梳理。1.OM:运维入口平时用得多关键时刻靠不住OM运维入口平时用得多关键时刻靠不住OMOperation Manager集成了一堆运维工具gs_om -t start/stop/restart/status这些日常命令都走它。但注意一个细节OM本身不参与集群的高可用仲裁。也就是说OM进程挂了不会影响数据库业务只是你暂时没法用gs_om命令了。这时候可以直接调用底层的cm_ctl来操作所以生产环境里OM挂了不慌先保证业务再修OM。2.CM真正干活的管理层分三个子模块CM是整个集群管理的核心拆开看有三个进程在跑cm_server—— 集群里只有一个主主备架构。它做的事情很简单收集所有实例的心跳 → 存到ETCD → 分析状态 → 决定谁做主谁做备 → 下发切换指令。cm_server挂了会怎样备cm_server会在心跳超时后默认大约几十秒自行仲裁升主优先选节点号小的那个备。只要ETCD多数派还在切换就能完成。cm_server切换期间集群管理功能暂停但数据库读写不受影响——这是很多人误解的地方以为cm_server挂了数据库就挂了其实不影响。cm_agent—— 每个节点一个是cm_server的手脚。它干两件事一是定时采集本节点所有实例GTM、CN、DN的状态上报给cm_server二是接收cm_server下发的指令去启停实例、做主备切换。cm_agent挂了本节点的所有实例就失联了——cm_server收不到心跳会判定这些实例状态异常可能触发不必要的主备切换。所以cm_agent的优先级最高由om_monitor专门看护。om_monitor—— 一个定时任务进程唯一职责就是看护cm_agent。cm_agent死了它负责拉起它自己死了由系统crontab负责拉起。这个三级看护链条crontab → om_monitor → cm_agent → 实例是GaussDB自愈机制的底座缺一不可。3.GTM全局事务ID发号器挂了会影响写操作GTM负责生成全局事务IDGXID、全局快照、时间戳。分布式事务开始时CN会先向GTM申请一个全局事务ID然后才能往下执行。所以GTM挂了的影响是新事务无法启动读写操作都会卡住。但已有的事务不受影响可以继续执行完。GTM也是主备架构主挂了会切备优先切高优先级AZ的备。切换过程一般需要几秒到十几秒。实际生产中如果业务对中断时间敏感建议部署多个GTM备机分散在不同AZ。4.ETCD集群状态的账本多数派没了集群停摆ETCD存了所有组件的实时状态谁主谁备、各实例的心跳信息、集群拓扑配置。cm_server做仲裁决策时所有判断依据都从ETCD读。所以ETCD是GaussDB最不能挂的组件它的优先级甚至高于cm_server。ETCD内部用raft算法实现分布式一致性。关键点ETCD集群必须有奇数个节点3个、5个等才能形成多数派需要额外规划一个仲裁AZAZ3作为仲裁AZ在1个AZ故障状态下保证ETCD的存活节点超过多数从而保障数据库集群仍可正常仲裁ETCD leader挂了follower会发起投票获得多数票的升主如果ETCD多数派节点同时挂了整个集群管理功能冻结cm_server无法做任何仲裁决策5.CNSQL入口挂了不影响读已缓存的数据CN是所有客户端的连接入口负责SQL解析、生成执行计划、汇总DN返回的结果。一个GaussDB集群可以部署多个CN它们之间完全对等一个CN挂了客户端连另一个就行。但要注意两个细节DDL操作需要所有CN参与因为CN上有表的元信息缓存如果有一个CN挂了且25秒内拉不起来CMS会把它剔除这期间DDL执行会被阻塞CN挂了之后已经连在这个CN上的会话会断开但其他CN上的会话不受影响6.DN数据节点真正干活的DN是数据存储和计算的实际执行者。数据按shard分布到多个DN上每个shard有1主多备默认1主3备。DN的主备复制用Quorum机制日志必须在多数派含主上落盘事务才能提交。这意味着少数派备机挂了 → 主DN继续工作不受影响多数派挂了比如1主3备里主1备挂了只剩2备→ 主DN无法形成多数派确认事务提交被阻塞业务卡住cm_server仲裁DN主备切换时会从半数以上存活的备机中选择日志量最全LSN最大的那个升主。这个设计保证了切换后的新主数据最全不会丢数据。二、启动流程七个步骤一步都不能跳GaussDB集群启动不是systemctl start gaussdb这么简单它有严格的启动顺序。理解这个顺序排障的时候才能知道该看哪里。1.启动链条从底到顶2.实际排查时怎么看gs_om -t statuscm_ctl query -Cvipd的输出按这个顺序看。正常的输出大概是排障时按从底到顶的顺序检查3.Step 1~3: 看护链是否正常这三步有问题后面的组件一定起不来。我那次GTM状态Unknown的故障根因就是cm_agent被人手动kill掉了om_monitor刚好在检测间隔期没及时拉起本节点GTM心跳中断cm_server判定异常状态全部变Unknown。4.Step 4~5: cm_server和ETCDETCD必须全部Healthy或者至少多数派Healthy。如果ETCD有问题cm_server的日志里会看到大量连接ETCD失败的报错。5.Step 6~7: GTM、DN、CNcm_server仲裁确定好主备关系后实际启动动作由cm_agent执行。所以GTM/DN/CN起不来首先怀疑cm_agent是否正常——cm_agent挂了本节点所有业务实例都无人看护。看gs_om -t status里的state列判断各实例状态。如果DN状态是Manually stopped或者Unknown说明cm_agent尝试过拉起但没成功需要去对应节点的日志里查原因。三、故障恢复每个组件谁看护、谁仲裁、怎么切GaussDB的故障恢复设计非常精细每个组件都有明确的看护关系和仲裁逻辑。下面按组件逐个拆解全是生产环境里需要烂熟于心的知识点。1.Monitor进程故障由crontab系统定时任务拉起om_monitor是整个看护链条的起点。它自己挂了由crontab兜底cm_agent挂了由om_monitor拉起。这条链任何一个环节断了后面的自愈机制全部失效。2.CMAgent进程故障由Monitor拉起cm_agent挂了 → om_monitor检测到 → 自动拉起cm_agent。cm_agent是所有实例的统一看护人本节点上GTM、DN、CN的进程状态都由cm_agent监控并上报cm_server。cm_agent是整个集群自愈机制的底座优先级最高。3.CN进程故障由CMAgent自动拉起cm_agent先尝试拉起CN进程拉不起的话cm_server会仲裁剔除该CN25秒超时CN被剔除后会阻塞DDL执行因为DDL需要所有CN参与元信息同步通过CN节点加回操作可以恢复故障CNCN没有主备概念一个CN挂了其他CN还能继续提供查询服务4.DN进程故障由CMAgent自动拉起cm_agent先尝试拉起DN进程拉不起的话触发主备切换cm_server仲裁从半数以上存活DN中选择日志量最全LSN最大的节点升主采用1主3备或1主5备方式部署日志在多数派DN上落盘之后事务才提交备机故障少数派不影响主机业务新主起来后其他备机自动追日志同步故障DN修复后可以作为新备机重新加入集群5.GTM进程故障由CMAgent自动拉起cm_agent先尝试拉起GTM进程拉不起的话触发主备切换优先选择高优先级AZ的GTM备机升主备机故障不影响主机业务只要有一个GTM主就不影响业务新事务需要向GTM申请全局事务ID6.CMServer进程故障由CMAgent自动拉起cm_agent先尝试拉起cm_server进程拉不起的话触发主备切换CM备发现CM主心跳超时CM备自行仲裁新主优先选择节点号较小的cm_server备机升主只要有一个CMS主就不影响业务切换期间集群管理功能暂停但数据库读写不受影响主备仲裁依赖ETCD备cm_server尝试在ETCD中写入自己的信息谁先写入谁升主7.ETCD进程故障由CMAgent自动拉起om_monitor先尝试拉起ETCD进程ETCD采用raft分布式一致性算法如果主节点leader故障备节点follower发起投票获得多数投票的candidate升主故障节点恢复之后成为follower2AZ部署时每个AZ部署同样个数ETCD需要额外一个仲裁AZ部署奇数个ETCD确保有一个AZ故障时ETCD可以多数派选主ETCD主要作用有两个利用共识算法来存储集群状态信息用于cm_server主备状态判断故障时先写入ETCD的升主DN主备仲裁主体由cm_server完成会依赖ETCD中保存的数据如term值3.一句话总结各组件故障影响组件看护人仲裁者切换策略对业务的影响om_monitorcrontab—自动拉起无直接业务影响cm_agentom_monitor—自动拉起本节点实例失联可能误触发切换cm_servercm_agentETCD写入节点号小的备优先升主管理功能暂停读写不受影响ETCDcm_agentraft投票多数派选举多数派没了集群管理冻结GTMcm_agentcm_server高优先级AZ备升主新事务无法启动已有事务不受影响DNcm_agentcm_serverLSN最大的备升主少数派故障不影响多数派不够事务阻塞CNcm_agentcm_server25秒拉不起就剔除DDL被阻塞查询不受影响四、实战中的四个血泪教训1.教训一kill进程前先确认是不是看护链上的组件我那两个小时就浪费在这上面。运维同事在清理僵尸进程时用了kill -9没注意把cm_agent也带下去了。cm_agent是om_monitor看护的但om_monitor的检测有周期间隔默认几十秒cm_agent刚好死在这个间隔窗口里没被及时拉起。那几十秒内GTM心跳没上报cm_server判定异常状态全部变Unknown。排查时翻来覆去看了GTM日志、cm_server日志最后才发现是cm_agent进程没了。现在清理进程之前必须先ps -ef | grep cm_agent确认一下看护链上的组件一个都不能动。2.教训二ETCD节点数必须是奇数2AZ部署别忘了仲裁AZETCD集群必须有奇数个节点3个、5个等才能形成多数派。2AZ部署时如果两个AZ各放同样数量的ETCD节点一旦其中一个AZ整体故障剩下的AZ节点数可能构不成多数派导致ETCD无法选主整个集群管理功能冻结。这时候需要额外加一个仲裁AZ部署奇数个ETCD节点确保任意一个AZ挂了还剩多数派。这个仲裁AZ只跑ETCD不跑业务很多项目前期规划时容易漏掉。3.教训三DN多数派的计算要心里有数1主3备的部署多数派是3含主。也就是说挂了1个备 → 还剩1主2备仍能形成3个多数派不影响挂了主1个备 → 还剩0主2备多数派不够事务阻塞挂了2个备 → 还剩1主1备多数派不够事务阻塞1主5备的部署多数派是4含主能容忍更多的故障。金融核心系统建议1主5备普通业务1主3备够用了。4.教训四CN剔除后要尽快恢复CN被剔除后DDL会被阻塞。如果业务有频繁的建表、改表操作影响会很大。建议在告警策略里给CN状态加个告警一旦CN被剔除立即通知DBA处理。总结GaussDB的架构设计思路很清晰每一层都有上一层看护最底层由操作系统定时任务兜底。这个链条是 crontab → om_monitor → cm_agent → cm_server → 业务实例任何一个环节断了都有恢复机制。日常运维中理解这套启动依赖和故障恢复优先级能让你在遇到问题时快速缩小排查范围。记住这个口诀• 集群起不来从底往上查crontab → om_monitor → cm_agent → cm_server → ETCD → 业务实例• 实例挂了看cm_agent能不能拉起拉不起等cm_server仲裁切换• ETCD多数派在集群就不会彻底瘫• DN多数派不够事务就提交不了下次生产环境出问题别慌按这个链条一步步查基本都能定位到根因。END