☰
Oracle RAC集群CSS详解:从心跳机制到脑裂仲裁与排障实战
2026/10/3 14:24:34 网站建设 项目流程

在开始讲CSS之前,先同步一个背景:这是“RAC管理”系列里关于集群软件的部分,接前面两篇把RAC整体架构和集群件安装梳理完之后,今天专门把集群软件里的CSS拎出来聊透。RAC、集群软件、CSS这三个词放在一起,很多刚接触Oracle数据库集群的同行第一反应是“CSS不是网页样式表吗?”——在RAC的世界里,CSS全称是Cluster Synchronization Services(集群同步服务),它既不负责页面样式,也不做任何渲染,而是集群所有节点之间相互确认“谁还活着、谁有资格继续待在集群里”的那根定海神针。这篇内容适合两类人:一类是刚接手RAC、对集群进程还停留在“会启动、会看STATUS”阶段的运维工程师,另一类是已经操作过一段时间、但遇到节点被驱逐或脑裂时只能靠重启解决问题的朋友——我会把CSS的原理、日常操作、故障排查串起来讲,尽量把那些文档里不会直说的经验补上。

1. CSS在集群软件栈里的定位:它不是“样式表”,而是集群的“神经系统”

1.1 先认清RAC集群软件里那几个常驻进程

要理解CSS,必须先弄清楚RAC的集群软件整体上由哪些角色组成。很多人习惯直接说“集群软件就是Oracle Grid Infrastructure(GI)”,这个说法在11g之后的版本里基本成立,GI栈里最核心的常驻进程有下面几个:

进程中文俗称主要职责
ohasd集群守护进程系统启动后第一个起来的集群进程,负责拉起其他关键进程,相当于“开机引导员”
cssdagent / cssdmonitorCSS代理/监控进程监控ocssd的健康状态,发现问题时执行本地节点重启或驱逐动作
ocssdCSS主进程维护节点成员关系、心跳检测、仲裁投票,是CSS服务的真正执行者
evmd事件进程负责集群内节点间事件消息的发布与订阅
crsd资源进程管理VIP、Listener、数据库实例、ASM等资源的启动/停止/故障恢复

从这张表能看出,CSS并不代表某一个单独进程,而是ocssd加上cssdagent、cssdmonitor这一整套机制的总称。这组进程在GI栈里的层级很低,低到什么程度呢:ohasd起来之后,第一优先级要拉起来的就是cssd家族,因为后面的evmd、crsd、ASM实例、数据库实例全都需要CSS先给出“节点是否具备集群成员资格”的结论。打个比方,CRS管的是“基础设施里哪些服务该上班”,EVM管的是“通知大家出了什么事”,而CSS管的是“什么样的人才有资格站在这间会议室里”。如果CSS不给资格,后面所有服务都无从谈起。

1.2 CSS三个核心职责:成员资格、磁盘判读、仲裁信号

CSS具体忙些什么,总结下来是三件大事。

第一件,维护节点成员资格表。每个节点启动后,ocssd会通过私网交换心跳信息,把“我上线了”“我还活着”的消息同步给其他节点,这个成员表就是集群决定“谁是自家人”的依据。数据库实例启动之前也要向CSS确认当前节点身份,只有拿到合法成员身份,实例才会真正启动数据库相关进程。

第二件,仲裁谁有权访问共享存储。RAC所有节点都共享同一套数据文件、OCR、表决文件,但共享不代表可以乱写。CSS负责保证在脑裂或者网络异常时,持有合法票数的那一组节点才能继续访问OCR和表决文件,另一组要么被驱逐、要么被本地重启,防止两个节点同时对同一份数据文件写入造成永久损坏。这个机制确保了RAC最核心的红线:同一时刻,只有一群“最合法”的节点能操作共享存储。

第三件,对外提供仲裁信号。ASM实例和数据库实例启动、运行的过程中,都需要从CSS拿到“当前集群状态稳定、可用节点数足够”的信号。如果CSS认为集群不安全,ASM实例会拒绝挂载磁盘组,数据库实例也会报出一些让人摸不着头脑的ORA错误。这也是为什么很多RAC故障表面上报错在数据库层,真正病灶却在CSS层。

理解CSS时,最忌讳的就是把它单纯当成“一个心跳检测进程”。心跳只是它的手段,它的真正价值是:在任何异常情况下都能让集群快速收敛到一个合法的、唯一的状态。这个定位决定了CSS出问题时,整个集群宁可重启节点、宁可短暂停服务,也不能让数据完整性受损——这是RAC设计里最根本的取舍。

2. 心跳、脑裂、投票:CSS到底是怎么防止集群“精神分裂”的

