2026/9/15 17:08:04

Oracle RAC集群gipc通信故障排查与修复实践

Oracle RAC集群gipc通信故障排查与修复实践 1. 故障背景与现象描述1.1 两节点RAC的物理环境这次出问题的是一套很典型的两节点Oracle RAC集群。节点配置不算高数据库版本是Oracle 11.2.0.4操作系统是Red Hat Enterprise Linux 7.9共享存储挂在SAN上每个节点配置了两块物理网卡一块走公有网络对外提供业务访问一块走私有网络做集群内部心跳和缓存融合数据交互。节点1和节点2的主机名分别是rac1和rac2公有IP和VIP分别做了规划私有IP用了单独的192.168.10.0/24网段。我在排查故障时习惯先把环境资料拉出来不然容易在网卡、主机名、IP这些基础信息上绕圈子。这次环境里有个细节值得先说两块网卡在系统里的接口名是enp2s0和enp3s0分别绑定公网网段和私网网段。Oracle通过oifcfg getif登记的接口信息决定了集群内部组件应该使用哪个网卡、哪个子网来通信。如果这里的登记信息和系统实际情况不一致后面gipc出问题几乎是必然的。1.2 故障爆发时的表现问题出现在一次机房计划维护之后。维护内容包括机房网络交换机配置变更期间节点rac2需要重启。重启完成后检查节点状态时发现rac1集群运行正常但rac2的CRS一直起不来。应用侧的表现非常直接连接RAC数据库的报错不再是常见的ORA-12541监听无响应而是直接超时部分应用直接连不上数据库。检查rac2上的Oracle监听服务监听没有正常启动。数据库服务也处于不可用状态业务反馈从节点2写入数据的模块全部失败。我登录到rac2上执行crsctl check crs输出直接显示CRS进程状态异常。再执行ps -ef | grep d.bin发现crsd.bin进程根本没有起来cssd.bin也在不断重启。这时候第一个直觉是集群底层资源链没有拉起来而不是数据库本身的问题。后续排查确实证明根因落在gipc这个集群内部通信组件上而它引发的连锁反应把CRS、监听、数据库全部拖垮了。2. 先搞懂gipc在集群启动链路中的位置2.1 gipc不是普通的网络通信工具很多DBA第一次看到gipc这个缩写容易把它理解成某种网络协议。gipc全称是Grid Infrastructure Process Communication它是Oracle Grid Infrastructure内部定义的进程间通信机制。说直白一点它就是集群各个组件之间传递消息的“专用电话线路”。在RAC架构里节点间的消息交互不只是数据库查询这种业务流量还包括大量的集群内部心跳、锁管理消息、缓存融合过程中的数据块传递。这些消息必须有一个可靠、低延迟的通信通道。gipc做的就是这个事情。它由gipcd守护进程负责管理会在节点启动时监听私有网络上的IP地址并以HAIPHighly Available IP的形式对外提供可漂移的通信地址。如果没有HAIPASM实例之间的通信、集群节点之间的内部协调都会变成一盘散沙。我把gipc比作“集群的电话交换机”。节点间所有关键通话都要经过它它不工作其他组件就算进程还在也像断了线的电话一样互相找不到对方。CRS的资源管理器在启动后续资源时会判断底层通信依赖是否就绪gipc资源没有online依赖它的资源就会一直处于等待或报错状态。2.2 CRS启动的资源依赖链Oracle集群从操作系统启动到最后提供数据库服务不是一条简单的线条而是一棵向上依赖的资源树。系统上电后init进程拉起ohasdohasd负责启动集群的初始化资源包括CSSD、EVMD、GIPCD这些。其中gipcd进程负责初始化gipc通信端点。在11.2版本中我们可以用crsctl stat res -t -init看到一批以ora.开头的初始化资源比如ora.cssd、ora.evmd、ora.gipcd、ora.drivers.acfs等。gipcd一旦无法初始化CSSD后面的集群就绪服务、节点成员关系、虚拟IP等资源全部无法正常拉起。这个依赖关系决定了故障位置的排查重点。当crsd进程起不来时不要急着把它当成最终问题而要先看它依赖的资源有没有online。这次rac2上crsctl stat res ora.gipcd -t -init显示的STATE是OFFLINE且反复处于启动失败状态才真正把目光聚焦到gipc上。3. 故障定位从表面报错一步步深入到gipc3.1 第一步抓取crs核心日志遇到CRS起不来的情况我一般不急着反复重启而是先把当前节点上所有集群日志的时间线梳理一遍。尤其是故障前最后几分钟的报错信息往往直接指向根因。这次我在rac2上按顺序检查了以下日志文件$GRID_HOME/log/rac2/alertrac2.log集群总告警日志记录了资源状态变化和关键错误。$GRID_HOME/log/rac2/cssd/ocssd.logCSSD日志看节点集群成员关系是否建立。$GRID_HOME/log/rac2/crsd/crsd.logCRSD日志看crsd进程为什么起不来。$GRID_HOME/log/rac2/gipcd/gipcd.loggipc守护进程日志这次问题的核心所在。在alertrac2.log里我看到资源ora.gipcd反复尝试启动每次都在很短时间内失败随后触发资源重启。在gipcd.log尾部出现了类似的报错2024-xx-xx 10:12:33.123: GIPC internal error: failed to bind to listen endpoint 2024-xx-xx 10:12:33.124: gipc: failed to establish listener on interface enp3s0 2024-xx-xx 10:12:33.125: gipc: unable to initialize network endpoint这个报错看起来是gipcd无法在指定的网络接口上建立监听。按我的经验这类问题十有八九和网络接口名称、IP地址绑定有关。3.2 第二步确认gipcd资源与进程状态在抓日志前我已经用crsctl stat res ora.gipcd -t -init看过资源状态。输出类似这样NAMEora.gipcd TYPEora.gipc.type TARGETONLINE STATEOFFLINE这里TARGET是online但STATE是offline说明资源管理器想把gipcd拉起来但进程始终无法稳定运行。接着用ps -ef | grep gipcd查看进程发现gipcd进程虽然出现了但过几秒就消失明显是启动后立刻退出。为了进一步确认我手动执行了crsctl start resource ora.gipcd -init -n rac2结果返回类似“CRS-1018: Resource is in an error state”的错误。这一下基本可以锁定gipcd进程本身有问题或者它依赖的网络环境有问题。结合gipcd.log中failed to bind的报错优先怀疑网络配置层面的问题。3.3 第三步核对网卡、oifcfg和hosts接下来我直接看了系统网络配置。先执行ip addr发现rac2上私网网卡enp3s0的IP地址是192.168.10.12状态是UP链路正常。然后执行oifcfg getif这是Oracle查看接口登记信息的关键命令。输出让人意外enp2s0 192.168.5.0 global public enp3s0 192.168.10.0 global private接口名称、子网、角色看起来没问题。但我继续执行oifcfg iflist检查系统扫描到的接口列表发现系统识别到的私网接口名仍然显示enp3s0而gipcd日志里却在尝试绑定另一个名称enp3s0这里看起来一致但日志里又有一个关键细节gipcd尝试绑定的IP地址是192.168.10.13而不是实际的192.168.10.12。这就很可疑了。我马上查看/etc/hosts发现里面把rac2-private这个私有网络别名解析到了192.168.10.13而实际网卡IP是192.168.10.12。也就是说gipcd按照hosts解析到的IP去绑定监听地址但这个IP并不属于本机任何网卡bind必然失败。原因到这里已经清楚了系统重启后某个配置脚本改写了hosts文件私有主机名对应的IP被写错导致gipcd拿着错误IP去初始化监听端点。这就是为什么gipc成为整条故障链的断点。4. 修复过程让gipc回到可用状态4.1 修正网络层配置修复的第一步不是去数据库里改任何东西而是把hosts文件里错误的私有IP改回来。我先把/etc/hosts中rac2-private对应的IP改成192.168.10.12也就是与实际网卡绑定IP一致。同时确认节点1和节点2的hosts文件里都有正确的公网IP、私有IP、VIP映射。这一步千万不能只改单个节点RAC环境里所有节点的resolve方式必须一致否则其他节点的通信也会出问题。改完之后用ping rac2-private确认解析到的IP已经是192.168.10.12。同时重新执行oifcfg getif确认接口角色没有变化。有人会问要不要修改oifcfg里的接口信息如果接口名没变、子网没变只是IP解析错了其实是hosts的问题不需要动oifcfg。但如果网卡接口名真的变了比如从eth1变成enp3s0就需要用oifcfg重新登记接口信息oifcfg delif -global eth1 oifcfg setif -global enp3s0/192.168.10.0:private我这次没有走到这步因为接口名没变。真正要改的只有hosts文件和后续资源状态。4.2 清理和重置gipc相关资源网络配置修正后需要让gipcd进程按照新的地址重新初始化。这时不要直接重启整个操作系统可以先尝试重置gipc资源。操作过程如下先以root用户在rac2上停止整个集群软件栈crsctl stop crs停止后确认ohasd进程已经退出然后清理异常状态下残留的gipc相关信息。大多数情况下直接启动ohasd会让gipcd重新读取网络配置并启动但为了避免上次的错误状态残留在进程环境里我习惯先做一次“干净复位”。我执行了crsctl start crs然后观察crsctl stat res -t -init这次gipcd从OFFLINE变成了ONLINE。紧接着cssd、evmd等一系列初始化资源也开始逐步online。大概两三分钟后CRS集群状态恢复正常。这里有个很重要的确认点在重启CRS之前一定要确认hosts文件已经改好。如果hosts还是错的gipcd照样启动不起来反复重启只会让问题变成“第二次踩同一个坑”。4.3 验证集群恢复与HAIP状态集群起来后验证工作不能只看CRS状态还要确认数据库和ASM能够正常启动。先执行crsctl check cluster -all输出显示所有节点CRS运行正常。再执行crsctl stat res -t确认数据库实例、监听、ASM实例、VIP等资源都已经online。这时候我登录到rac2用sqlplus / as sysdba连上本地实例执行了下面这个查询确认节点间的集群互联地址已经正常建立select instance_name, name, ip_address, is_source from v$cluster_interconnects;结果里能看到多个HAIP地址这说明gipc已经成功在私网接口上建立了通信端点。业务侧接着做了测试之前跑不起来的存储过程任务也能正常调度。我随口让开发同事跑了一个分页查询脚本语句执行速度恢复正常数据库对外服务完全恢复。验证之后我又做了一次节点级重启测试确认rac2重启后能够自动拉起CRS并重新加入集群。这一步很有必要不然谁也不敢保证下次遇到类似情况还能顺利恢复。5. 避坑清单与实际运维建议5.1 导致gipc故障的常见诱因总结这次问题是因为hosts文件被改错但根据实际运维经验gipc出问题的诱因远不止这一种。我把常见场景整理成了一张速查表方便遇到类似问题时快速对号入座。诱因现象日志关键字段/etc/hosts中私有IP解析错误gipcd绑定的IP不在本机网卡上gipcd进程反复启动失败failed to bind to listen endpoint网卡接口命名变化oifcfg登记的接口名和系统实际接口名不一致unable to initialize network endpoint私有网卡IP地址冲突节点心跳间歇性中断gipc通信时断时续gipc: connection timed out防火墙拦截私有网段端口gipcd无法完成节点间握手集群资源启动停滞gipc: no receiving packets集群节点间系统时间偏差过大gipcd连接被判定为无效节点被驱逐gipc: clock skew detected日常维护中网络变更和操作系统升级是触发这类问题最多的两个时间点。尤其机房调整过交换机配置后一定要重新检查集群内部通信是否正常。5.2 日常巡检与健康检查命令经过这次故障我把gipc相关的检查动作纳入了固定巡检流程。推荐在维护窗口或者定期巡检时执行以下几项命令。第一检查接口登记信息oifcfg getif oifcfg iflist重点确认私有网卡的子网、接口名是否和系统实际情况一致。第二查看gipcd资源状态crsctl stat res ora.gipcd -t -init正常状态下STATE应该是ONLINE。如果长时间处于OFFLINE或INTERMEDIATE需要立刻查日志。第三定期扫描gipcd日志中的异常信息。可以使用简单的日志检索命令grep -E ERR|FATAL|failed|unable $GRID_HOME/log/$(hostname)/gipcd/gipcd.log发现ERROR级别以上的记录时要结合时间点分析是否有节点重启或网络变更。第四必要时检查v$cluster_interconnects视图确认HAIP地址列表是正常的。出现单个地址缺失或者地址异常漂移时先查gipc。5.3 遇到类似问题时的处理节奏最后聊一聊处理节奏。我发现很多人遇到CRS起不来第一反应就是重跑root.sh或者重建集群资源。这种冲动要压住。正确的顺序应该是“日志先行”。信息最全的永远在日志里尤其是gipcd.log和alert日志。先结合报错时间确认是网络问题、权限问题还是资源状态问题再有针对性地操作。像这次的问题如果盲目重建集群虽然也能恢复业务但会引入更大风险——OCR丢失、资源依赖关系被破坏、实例配置丢失任何一个都够喝一壶。我个人习惯是先看日志关键词再核对hosts和oifcfg最后才考虑要不要重启资源。绝大多数gipc问题都逃不过这三个环节。确认网络层无误后重启CRS顺理成章而不是在错误配置下反复重启碰运气。这次故障从发生到解决我最大的感受是RAC集群不是简单起个数据库服务底层通信链路任何一个环节出问题表面看起来都会像是数据库崩了。gipc恰恰又是容易被忽略的一环平时它默默工作一旦网卡变化、主机解析乱了就是集群起不来的那种致命伤。最后分享一个习惯机房做网络变更之后我都会先跑一遍oifcfg getif和crsctl stat res -t确认gipc、haip这些资源没有被偷偷改坏。很多时候少踩一个坑靠的就是这种小习惯。