ITPub博客

首页 > 数据库 > Oracle > 搞懂 Oracle RAC 的三种心跳:网络心跳、磁盘心跳、本地心跳

搞懂 Oracle RAC 的三种心跳:网络心跳、磁盘心跳、本地心跳

原创 Oracle 作者:a960549548 时间:2026-08-17 14:24:28 0 删除 编辑


 RAC 运维的人多少都见过节点被驱逐:告警响起来,上去一看,一个节点自己重启了,日志里一片 eviction 的信息。要搞明白节点为什么被踢出去,就得先搞明白集群的心跳机制。这篇文章把 Oracle 集群的三种心跳捋一遍,给以后排查这类问题打个底。

从集群一致性说起

先说一个概念:集群一致性。听起来挺玄,其实就是两件事:

  1. 集群里的每个成员都得知道其他成员的状态;
  2. 每个成员手里的“节点成员列表”和“各节点状态”必须是一致的,不能 node1 认为集群有 4 个节点、node2 认为只有 3 个。

这是集群最基本的要求,做不到这一点,后面的一切都无从谈起。Oracle 靠三种心跳来维护它:

  • 网络心跳(NHB):节点之间互相探活,走私网;
  • 磁盘心跳(DHB):节点往共享的表决盘(Voting File)上写连通性信息;
  • 本地心跳(LHB):节点自己监控自己。

下面一个一个说。

网络心跳:私网上每秒一次的问候

ocssd.bin 进程每秒钟通过集群私网,向其他所有节点发送一次网络心跳。拿 4 节点集群举例:每个节点每秒向另外 3 个节点各发一次心跳,同时也收到 3 份心跳。既然是互相发,就得有一套机制判断“对方是不是失联了”,以及失联之后怎么处理。这套逻辑由 ocssd.bin 里的几个线程完成:

  • 发送线程:每秒向集群所有节点发送网络心跳;
  • 派遣线程:接收远程节点传过来的信息,按信息类型分发给相关线程处理;
  • 分析线程:分析收到的网络心跳,确认节点连通性,如果发现某个节点持续丢失心跳,就通知集群重新配置;
  • 集群重新配置线程:负责执行重新配置。

流程很直白:发送线程每秒往外发,派遣线程收进来,分析线程做判断。一旦分析线程发现在连续一段时间内收不到某个(或某几个)节点的心跳,集群就会触发重新配置——而这种情况下的结果,往往就是那个节点离开集群。

所以说私网是 RAC 的命根子。私网抖一下,轻则重新配置,重则节点被驱逐,集群一致性直接被破坏。生产环境私网交换机、网卡出问题导致的驱逐,是真实世界里很常见的事故。

磁盘心跳:脑裂时的裁判

磁盘心跳的目的只有一个: 脑裂发生时,帮集群做裁决。

每个节点每秒钟向所有表决盘(VF)写入两样东西:本节点的磁盘心跳信息,以及自己当前能联系到的其他节点列表。平时这些信息用不上,一旦脑裂,CSS 的重新配置线程就能靠表决盘里的数据还原出“谁和谁还连着”,从而判断集群会分裂成几个子集群、每个子集群包含哪些节点、各节点处于什么状态。

这里有条关键规则:每个节点必须能访问到 [VF 总数 / 2] + 1 个表决盘,也就是多数派。

为什么必须是多数派?拿两节点集群配三块 VF 举例就明白了。

情况一:node1 访问不了 VF1,node2 访问不了 VF2。没事,两个节点仍然能同时访问 VF3,裁决信息在 VF3 上还是对齐的。

情况二:node1 访问不了 VF1 和 VF2(只剩 VF3),node2 访问不了 VF3(还剩 VF1、VF2)。这时三块盘里没有任何一块能被两个节点同时访问。一旦网络再出问题,两边从表决盘里读到的信息对不上,谁也说服不了谁,重新配置就做不下去了——没法决定谁该留下、谁该离开。

多数派规则正好堵死了情况二:3 块盘要求每个节点至少能访问 2 块,两个节点各自可见 2 块,2 + 2 > 3,两边的盘集合必然有交集。也就是说,无论怎么坏,至少有一块 VF 能被所有节点访问到,裁决依据永远存在。

本地心跳:自己看着自己

网络心跳和磁盘心跳解决的是“别人活没活着”,本地心跳解决的是“我自己活没活着”。

ocssd.bin 每秒在发送网络心跳的同时,会向 cssdagent 和 cssdmonitor 报告自己的状态,这就是本地心跳。cssdagent 收得到心跳,就认为 ocssd.bin 正常;如果本地心跳持续丢失、时间达到 misscount,cssdagent 就判定本地节点的 ocssd.bin 出了问题,然后直接重启该节点。

听着挺狠,但这是必要的:一个 hang 死的节点如果还占着集群成员身份,比直接重启危害大得多。与其留下来制造不一致,不如主动离场。

脑裂及其裁决原则

脑裂指的是:网络心跳丢了,但磁盘心跳正常。集群因此分裂成若干个子集群,每个子集群都以为自己是主节点。这时集群需要重新配置,裁决原则很朴素:

  • 节点数多的子集群活下来;
  • 节点数一样多时,包含最小编号节点的子集群活下来。

输掉的一方,被驱逐。

misscount 和 disktimeout 的查询与修改

misscount 定义网络心跳的超时时间,默认 30 秒。一个或多个节点连续丢失网络心跳超过这个时间,集群就得重新配置。在 11gR2 里,它同时也是本地心跳的超时时间——因为本地心跳和网络心跳是同一个线程发的,一损俱损。

disktimeout 是磁盘心跳的超时时间,默认 200 秒。

查询网络心跳的 misscount:

text
[root@node1 ~]# crsctl get css misscountCRS-4678: Successful get misscount 30 for Cluster Synchronization Services.

查询磁盘心跳的 disktimeout:

text
[root@node1 ~]# crsctl get css disktimeoutCRS-4678: Successful get disktimeout 200 for Cluster Synchronization Services.

修改 misscount(改成 50,再改回 30):

text
[root@node1 ~]# crsctl set css misscount 50CRS-4684: Successful set of parameter misscount to 50 for Cluster Synchronization Services.[root@node1 ~]# crsctl set css misscount 30CRS-4684: Successful set of parameter misscount to 30 for Cluster Synchronization Services.

修改 disktimeout:

text
crsctl set css disktimeout 300

这两个参数不是不能改,而是改之前最好想清楚为什么。misscount 调小了,私网稍微一抖就驱逐节点;调大了,真出故障时集群的反应又变慢。除非有明确的理由,一般不建议动。

三种心跳各管一摊:网络心跳管节点之间的连通性,磁盘心跳在脑裂时提供裁决依据,本地心跳保证节点自身出问题时主动离场。排查节点驱逐类故障时,先分清丢的是哪种心跳,再核对 misscount 和 disktimeout 的设置,alert log 加上 ocssd 的日志里,基本都能找到答案。


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70013625/viewspace-3179915/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
Oracle ACE,MySQL 8.0 OCP,PMP,拥有OceanBase OBCP,TiDB PCTP,GoldenDB GDCP等多项认证,ITPUB认证专家,微信公众号:DBA之友。

注册时间:2022-02-08

  • 博文量
    132
  • 访问量
    171527