2.1 双心跳机制:网络心跳和磁盘心跳各有分工

CSS判定节点是否存活,靠的不只是一条通道,而是两条:网络心跳和磁盘心跳。

网络心跳走私网,默认大概每秒钟发送一次报文,用来确认其他节点的操作系统和网络协议栈是否正常响应。这一层反应最快,一两个心跳周期收不到回复,ocssd就开始怀疑对方出问题了。但网络心跳有个盲区:它只能证明“另一个节点的心跳进程有没有回话”,无法证明“这个节点是否已经失控、会不会去破坏共享数据”,所以CSS还需要第二层保障。

磁盘心跳走的是表决文件。每个存活的节点都会周期性地往表决文件里写入自己的状态信息,同时读取其他节点的状态。即使两台服务器之间私网完全断了,只要它们还能同时访问表决文件,CSS就能通过磁盘心跳判断“谁还在场上”。这个设计非常关键:私网断了不等于集群一定要脑裂,只要共享存储链路还通,节点之间依然可以凭磁盘状态维持一致性。

两套心跳一起工作,就引出了RAC界非常经典的故障场景——私网断开、存储正常时,集群会尽量维持原有成员不踢人,等待网络恢复;但如果私网断开的同时,某个节点又无法访问表决文件,那这个节点就会很快被判定为“已经脱离集群”,触发驱逐或重启流程。

2.2 脑裂为什么必须“你死我活”

集群最怕的状态,不是某个节点挂了,而是两个节点都觉得自己才是合法主体。想象一个双节点集群,私网突然断开,节点A和节点B都收不到对方心跳,此时如果没有仲裁机制,两边都会认为“我才是唯一活着的节点”,然后同时尝试往共享存储上写数据——这就是脑裂。

CSS应对脑裂的办法非常直接:投票,少数服从多数。表决文件在传统设计里由奇数个“投票磁盘”组成,每个投票磁盘代表一票,集群中每个节点平时都保持对全部表决文件的写入能力。脑裂发生时,能访问到表决文件的节点会统计自己这边能访问的票数,票数不过半的一组会被强制出局。三节点集群最常见的结局是:两个节点能访问两个表决文件、组成“2票联盟”保留集群资格,剩下那个节点即使还活着也会被fence(栅栏隔离),轻则触发本地重启,重则直接关机,目的就是杜绝它继续操作共享资源。

这也是为什么很多老DBA常说“投票磁盘一定要配置奇数个”。2个或4个表决文件在均分时会出现票数相等,谁也没法说服谁,反而让局面僵住。奇数个核心里,2对1、3对1、3对2都能快速分出胜负,让集群迅速收敛到一个合法的赢家。到了12c之后的版本,表决文件被整合进ASM磁盘组,底层逻辑依然是“总票数必须过半才算赢”,只是增加了一些如quorum磁盘、failure group的新玩法,以适应更多跨机房部署场景,但核心仲裁思想完全没有变。

2.3 CSS重配置:每个节点加入或离开都会触发的一场“重新组阁”

当某个节点启动时想加入集群,或者某个节点被判定离开时,CSS并不会简单地说“好,你走吧”或“你进来吧”。它会启动一次全局重配置流程,把所有存活节点召集起来,重新确认一遍成员列表、交换各自状态、同步配置版本,整个过程日志里能看到“Reconfiguration started”和“Reconfiguration completed”两条关键记录。

重配置期间,所有涉及成员判断的操作都会暂停,数据访问虽然不是完全停顿,但新增资源调度会放缓。如果集群环境不稳定,比如某节点反复崩溃、反复尝试加入,就会触发连续重配置,日志里出现一个又一个“reconfig”循环,这对集群的伤害比单个节点宕机更严重,因为每个节点都会跟着做一遍状态同步,整个集群的性能和稳定性都会被拖垮。

理解重配置机制,对后期运维有三层价值:第一,看到节点加入或退出时,不必惊慌,关键是看重配置是否在预期时间内完成;第二,正常维护中增删节点,必须选在业务低峰,因为重配置过程本身有开销;第三,如果日志里频繁出现重配置,一定是底层节点状态或网络在反复抖动,这时候追根因比反复重启集群重要得多。

3. 日常运维中与CSS打交道的正手动作

3.1 检查CSS状态的三板斧:三种命令对应三种视角

接手一台RAC,第一步不是去查数据库状态,而是先确认CSS这个“神经中枢”是否健康。平时我基本上是三条命令打天下。

