
在数据库运维领域Oracle RAC被广泛视为高可用的代名词。当集群中的一个节点因硬件故障宕机时理论上存活的节点应当无缝接管所有服务业务几乎不受影响。然而现实中的故障往往比理论复杂得多。本文记录了一次真实的生产环境Oracle RAC集群故障。故障发生时节点2因硬件故障彻底失效节点1虽然存活却无法对外提供数据库服务RAC的高可用架构形同虚设。整个故障排查过程经历了多次转折最终在操作系统层面找到了根因而此前DBA团队和AIX专家团队都曾在不同环节陷入困境。这不是一个技术选型优劣的讨论而是一次关于如何在复杂分布式环境中定位集群故障的完整演练。故障现象、分析路径、根因定位和预防措施每一个环节都值得运维人员深入思考。一、故障现象RAC高可用为何形同虚设1.1 集群架构与环境描述该系统的运行环境为IBM AIX 5.3操作系统部署了Oracle 10.2版本的双节点RAC集群底层存储采用HACMP加裸设备的架构。这是一个典型的企业级核心业务系统部署方式RAC加HACMP的双层集群架构在当时被视为高可用的标准方案。由于系统已上线运行较长时间运维团队对高可用机制形成了稳定预期当某个节点出现故障时另一个节点应能够自动接管所有服务业务影响应控制在最小范围。正如行业专家在分享中提到的不少DBA会拍着胸脯说没事这是Oracle RAC还有一个节点呢只要该节点可以扛住负载完全可以正常对外提供服务。但现实往往比这句承诺复杂得多。1.2 故障触发与初始表现下午16点01分RAC集群节点2所在的P595小型机发生硬件故障导致该节点所在的LPAR不可用。按照RAC的设计原理节点2上的VIP和数据库服务应由节点1自动接管。然而从16点01分开始应用程序无法连接到集群中存活的节点1。DBA团队尝试通过sqlplus以sysdba身份连接到节点1的数据库连接操作直接挂起无任何响应返回。更令人警觉的是运维人员尝试使用sqlplus -prelim / as sysdba附加到数据库这种带-prelim参数的连接方式在数据库异常时通常仍能成功但本次尝试同样挂起。这一现象极为罕见正如案例分析的记录所言加了-prelim参数连接到数据库也hang是很罕见的情况。1.3 一个信号叠加一个信号团队尝试通过crsctl stop crs -f命令停止节点1的CRS命令挂起无法结束。进一步尝试通过shutdown -Fr重启操作系统同样挂起最终只能通过HMC强行重启分区才使业务恢复。存活节点上的连接命令挂起说明问题不仅局限于数据库层面。CRS命令无法停止操作系统重启命令也无法执行这表明故障已从数据库扩散到了操作系统核心层面。在一篇类似的RAC故障分析中也提到通过crsctl stop crs -f命令停止节点1的CRS命令挂起无法结束通过shutdown -Fr重启操作系统命令挂起最终通过HMC强行重启分区才使业务恢复。这不禁让人反思就像有经验的DBA指出的那样建议DBA在处理数据库异常的问题时跳出对数据库本身异常日志内容分析的范畴要从操作系统、服务器硬件甚至更高的视角来分析整个异常现象。因为在很多公司DBA和SA各司其职界面分工比较清楚但是在处理尤其是集群环境的异常时却很容易发生互相甩锅的情况最后失去了发现问题源头的机会。二、初步排查三张日志中寻找线索2.1 数据库集群层的分析DBA团队首先检查了节点1的数据库alert日志试图确认RAC集群是否完成了重组。日志中有一个关键信息RAC集群在16点01分32秒左右即完成了重组。集群级别的融合机制并未出现问题节点间的通信与数据重组正常完成。但alert日志正常只能说明RAC本身的协同机制正常工作无法解释为什么存活节点无法对外提供数据库服务。2.2 CRS集群软件层的分析排查方向转向CRS日志。由于节点2已宕机按设计节点2的VIP应漂移到节点1。通过netstat -in命令检查发现节点1上并未出现节点2漂移过来的VIP。CRS日志中出现了关键错误信息。CRSD进程在尝试接管节点2的VIP和数据库资源时调用racgwrap脚本进行check、start和stop操作均出现timeout超时。同一份日志中节点1自身VIP的健康检测也出现了超时。racgwrap脚本出现timeout通常有两种可能原因操作系统性能严重下降导致大量内存换页或脚本执行过程中出现命令挂起。单纯从CRS日志看问题源头指向操作系统层面。2.3 HACMP集群层的检查HACMP集群日志未发现明显异常集群软件未报告故障未触发异常切换。这条线索看似排除了HACMP的嫌疑但在后续的根因分析中这条线索却成了误导团队的一个重要因素。三层集群日志检查完毕后CRS超时指向操作系统但AIX专家检查后认为操作系统运行正常crontab脚本仍有输出证明OS并未整体挂起。在CRS日志提供线索却被AIX专家否定后DBA团队意识到要在操作系统层面证明异常需要找到更具说服力的证据。三、穷追不舍操作系统层次的根因定位3.1 一个被忽略的监控脚本DBA团队重新梳理了所有证据将焦点转向了nmon性能数据在故障时间点后停止写入这一细节。在检查相关的监控shell脚本时发现了一个关键规律脚本每次执行到检查文件系统状态的输出语句后便停止未写入表示脚本正常完成的关键字。深入查看脚本源码后发现该位置调用的是df命令。在NFS文件系统挂载点不可达的情况下df命令会挂起。检查系统挂载信息确认了猜想节点2的/arch3目录确实通过NFS挂载到了节点1的/arch3目录上。当节点2因硬件故障不可用后NFS server随即不可达节点1上任何试图访问/arch3目录的操作都会挂起。行业的案例分析中也记录了完全一致的发现XX系统数据库集群中使用了NFS文件系统将节点2的/arch3文件系统通过NFS挂载到了节点1的/arch3文件系统上。当节点2出现硬件故障后导致节点1无法与节点2的nfs server通讯继而导致节点1上df命令查看文件系统时挂起。3.2 重新解释所有现象至此所有异常现象都可得到合理解释。sqlplus及sqlplus -prelim连接挂起的原因在于执行连接数据库操作时Oracle需要获取当前工作目录。AIX某些版本中pwd命令的实现存在缺陷必须递归到根目录下检查每个目录的权限和类型。当检查到NFS挂载点时由于以hard方式挂载且server不可达操作挂起继而导致整个连接过程无法完成。CRS脚本无法执行接管操作同样是因为调用了pwd命令或cd命令同样的NFS阻塞导致脚本超时。kill -9无法终止进程也是同样的根因进程正在进行NFS I/O操作已处于不可中断状态无法接收终止信号。nmon数据停止写入是因为nmon脚本调用了df命令被相同的NFS挂载点阻塞。在Linux内核的邮件列表历史讨论中也有类似的跨平台NFS兼容性问题被报告过AIX 4.1客户端在使用pwd命令时会出现pwd: The file access permissions do not allow the specified action的报错原因指向NFS mount点处理上的实现差异。3.3 根因确认与版本差异在高版本AIX上通过truss命令跟踪发现pwd命令不再递归扫描根目录因此无法在测试环境重现该问题。经IBM官方确认该问题属于AIX特定版本的缺陷后续版本已通过APAR修复。根因在于两个因素叠加AIX低版本pwd实现上的缺陷以及关键文件系统使用NFS挂载带来的单点风险。四、经验教训与预防措施4.1 问题根源NFS的隐患当节点2宕机后节点1上以hard方式挂载的NFS文件系统无法访问任何涉及该挂载点的文件系统操作都会无限期挂起。ping命令不受影响crontab脚本中的其他命令如果未涉及该目录仍能运行但这些不足以证明操作系统整体正常。RAC的Cache Fusion机制虽然强大但NFS层的单点故障可以绕过所有集群层面的容错机制直接引发操作系统级的命令挂起。4.2 架构层面的改进建议基于本案例的教训可以总结出几项架构层面的改进建议避免使用NFS挂载关键目录。对于需要跨节点共享的目录应考虑使用集群文件系统或ASM等专为集群设计的存储方案。如Oracle官方文档所述使用NFS存储数据库文件时需要关注NFS协议版本和支持的I/O特性比如Direct NFS Client支持NFSv3、NFSv4和NFSv4.1协议来访问NFS服务器。若确需使用NFS应将挂载方式从hard改为soft并设置超时参数防止server不可达时客户端进程无限挂起。操作系统版本需保持更新。对于关键依赖的底层机制及时应用操作系统补丁。定期进行高可用演练验证故障切换的真实效果而非仅凭理论判断。正如一位行业专家所警示的虽然系统上线前做过RAC高可用测试但是当集群中的一个节点长时间运行包括CPU、内存、进程数在内的负载在不断变化并且又经历了一些列变更后期间又没有再做过高可用测试这样的情况下如果RAC一个节点所在的分区/服务器宕掉的时候你是否依然可以拍着胸脯坚定的说我的Oracle RAC其他的节点一定可以正常对外提供服务4.3 ADG RAC场景的额外考量对于运行Active Data Guard的场景节点宕机时还需要考虑ADG的特殊行为。如果ADG RAC备库中负责apply redo的实例进程异常终止其他所有处于open read only状态的实例也会被关闭并回到mount状态导致所有ADG查询断开。MOS文档对此的解释是如果redo apply实例在media recovery过程中崩溃它会在幸存实例上留下RAC cache fusion锁磁盘上的数据文件也可能处于in-flux状态。此时在幸存实例上的查询可能看到不一致的数据因此需要关闭整个备库。在第一个实例重新打开时buffer cache和数据文件会重新达成一致。从12.1版本开始ADG instance recovery特性可以自动处理此问题避免影响其他实例。在11.2.0.4版本中通过安装较新PSU并设置隐藏参数_adg_instance_recoveryTRUE也可启用该特性。4.4 运维管理的补充DBA在排查集群故障时应对操作系统层面的现象保持警觉。sqlplus -prelim命令挂起是一个极其强烈的信号表明问题出在操作系统核心层面而非数据库层。当多个专业团队对同一故障现象给出不同判断时应回到基础原理层面从最底层的证据出发重新推演。本次故障中nmon停止写入和df命令挂起这两个证据最终成为解开所有谜团的关键。值得注意的是除了NFS导致的hang问题Oracle集群故障还可能由其他操作系统层面的因素引发。例如另一篇RAC故障分析中指出当一个节点因大量高耗SQL导致IO耗尽主机无法响应网络通信失败节点网络心跳超时也会触发主机重启。这意味着运维人员需要同时关注应用负载特征和存储网络架构的稳定性。在实际生产中出现Oracle RAC高可用失效的情况并不少见且表现形式多样。在某些案例中节点因硬件原因crash后另一个节点也可能自动切换到mount状态而非保持open中断所有只读业务需要人工介入才能恢复。这进一步印证了一个观点RAC的高可用能力需要在完整的运维体系保障下才能兑现。结语这次RAC高可用失效案例揭示了运维领域中一个容易被忽视的真相多层次的集群架构无法自动消除单点故障它们只是将故障点从数据库层转移到了更底层的组件。NFS文件系统挂载本身是生产系统中的常见操作但当它与操作系统版本的特定缺陷相遇再加上RAC节点的硬件故障三者叠加便足以让整套高可用架构彻底失效。在分布式系统的运维中真正的稳定不是靠某个工具单点保障的而是靠对每一个潜在隐患的持续排查和消除。节点2的硬件故障是偶然的AIX版本的缺陷是已知的NFS挂载点的使用是可以避免的。当这三者的交集恰好出现在同一时刻故障的发生就已不再是偶然。高可用不只是一个技术名词它需要被验证、被测试、被审视。正如一位DBA在其案例总结中所言DBA在处理数据库异常时要从操作系统、服务器硬件甚至更高的视角来分析整个异常现象。跳出技术栈的局部视野从系统全局审视每个潜在的故障点才是避免下一次灾难的根本之道。