RAC 运维的人多少都见过节点被驱逐:告警响起来,上去一看,一个节点自己重启了,日志里一片 eviction 的信息。要搞明白节点为什么被踢出去,就得先搞明白集群的心跳机制。这篇文章把 Oracle 集群的三种心跳捋一遍,给以后排查这类问题打个底。
先说一个概念:集群一致性。听起来挺玄,其实就是两件事:
这是集群最基本的要求,做不到这一点,后面的一切都无从谈起。Oracle 靠三种心跳来维护它:
下面一个一个说。
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 定义网络心跳的超时时间,默认 30 秒。一个或多个节点连续丢失网络心跳超过这个时间,集群就得重新配置。在 11gR2 里,它同时也是本地心跳的超时时间——因为本地心跳和网络心跳是同一个线程发的,一损俱损。
disktimeout 是磁盘心跳的超时时间,默认 200 秒。
查询网络心跳的 misscount:
查询磁盘心跳的 disktimeout:
修改 misscount(改成 50,再改回 30):
修改 disktimeout:
这两个参数不是不能改,而是改之前最好想清楚为什么。misscount 调小了,私网稍微一抖就驱逐节点;调大了,真出故障时集群的反应又变慢。除非有明确的理由,一般不建议动。
三种心跳各管一摊:网络心跳管节点之间的连通性,磁盘心跳在脑裂时提供裁决依据,本地心跳保证节点自身出问题时主动离场。排查节点驱逐类故障时,先分清丢的是哪种心跳,再核对 misscount 和 disktimeout 的设置,alert log 加上 ocssd 的日志里,基本都能找到答案。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70013625/viewspace-3179915/ ,如需转载,请注明出处,否则将追究法律责任。