# 在任一节点执行,查看整个集群所有节点的CRS状态 crsctl check cluster -all # 单独检查CSS服务在当前节点的状态 crsctl check css # 查看集群初始化资源的运行情况,重点关注cssd资源 crsctl status resource -t -init

第一条命令返回“CRS-1009: The cluster is running in exclusive mode”之类的信息,说明集群级状态正常,注意“exclusive mode”在12c之后是正常现象,不用当成异常。第二条命令更聚焦,如果返回“CSS is active on all of the nodes”,说明CSS层没问题;如果某个节点通信异常,它会直接列出不可达的节点名。第三条命令能看到cssd、cssdagent、cssdmonitor、evmd、crsd这一组初始化资源的当前状态,正常情况下应该全是“ONLINE”。

除了上述三个动作,还有一条必须记住:

crsctl query css votedisk

这条命令用于查看当前集群使用的表决文件位置、名称和状态。正常情况下每一行都是“ONLINE”,如果出现“OFFLINE”或状态异常,说明表决文件读写有问题,这是CSS故障里最危险的一类,后面场景三会详细讲。

3.2 日志所在:“病历本”都写在哪个目录

CSS排障离不开日志,密码就在GI_HOME的log目录下。以11gR2之后的典型布局为例,日志主要在这几个位置:

# CSS主日志,包含心跳、重配置、投票、驱逐等关键记录 $GRID_HOME/log/<节点名>/cssd/ocssd.log # 集群告警日志,记录集群级的各类事件汇总 $GRID_HOME/log/<节点名>/alert<节点名>.log # CRS日志,资源级别的启停与故障记录 $GRID_HOME/log/<节点名>/crsd/crsd.log # 集群命令执行日志,适合查看命令层面的报错 $GRID_HOME/log/<节点名>/crsd/clusterware.log

实际排障时,我的习惯是先看alert日志确定“大概哪个时间段出问题”,再进ocssd.log里找细节。ocssd.log里真正需要关注的关键词不算多,重点抓这几个:reconfiguration、vote、fence、kill、timeout、inaccessible。比如搜到“Reconfiguration completed”前后跟着某节点被标记为not reachable,那就基本能锁定问题发生在网络或该节点自身。

还有一个细节很容易踩坑:很多环境里$GRID_HOME和$ORACLE_HOME不是同一个路径。CSS属于GI栈,日志一定写在上海GI的log目录下,不是数据库软件目录下。我刚带人的时候经常看到新手在$ORACLE_HOME/log里翻半天找不到ocssd.log,实际是因为他看的是数据库实例的目录。先确认echo $ORACLE_HOME里的路径是不是GI的安装路径,再去找log目录,能省一大堆时间。

3.3 想停CSS?别只盯着它,要停就停整个CRS栈

CSS在GI栈里被设计成“受保护进程”,日常管理中几乎不存在单独启停CSS的场景。如果你执行crsctl stop crs,相当于停掉当前节点整个集群软件栈,CSS、EVM、CRS会按顺序依次停止;反过来crsctl start crs则会先起ohasd,再由ohasd启动CSS,然后才是EVM和CRS。

为什么不要尝试单独kill ocssd进程?因为CSS是集群的“生死判定者”,它挂了之后,其他节点会因为收不到心跳而认为该节点失联,直接触发驱逐。结果就是你明明只想重启CSS,最后却变成节点被集群强制重启,还可能连带影响OCR和表决文件的访问。真要维护某个节点,正手操作是下面这个次序:

# 在目标节点上先关应用层 srvctl stop database -d <数据库名> srvctl stop asm -n <节点名> # 再停整个集群软件栈 crsctl stop crs # 维护完成后重新启动 crsctl start crs # 确认状态 crsctl check cluster -all

如果是整个集群计划内停机,还有一种更简洁的姿态,在任一节点上执行crsctl stop cluster -all,所有节点会一起安静下来。需要强调的一点是:能不停就别停,能滚动停就滚动停。虽然很多时候我们改OS参数、换网卡不得不重启节点,但每次CRS重启都是一次重新建立成员关系的过程,停了再起,如果底层的网络心跳或者存储链路本来就有隐患,重启过程会把这些隐患加倍放大。

4. 真实排障:CSS相关三个典型场景与完整排查链路

4.1 场景一:节点被CSS判定失联,反复重启或直接fence

现象描述:某天监控报警,集群里的节点2状态异常,操作系统层面显示服务器不断重启,或者节点2没有重启但数据库日志里突然出现大量错误,应用端彻底连不上该节点上的服务。此时另一个节点1上看,crsctl check cluster -all显示节点2 unreachable。

