ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Oracle 19c RAC健康检查与故障排查实战指南

Oracle 19c RAC健康检查与故障排查实战指南 接手一套 Oracle 19c RAC 环境之后最怕的不是节点挂掉而是不知道它什么时候、在哪个环节先出的问题。RAC 的本质是多个节点共享一套数据库节点之间的心跳、集群服务、监听、ASM 卷组任何一个环节出了状况都会让整个集群变得不可用。而排障时如果东敲一条命令西查一个日志往往越查越乱最后连问题出在哪个层面都说不清楚。这篇东西想解决的问题很明确怎么在最短时间内判定一套 19c RAC 多节点环境到底健不健康以及出问题时按什么顺序、用哪些命令快速定位。这份指南适合经常接触 RAC 的 DBA、刚接手 19c 集群的运维同学也适合那些需要给客户做应急响应的人。我会把实际排查时最常用的命令、输出判读方法、容易忽略的细节和踩过的坑整理出来按固定套路执行五分钟内基本能判断出集群状态。1. RAC 运行状态排查的整体思路1.1 为什么需要一套固定的排查路径RAC 环境里涉及的组件太多了。一套 19c RAC 至少包含 GIGrid Infrastructure层面的集群软件、两个节点上的数据库实例、SCAN 监听和节点监听、ASM 实例与磁盘组、OCR 和 Voting Disk还有公网、私网两套网络。任何一个组件出问题症状都可能表现为应用报错连不上某个节点 down 了数据库卡顿这类模糊现象。如果每次都是凭感觉从某一个现象开始查很容易陷入一个误区花大量时间在某个组件上排查结果发现根因在另一个层面。比如应用一直报连接超时你可能先去查监听查了半天发现监听正常最后才发现是某个节点被驱逐出了集群服务没有漂移过去。这种问题我在生产环境见过不止一次。固定的排查路径本质上是一条覆盖所有关键组件的检查链路按顺序走一遍任何一层有问题都会暴露出来。用一个生活化的类比体检。你不会因为嗓子疼就直接去做胃镜而是先量体温、看血常规、再根据指标异常去查具体器官。RAC 排查也是一样先看整体再逐层深入。这份指南的核心就是给你一套体检项目表。1.2 一次完整排查需要覆盖的五个层面我习惯把一次完整的 RAC 运行状态排查拆成五个层面每个层面都有对应的一组命令。这五个层面按依赖关系排列集群层在最底层实例层在上面然后是服务和监听接着是存储层最后用日志来验证和佐证判断。层面核心内容关键命令集群层CRS 进程、节点成员关系、资源状态crsctl check cluster -all、crsctl status resource -t实例层各节点实例是否 open、会话情况srvctl status database、v$instance服务与监听层SCAN、节点监听、服务状态srvctl status listener、lsnrctl status存储层ASM 实例、磁盘组空间与冗余asmcmd lsdg、v$asm_diskgroup日志层alert 日志、CRS 日志、监听日志各组件日志文件用于交叉验证这五层不是孤立的。比如实例起不来可能是 ASM 磁盘组不可用监听起不来可能是 OCR 里注册的资源状态不对。所以排查时必须带着上一层的结果会影响下一层的思路而不是机械地跑命令。2. 五分钟快速体检命令集2.1 用 crsctl 快速确认集群整体状态所有 RAC 排查的第一步一定是确认集群服务本身是否健康。crsctl check cluster -all会在所有节点上执行健康检查并返回每个节点的状态。正常输出的结尾一般是CRS-4537: Cluster Ready Services are healthy之类的结果如果某个节点异常会直接显示CRS-4535: Cannot communicate with Cluster Ready Services或类似报错。这个命令只给结果不给出细节。所以第二步要执行crsctl status resource -t把集群里所有资源的在线状态列出来。正常环境下ora.rac.db、ora.asm、ora.node1.vip、ora.scan1.vip、ora.listener 这些资源的 STATE 都是 ONLINE且分布在对应的节点上。如果有资源显示 OFFLINE、INTERMEDIATE 或 UNKNOWN就要看具体是哪个资源、属于哪个节点。提示crsctl status resource -t的输出里TARGET 列显示期望状态STATE 列显示实际状态。如果 TARGET 是 ONLINE 但 STATE 是 OFFLINE说明资源没有正常启动如果两边都是 OFFLINE可能是被人为 stop 了。这两者有本质区别。我在实际巡检时有个习惯先跑crsctl check cluster -all如果全部 healthy再跑crsctl status resource -t快速扫一遍资源状态。如果第一步就有节点报错直接进入对应节点的日志排查不用浪费时间去逐条看资源。2.2 数据库实例状态检查集群健康不代表数据库实例健康。19c RAC 环境下每个节点上都有一个实例任何一个实例 down 掉都会让客户端连接和负载分配出问题。检查实例状态最直接的方式是srvctl status database -d dbname -v输出会列出每个实例所在的节点、状态和角色。举个例子$ srvctl status database -d orcl -v Instance orcl1 is running on node node1, instance state: Open Instance orcl2 is running on node node2, instance state: Open如果看到 instance state 是 Started 而不是 Open说明实例进程起来了但数据库没有完成 mount 或 open这通常意味着存储或控制文件有问题。如果某个节点没有实例输出说明这个节点上根本没起实例需要检查实例进程或 GI 资源。用 SQL 查看也是常见做法。登录任意一个节点查询select inst_id, instance_name, status, host_name from gv$instance order by inst_id;可以一次看全所有实例状态。status列显示OPEN说明实例正常显示STARTED或MOUNTED说明处于中间状态。2.3 监听与 SCAN 监听状态应用连不上 RAC一半以上的根因在监听层面。19c RAC 环境有节点监听和 SCAN 监听两类。节点监听负责本机实例的本地连接SCAN 监听配合 SCAN VIP 实现客户端负载均衡和故障转移。检查命令是srvctl status listener它会同时列出所有监听资源及其状态。之后用lsnrctl status 监听名查看单个监听的详细情况包括服务注册列表、实例数量、当前连接数。正常状态下lsnrctl status里能看到每个实例的多个服务名注册比如orclXDB、orcl这些服务都有对应的实例在监听器注册表里。注意如果lsnrctl status显示 The listener supports no services 或者服务列表为空不代表监听本身挂了而是实例没有完成向监听的动态注册。常见原因包括 LOCAL_LISTENER/REMOTE_LISTENER 参数配置错误、网络不通、监听日志权限问题。这种状态最坑因为监听进程是活的但应用就是连不上。2.4 ASM 实例与磁盘组状态RAC 的数据文件、控制文件、参数文件基本都在 ASM 里ASM 状态直接决定数据库能不能正常读写。检查 ASM 常用两个入口一个是用 SQL 查v$asm_diskgroup另一个是进入 ASM 命令环境用asmcmd lsdg。asmcmd lsdg输出里最重要的是 State、Type 和 Usable_file_MB 三列。State 栏显示MOUNTED表示磁盘组已挂载Type 显示NORMAL、HIGH或EXTERNAL代表冗余级别Usable_file_MB 是扣除冗余之后实际可用的空间。如果某个磁盘组显示DISMOUNTED那数据库大概率已经出问题了。另外要关注磁盘组空间使用率。ASM 磁盘组空间用完时数据库会直接报 ORA-15041严重时所有写入都会失败。巡检时如果发现某个磁盘组使用率超过 85%就要提前规划扩容或清理别等到报错再处理。2.5 关键日志位置与命名规律排查 RAC 运行状态最终都要落到日志上。19c 的日志路径比早期版本更有规律都在$ORACLE_BASE/diag目录下。常用日志的位置如下数据库实例 alert 日志$ORACLE_BASE/diag/rdbms/dbname/SID/trace/alert_SID.logASM 实例 alert 日志$ORACLE_BASE/diag/asm/asm/ASM1/trace/alert_ASM1.logCRS 日志目录$GRID_HOME/log/hostname/下面有 crsd.log、cssd.log、evmd.log监听日志$ORACLE_BASE/diag/tnslsnr/hostname/listener/alert/log.xml或按listener_XXXX的监听日志目录这些日志的命名规律是固定的。多个节点之间日志格式一致排查时可以并行对比。后续的排障中这几个日志文件是核心证据来源后面的章节会展开讲怎么高效读它们。3. 核心状态视图与排查细节3.1 实例状态视图的进阶用法gv$instance和v$instance是最常用的两个视图但它们能看的东西差别不小。v$instance只显示当前登录实例的信息gv$instance聚合了所有实例的信息。在一个节点上执行gv$instance查询就可以确认每个实例是否都起来了、版本是否一致、当前 SCIN 是否一样。除了gv$instance还有几个视图值得关注。gv$active_instances显示当前参与集群工作的实例列表gv$services可以看每个服务在每个实例上的状态。多节点环境排查时我最常做的一件事是同时查这几个视图把实例、服务、节点对应关系全部拉出来select inst_id, instance_name, status, host_name, version, logins from gv$instance order by inst_id; select inst_id, name, name_id, active from gv$active_instances order by inst_id; select inst_id, name, pdb, failover_type, goal from gv$services order by inst_id, name;如果gv$instance里有实例状态不是 OPEN或者gv$active_instances里少了某个节点基本可以确定该节点的实例有问题。此时去对应的 alert 日志查 ORA- 错误是最高效的路径。3.2 OCR 与 Voting Disk 的健康确认OCR 和 Voting Disk 是集群的大脑和选票箱。OCR 存集群配置信息Voting Disk 负责节点成员仲裁。这两个组件出问题时集群可能频繁驱逐节点或者干脆起不来。检查 OCR 的命令是ocrcheck正常输出会显示 OCR 文件、Device、Status 为 AVAILABLE且 Total size 和 Used size 都在正常范围。如果出现PROT-601或者 Status 不是 AVAILABLEOCR 完整性有问题需要从自动备份中恢复。检查 Voting Disk 用crsctl query css votedisk。正常输出会列出所有 voting disk 的路径和状态且状态都是 ONLINE。如果某个 voting disk 显示 OFFLINE 或缺失说明该磁盘有问题。需要注意的是19c 环境下 voting disk 放在 ASM 磁盘组里查询命令会显示类似DATA的路径。提示不要轻易在集群正常运行时删除或添加 voting disk。每次变更后必须验证磁盘组冗余级别否则一旦某块盘故障整个集群可能全部停机。这个操作我建议只在维护窗口做并且前后都要执行crsctl query css votedisk确认。3.3 服务状态与应用连接排查RAC 环境通常按业务配置多个服务Service比如核心交易走oltp_svc报表走report_svc。服务状态直接决定应用能不能正常工作。检查命令是srvctl status service -d dbname。输出示例$ srvctl status service -d orcl Service oltp_svc is running on instance(s): orcl1, orcl2 Service report_svc is running on instance(s): orcl1 Service offlinesvc is not running.如果某个服务应该运行在两个实例上实际只在其中一个运行说明另一个实例上该服务注册失败。这时候要看服务的srvctl config service -d dbname -s 服务名配置以及实例上的监听注册情况。应用连接排查还要关注 SCAN 的解析情况。客户端连接 RAC 通常用scan-name:1521/orcl这种方式SCAN 解析到多个 SCAN VIP 实现负载均衡。排查连接问题时在客户端执行tnsping scan名称确认能够解析到所有 SCAN IP再确认监听有没有正常提供服务。如果发现 SCAN 只解析到一个 IP说明 SCAN 监听资源有问题或 DNS 配了多个 A 记录但没有轮询。3.4 会话、锁和负载角度运行状态排查不只是看进程起没起来还要看数据库能不能正常处理负载。多节点环境里一个节点的会话数异常或者某个节点出现了锁等待都会影响整体可用性。用gv$session查看节点分布和活动会话select inst_id, count(*), sum(decode(status, ACTIVE, 1, 0)) active_cnt from gv$session group by inst_id order by inst_id;正常情况下每个节点的会话数应该大致均衡。如果某个节点的活动会话数异常高另一个节点几乎没有除了连接配置问题也可能和某个节点的硬件性能、网络状况有关需要进一步排查。锁相关的排查用gv$lock和gv$session_wait。当应用报资源忙或卡死时先查有没有阻塞会话select blocking_session, sid, serial#, inst_id, event, wait_class, seconds_in_wait from gv$session where blocking_session is not null order by seconds_in_wait desc;阻塞查询的event通常是enq: TX - row lock contention或library cache lock这类拿到阻塞链之后定位源头会话并评估是否可以 kill。RAC 环境下这种锁问题往往跨节点因为一个节点的会话可能被另一个节点的会话阻塞单查本地v$session会漏掉信息所以必须用gv$视图。4. 常见问题与排查技巧实录4.1 节点被驱逐出集群的问题RAC 里最典型的故障就是节点被驱逐Node Eviction。症状是某个节点上的实例和资源全部 offline另外的节点正常。造成驱逐的原因通常有三类心跳网络中断、存储 IO 长时间 hang、节点时钟漂移。排查这种问题第一步先确认集群目前的状态用crsctl status resource -t看哪些节点的资源 offline。第二步看被驱逐节点上的crsd.log和cssd.log重点找Node eviction、LOST CONNECTION、IO latency、clock之类的关键字。第三步检查私网网卡状态、心跳链路的连通性和丢包率。时钟漂移是一个容易被忽略的原因。RAC 集群要求所有节点时间同步一般用 NTP 或 chrony。如果某个节点时钟跑偏超过几十毫秒就可能触发驱逐。我在一次生产故障里遇到过节点一切正常但每过几天就被踢出集群一次最后发现是 chrony 配置被某台新机器覆盖了。用timedatectl和chronyc tracking检查时间同步状态是排查这个问题的标准动作。4.2 监听异常但集群看起来正常有一种故障特别容易误导人crsctl status resource -t显示监听资源 ONLINElsnrctl status显示监听进程活着但应用就是连不上。这种情况十有八九是监听器服务注册列表异常或者监听日志文件被撑爆。先看监听日志。19c 默认的监听日志目录在$ORACLE_BASE/diag/tnslsnr/hostname/listener/alert/log.xml如果磁盘空间满了或者日志文件损坏监听会拒绝新连接但不影响已有连接。另外检查监听端口是否被占用的经典命令是netstat -anp | grep 1521确认监听确实在监听预期的地址。还有一种情况是 hosts 文件解析问题。RAC 环境里/etc/hosts必须正确配置所有节点的公网和私网地址如果私网主机名解析到错误地址节点间的监听注册就会出现奇怪现象。这类问题排查到最后往往是简单因素某个节点的 hosts 文件被改动了。4.3 实例启动失败与 ORA- 错误定位实例起不来是 RAC 排障的另一大类问题。常见错误包括 ORA-01157数据文件无法识别、ORA-15081ASM 磁盘组未挂载、ORA-29701集群无法识别实例等。定位这类问题的步骤很有规律先用srvctl start instance -d dbname -i 实例名尝试启动然后立刻去查该实例的 alert 日志尾部。alert 日志会记录启动过程中遇到的第一个致命错误这个错误往往就是根因。比如 ORA-01157 后面通常会紧跟着 ORA-01110明确指出是哪个数据文件有问题。另一种情况是实例已经被注册到集群里但启动时由于参数文件位置不对起不来。19c RAC 常用 spfile 放在 ASM 里如果 ASM 磁盘组没挂载spfile 读取失败实例就起不来。此时先去查 ASM 的 alert 日志确认磁盘组状态再回头处理数据库实例。4.4 日志交叉验证技巧单独看一个日志经常不够我习惯把实例 alert 日志、ASM alert 日志和 crsd 日志按时间线对齐看。比如实例报 ORA-15081 可能是 ASM 实例先挂了导致的那 ASM 日志里会有关键的错误记录而 ASM 挂掉可能又是磁盘组里某块盘坏了这在v$asm_disk里能查到。三层日志对时间戳很容易把因果链拼完整。日志文件都很大直接用编辑器打开搜很费劲。我常用的命令# 查看实例 alert 日志最后 200 行重点是行首有 *** 分隔块的最后一次内容 tail -200 $ORACLE_BASE/diag/rdbms/dbname/SID/trace/alert_SID.log # 按时间过滤某段日志通常用前一天 20:00 到当前时间 awk /2026-04-06 20:00/,/2026-04-07 08:00/ alert_SID.log # 搜索包含 ORA- 的行 grep -n ORA- alert_SID.log | tail -30还有一个实用技巧alert 日志里以***开头的分隔块代表一次事件比如实例启动、shutdown、错误记录。用grep -n ^\*\*\* alert_SID.log | tail -10可以快速找到最近的几次关键事件再定位到对应时间块细看效率比从头翻到尾高很多。5. 实操笔记一套可落地的巡检与应急脚本5.1 每日巡检命令组合与其每天手动敲一遍命令不如把稳定的检查项写成脚本。我在生产环境用的巡检思路很简单按集群、实例、监听、ASM 四个维度把命令串起来输出重定向到文件再用颜色区分正常和异常。一段简化的核心命令组合如下GRID_HOME/u01/app/19.0.0/grid ORACLE_HOME/u01/app/oracle/product/19.0.0/dbhome_1 DB_NAMEorcl # 1. 集群状态 $GRID_HOME/bin/crsctl check cluster -all # 2. 资源状态 $GRID_HOME/bin/crsctl status resource -t # 3. 数据库实例 $GRID_HOME/bin/srvctl status database -d $DB_NAME -v # 4. 监听状态 $GRID_HOME/bin/srvctl status listener # 5. ASM 磁盘组空间 $ORACLE_HOME/bin/sqlplus -s / as sysasm EOF set lines 200 col name format a15 col state format a10 col type format a10 select name, state, type, usable_file_mb, total_mb from v\$asm_diskgroup; exit EOF # 6. OCR 检查 $GRID_HOME/bin/ocrcheck把这段脚本放到所有节点上用 cron 每天定时执行并输出到/tmp/rac_check_$(hostname).log。第二天上班扫一眼各节点的输出重点关注有没有OFFLINE、ERROR、FAILED这类字眼。这套逻辑很基础但确实能防住绝大多数小问题拖成大故障的场景。5.2 应急排障的执行顺序如果脚本输出异常或者应用已经报障排障顺序要遵循从底层到上层、先集群后实例的原则。我总结了一套四步走的应急套路先看集群成员crsctl check cluster -all确认所有节点在线。如果节点被驱逐立刻定位驱逐原因而不是急着把实例拉起来。再看资源状态crsctl status resource -t找出异常的资源。重点关注数据库、监听、VIP、ASM 这几类关键资源。然后看实例与日志如果数据库资源异常查srvctl status database和对应实例的 alert 日志如果监听资源异常查监听状态和监听日志。最后看存储asmcmd lsdg确认磁盘组挂载和空间因为存储层面是很多实例故障的下游根本原因。这四步走完绝大多数问题能定位到具体组件。剩下的是跨组件的复杂问题比如网络波动导致的心跳丢失、存储路径问题导致的 IO hang这些就需要结合系统层的dmesg、网络日志、存储告警做进一步交叉验证了。提示应急排障时切忌反复重启。很多 DBA 看到节点 down 就crsctl stop cluster -all然后重新 start结果重复触发相同的故障。合理做法是先采集日志证据确认根因后再恢复。除非是明显的进程僵死否则先取证、后恢复是生产环境排障的底线原则。最后再分享一点个人体会我在生产环境折腾 RAC 排障这几年最大的感受是RAC 出故障不可怕可怕的是没有一套固定的排查逻辑。很多时候问题之所以拖成事故是因为排查的人在不同的节点、不同的日志、不同的工具之间来回跳信息越看越乱。把这套集群层 → 实例层 → 监听层 → 存储层 → 日志层的顺序跑熟遇到任何 RAC 运行状态异常心里都会有一个清晰的路线图。另外日常巡检的人一定不要只盯着crsctl status resource -t这个单一输出。它确实是最快的入口但 ASM 磁盘组空间、监听服务注册列表、实例 alert 日志里的隐性错误这些慢变量才是一套 RAC 能否长期稳定运行的关键。把这套五分钟体检变成肌肉记忆你的 19c RAC 环境就能多一分确定性。
返回列表