完整排查链路: 第一步,先看时间线。登录节点1,打开集群告警日志和ocssd.log,找到节点2出问题前最后几条记录,看是“Network heartbeat lost”还是“Disk heartbeat lost”。这一步直接决定了后面排查方向。 第二步,如果是网络心跳丢失,重点看私网是否抖动。用ifconfig或ip link查看私网网卡状态,看有没有大量丢包、错包、DOWN/UP切换记录;再看交换机和网卡日志有没有CRC错误或协商速率变化。很多时候是私网网线松动、光模块劣化这类硬件问题。 第三步,如果是磁盘心跳丢失,重点看共享存储路径。检查节点访问表决文件对应磁盘的IO状态,iostat -x 1看看有没有长时间await飙高;同时确认多路径软件状态正常,别是存储侧链路瞬断导致表决文件访问超时。 第四步,确认根因后修复,恢复网络或存储。再手动把被强制下线的节点的CRS服务拉起来,crsctl start crs,然后等它重新加入集群,观察ocssd.log中是否出现重配置完成记录。

这条链路里我最想强调的一点是:不要一看到节点重启就急着把它加回去。节点重启是CSS的自我保护,真正的问题是为什么触发保护。不找到根因就反复加节点,只会让集群陷入“加进来—又掉线—又加进来”的循环,重配置风暴比单个节点宕机更可怕。

4.2 场景二:ocssd.log里出现大量“IPC send timeout”或“heartbeat timeout”

现象描述:集群当前没有节点掉线,业务也还跑着,但日志里不断刷IPC send timeout、heartbeat timeout之类的告警,节点间通信时快时慢,偶尔还会出现资源组在节点间飘移。

完整排查链路: 第一步,确认私网延迟和丢包。在节点间用ping测延迟,但一定不要只ping几个包就下结论。至少连续ping 1000个包,统计丢包率和最大延迟,CSS要求的心跳周期非常短,任何超过几十毫秒的延迟都可能被判定为危险信号。 第二步,检查私网是否被误用。常见问题是有人把备份流量、日志同步流量、甚至SSH管理流量都走私有网络,高峰时段把私网带宽打满。RAC私网是集群的生命线,备份、OGG同步这类大流量必须走独立网络或服务网络。 第三步,查看crsctl get css misscount这类参数,但我要明确说一句:这些参数在11gR2之后大多已经不用手工调整,CSS会自适应心跳超时。老经验里改misscount的操作在新版本里不仅没用,还可能让集群在真正脑裂时反应迟钝。真正需要做的,是让私网负载回归正常。 第四步,如果网络负载正常但问题依旧,考虑私网网关配置或路由问题,确认私网网段的连通性没有经过不必要的路由跳转;如果配置了多个私网网卡,还要检查它们是否属于同一子网或存在路由冲突。

排这个故障时最颠覆我认知的一次经历是:问题出在节点上某块网卡开启了节能模式,低负载时一切正常,高峰时网卡自动降速,心跳就开始超时。后来在系统层把网卡节能彻底关闭,问题才消失。这类问题用常规网络排查很难一眼发现,必须结合日志时间点与网卡状态联动分析。

4.3 场景三:表决文件异常导致的CSS仲裁失败

现象描述:执行crsctl query css votedisk时,某个votedisk状态不是ONLINE;ocssd.log中反复出现“Voting disk(s) inaccessible”或“Lost access to voting disk”的记录。严重时集群所有节点都不敢继续维持成员资格,先后重启,服务全停。

完整排查链路: 第一步,用crsctl query css votedisk确认哪些表决文件脱机。这里的输出会列出磁盘路径、状态、票数,先记录完整信息再动手。 第二步,检查存储链路。如果表决文件放在ASM磁盘组里,用asmcmd lsdg看磁盘组状态,确认是否某块ASM磁盘故障导致ASM降级;如果表决文件还放在裸设备或集群文件系统上,直接用dd读测试磁盘设备,看有没有IO error。 第三步,检查权限与设备状态。确认GI运行用户对该磁盘设备有正确的读写权限,有些环境重启后设备的属主或权限会变化,导致CSS无法打开表决文件。同时确认多路径设备状态,multipath -ll看看路径是否只剩一条,Active/Active状态是否正常。 第四步,修复表决文件。ASM磁盘组内的表决文件损坏时,通常做法是从正常节点执行crsctl replace votedisk +复制的磁盘组名,让OCR的自动备份能力重新生成表决文件。这个命令是有风险的,执行前一定确认备份和磁盘组冗余度都在线,操作完成后再次用crsctl query css votedisk验证全部状态变为ONLINE。

这个场景是CSS故障里危险系数最高的,因为表决文件是仲裁的“选票底稿”,一旦损坏,整个集群连合法的老大都选不出来。之前见过有同事想“省事”,直接把故障磁盘从ASM里踢出去重建,结果连OCR也一起损坏,最后只能靠整库恢复兜底。这种操作绝对不可以贪图快,诊断做得越细,后面的恢复越稳。

4.4 三条链路背后的共同排查思维

把三个场景串起来看,CSS排障其实就三句话:先分网络还是存储,再看日志时间线,最后才动手改配置。我见过太多排查一上来就重启集群、重新配置votedisk的例子,最后都把小问题搞成大事故。只要CSS日志还在,它就把当时发生了什么写得明明白白——问题是你看没看、会不会看。

5. 版本演进与维护边界:CSS在不同版本里的角色转换

5.1 从10g到19c,CSS的形态变了但本质没变

老DBA应该还记得10g时代,集群软件叫CRS,CSS服务还是单独的ocssd进程,表决文件是几个裸设备,每个节点上还要格外小心地维护设备权限。到了11gR2,GI把OCR和表决文件整合进ASM磁盘组,CSS的仲裁动作不再直接对着裸设备,而是通过ASM来读写表决信息,同时增加了cssdagent和cssdmonitor两个守护进程,让ocssd本身也处于被监控状态,整个保护链更完整。12c之后,CSS继续演进,支持在扩展集群或同质集群中加入quorum磁盘、failure group的概念,仲裁算法可以更灵活地适应跨机房、跨地域的部署。到了19c,我们日常看到的“exclusive mode”已经成为常态,GI在单节点环境下也默认以集群方式运行,CSS依然是最底层最核心的那根弦。

这些版本变化容易让人产生一个错觉:既然表决文件都进了ASM,CSS是不是只是个“老古董”接口?完全不是。版本不断演进的是存储方式和管理入口,但CSS对节点成员资格的判定权、对脑裂时的话语权、对共享存储的保护权,一点都没有削弱。你升级到19c,遇到私网闪断,CCS该驱逐的还是会驱逐,该重启的还是重启,和前代版本的行为逻辑完全一致。

5.2 哪些日常操作会无意中“碰到CSS”

维护RAC时,很多动作表面上是网络、存储或系统层面的,实际上都会牵动CSS的判断逻辑。

第一类,NTP时间同步问题。CSS对集群内时间漂移很敏感,节点间时钟差一大,心跳的时间戳就乱了,脑裂判定容易被误触发。虽然有些环境下配置了CTSS负责时间同步,但如果你额外手工改了系统时间或NTP配置,动作一定不能只做一次,要确认跨节点时间完全一致后再继续观察CSS日志,看有没有异常重配置。

第二类,私网IP或主机名变更。做这类变更前至少要过一遍CSS思路:改名或改IP之后,节点还能不能通过原来的私网路径找到彼此?OCR里记录的节点信息要不要同步更新?很多集群变更加载之后出现节点无法加入,根源就是只改了系统层,没同步集群配置层。

第三类,动态增删表决文件。CSS支持在线增加或移除表决文件,理论上可以在业务运行中执行crsctl add votedisk、crsctl delete votedisk,但我强烈不建议高峰期做这类操作。表决文件的重配置同样涉及全局重配置过程,一旦命令执行中遇到存储抖动,影响范围不会只局限在一块磁盘上。

第四类,操作系统加固。给服务器做安全基线加固时,最容易被忽略的就是对CSS相关进程、私网端口、共享存储设备权限的变更。一块权限收得过紧,CSS进程就再也打不开表决文件;一个私网端口被防火墙策略误封,心跳立刻中断。每一次系统加固之后,都应该顺手跑一遍crsctl check cluster -all,这不是形式主义,而是用最短时间验证CSS最关心的两件事——网络和存储——是否依然畅通。

经验上我还有个土办法:每次在RAC环境做任何变更前,先截一个图表决文件和集群状态的基线,变更完再截一次,对比一下。别小看这个动作,它曾经帮我快速定位过一次“加固脚本把ASM磁盘设备权限改错”的低级问题。CSS这东西,平时看不出存在感,但恰恰是这些看似不相关的操作会让它瞬间从“后台进程”变成“故障主角”。

再补一个非常实际的小技巧:CSS日志会滚动保留,但历史文件同样是排障宝藏。遇到问题时,不要只盯着当天的ocssd.log,去翻一下前一天甚至前几天的滚动日志,往往能发现故障发生前就存在的规律性异常,比如每天晚上同一个时间段就出现几次心跳超时,这通常是定时任务或备份流量在捣乱。能看到这层规律,才是把CSS排障从“救火”上升到“防火”的关键一步。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询