☰
PRCR-1079/CRS-5017/ORA-12547 一条启动链排查
2026/10/19 5:36:24 网站建设 项目流程

前阵子调试一台即将承载 ASM 存储的数据库服务器,图形化安装 Oracle 11g R2 的 Grid Infrastructure,流程走到最后一步,界面提示需要以 root 身份执行配置脚本。我按惯例把 root.sh 跑起来,结果等了几分钟,返回的错误列表里同时躺着 PRCR-1079、CRS-5017、ORA-12547 三个报错。当时第一反应是“完了,是不是又要从头装”。但冷静下来把三行错误码连起来看,发现它们根本不是三个独立故障,而是一条启动链上断裂的三个环节,真正的根因大概率只有一个。

这篇文章把我当时的排查思路完整梳理一遍:每个错误码到底在说什么、日志去哪看、先查什么后查什么、最后怎么把 root.sh 顺利跑通。如果你也在做 RAC 或者单机 ASM 安装,卡在图形界面最后一步,希望这篇能帮你少走几趟弯路。

1. 先认清三个错误码之间的关系

1.1 图形化安装最后一步究竟在做什么

装 Grid Infrastructure(也就是集群软件 + ASM 服务)和单纯装数据库软件不一样,它不是一路点“下一步”就完事的纯复制操作。安装向导把二进制文件复制到 $GRID_HOME 后,会停在一个“执行配置脚本”的界面,要求你切到 root 用户,去跑 $GRID_HOME 下的 root.sh。这一步承担的工作非常重:初始化本机集群配置、创建注册信息、启动 OHASD 守护进程、拉起 CSS 服务、加载 OCR 和 Voting Disk、注册 CRSD,最后再启动一批资源。

我习惯把它类比成新房子第一次通电。root.sh 不是在某个开关上按一下就亮灯,而是要把总闸、分闸、各路电线全部检查一遍——只要有一路短路,整个楼都会黑掉。你看到的 PRCR-1079、CRS-5017、ORA-12547,就是这一路一路检查过程中暴露出来的问题。

1.2 三个错误码不是三件事,而是一条链

先给不熟悉这三个码的读者做一张对照表:

错误码字面含义实际触发点
PRCR-1079Failed to start Oracle Clusterware stack集群软件栈整体启动失败,多半由 root.sh 或 crsctl 触发
CRS-5017Unable to communicate with CSS daemon无法与 CSS 守护进程通信,OHASD 之后的关键组件没起来
ORA-12547TNS:lost contact某个客户端尝试连接 ASM 实例时,链路中途断开

三者的关系是这样的:PRCR-1079 是“总表现”,说明集群软件栈整体没能启动成功;CRS-5017 是“核心症结”,因为 CSS 在集群栈里负责节点心跳、锁管理,它一旦没就位,后面的 CRSD 和资源全都起不来;ORA-12547 则是“连带伤害”,ASM 实例依赖集群栈,栈没起来,实例自然不存在,任何尝试连 ASM 的动作都会断线。

新手最常见的失误,是把这个错误当成三个独立故障去修:一看到 ORA-12547 就去折腾监听器,看到 CRS-5017 就反复重启机器,看到 PRCR-1079 就想重装系统。结果折腾半天,一个都没修好,因为它们的根在同一个地方:集群软件栈没有正常启动。

1.3 所有排查都要从日志开始

这三个报错其实已经把线索指向“启动集群栈”这半个环节了,但具体卡在哪一步,必须看日志,不能靠猜。我每次遇到这类问题,固定会按下述路径翻日志:

  • root.sh 执行日志:$GRID_HOME/cfgtoollogs/crsconfig/rootcrs*.log,重点搜 ERROR、SEVERE
  • OHASD 日志:$GRID_HOME/log/主机名/ohasd/ohasd.log,看初始化和启动过程
  • CSSD 日志:$GRID_HOME/log/主机名/cssd/ocssd.log,看 CSS 为什么起不来
  • CRSD 日志:$GRID_HOME/log/主机名/crsd/crsd.log,看资源注册情况
  • ASM 实例告警日志:$GRID_HOME/diag/asm/+asm/主机名/trace/alert_主机名.log

root.sh 跑得慢不一定是失败。执行过程中,可以先tail -f观察 rootcrs.log 尾部有没有新内容持续写入,只要日志在推进,就说明脚本还在干活;如果超过 15 分钟没有新行,再判定为卡死。拿到日志后,用grep -E "ERROR|SEVERE|PRCR-1079|CRS-5017|ORA-12547"快速定位异常行,再顺着异常行的上下文往下读,比从头到尾翻一遍日志高效得多。

2. 环境配置的两座大山:hosts 解析和内核参数

2.1 /etc/hosts:主机名解析错位是最容易撞上的墙

在正式分析集群日志之前,我建议你先花两分钟检查环境配置,因为大量安装阶段集群起不来的案子,最后都栽在 /etc/hosts 上。Oracle 集群对主机名解析异常敏感,主机名必须能解析到实实在在的网卡 IP,而不是回环地址。

我当时的检查命令就这四条:

hostname uname -n cat /etc/hosts getent hosts 主机名

理想的输出应该满足三点:hostname 和 uname -n 结果一致;/etc/hosts 里 127.0.0.1 只对应 localhost 之类的回环名;主机名对应的是实际业务网卡 IP,比如 192.168.x.x。

最常见的错误写法,是把第一行写成127.0.0.1 主机名。这么一来,集群软件解析主机名时得到的地址永远是回环地址,节点间通信直接乱套。另一种情况是服务器有公网和私网两块网卡,hosts 里只写了公网 IP,私网 IP 没登记,导致集群内部的私有心跳找不到对端。如果你用的是多节点 RAC,这类问题会更早爆发,但单机 ASM 环境同样可能因为主机名解析回环而卡在 root.sh。

2.2 内核参数与共享内存:数值不达标,起不来就是起不来

主机名没问题之后,下一个高发坑是内核参数不满足要求。安装界面的“先决条件检查”其实会列出不合格项,但很多人会忽略警告直接继续安装,等到了 root.sh 阶段,问题才集中爆发。

我会重点核对这几个参数:

sysctl -a | grep -E "kernel.sem|kernel.shmall|kernel.shmmax|fs.aio-max-nr|net.core.rmem_default|net.core.wmem_default|net.ipv4.ip_local_port_range"

以 11g R2 的通用参考值为例:

  • kernel.sem:推荐为 250 32000 100 128 左右
  • kernel.shmall 和 kernel.shmmax:建议按物理内存的一定比例设置,shmall 至少要保证能容纳大页和 SGA 需求
  • fs.aio-max-nr:建议 1048576 或更高,AIO 请求数不够时 ASM 实例启动会报错
  • net.ipv4.ip_local_port_range:建议 9000 65500 左右,保证建连时端口充足

修改 /etc/sysctl.conf 后执行sysctl -p让参数生效。这里有个容易忽略的点:同一台机器上如果之前装过其他数据库软件,或者系统模板里做过裁剪,内核参数很可能被人为改过。不要只看安装向导的“检查通过”就放松,那是它检查时刻的快照,实际启动集群栈用到的是当前内核态。

2.3 依赖包、/dev/shm 和磁盘空间:容易被略过的小门槛

环境检查里还有三个低调但致命的小项。

第一是依赖包。11g R2 在 Linux 上要求一批基础包,比如 libaio、libaio-devel、glibc、unixODBC 等。缺包时 root.sh 会在很早期就弹错,而且错误信息经常是“权限不足”或者“命令找不到”,误导性很强。可以用rpm -qa | grep libaio的方式逐个核对。

第二是 /dev/shm。Oracle 的共享内存机制对 /dev/shm 有依赖,如果它被挂载得很小,比如只有几十 MB,OHASD 或者后续 ASM 实例的共享内存分配就会失败。执行df -h /dev/shm看一眼,通常建议挂载到物理内存的一半以上,或者至少满足 SGA 需求。

第三是磁盘空间。root.sh 运行过程要写大量日志和临时文件,$GRID_HOME、/tmp、/ 分区任何一个被塞满,脚本都会中途异常退出。执行df -h /tmp /u01 /检查余量。

我把环境检查放在日志排查之前,是因为这一步成本极低、命中率极高。很多时候你花一晚上翻 ohasd.log,最后发现根因就是 hosts 里多了一行回环解析,那真是亏大了。

3. 把集群栈手动拉一遍,从日志里揪出真凶

3.1 集群栈的启动链路:OHASD 是先决条件

环境扫完没问题,或者修复完环境问题之后,就该正式面对集群栈本身了。这一步的核心思路是:不要一上来就重跑 root.sh,而是手动执行启动命令,看它到底卡在哪一层。

11g R2 的集群栈启动链路大致是:

  • OHASD 负责把整个栈的守护进程拉起来,相当于管家
  • CSS 负责节点心跳和锁管理,是集群成立的基础
  • CRSD 负责资源调度,比如 ASM 实例、监听器、磁盘组
  • 资源按依赖关系逐个启动

在这条链上,OHASD 不起来,后面全免谈;OHASD 起来了但 CSS 通信不上,就会出现 CRS-5017。

3.2 手动启动来复现问题

以 root 用户执行:

crsctl start has crsctl check has crsctl check crs ps -ef | grep -E "ohasd|ocssd|crsd"

crsctl start has如果直接报 PRCR-1079,说明问题正好命中集群栈启动环节;crsctl check crs会逐项显示 CSS、CRS 的状态,如果 CSS 那行显示无法通信,就是 CRS-5017 的现场。

人工执行启动命令有一个好处:它能让你在一步之内区分“集群栈根本起不来”和“启动了但资源没起来”两种情形。模拟类问题(假设 root.sh 执行慢)和真实故障,在这个步骤下很容易分开。

3.3 真凶往往藏在 ohasd.log 和 ocssd.log 里

手动启动失败后,立刻去看对应日志。ohasd.log 里常见的几类根因我列一下:

  • 文件权限错误:日志目录属主不对,或者 $GRID_HOME 被 root 意外改过属主,导致进程无法写文件
  • 共享内存不足:普遍表现为 shmget 相关错误,指向 /dev/shm 配置问题
  • OCR 文件路径无效:安装向导阶段写入的 OCR 位置无法访问,导致 OHASD 初始化失败
  • 残留注册信息:/etc/oracle/scls_scr 目录下有旧配置,新配置识别成旧实例

如果 ohasd.log 显示 OHASD 已经起来了,但 ocssd.log 里出现通信异常,CSS 就是起不来。这种情况要检查三样东西:私网网卡的 IP 配置是否正确、voting disk 是否能被正常读取、节点之间的防火墙是否拦了集群端口。很多人以为 Linux 防火墙只影响外部访问,其实集群内部通信同样会被它拦,安装前就该把相关端口放行或临时关闭。

3.4 上一次失败留下的脏配置:重跑 root.sh 前必清

这里要专门提一个我在实际部署中最常遇到的情形:root.sh 第一次跑失败后,没有做任何清理,直接点界面上的“重试”,或者重新执行 root.sh,结果报错更复杂。

原因是 root.sh 并不是一个“原子操作”。它走到一半失败时,部分配置其实已经写到系统里了,典型的就是 /etc/oracle/scls_scr 目录下的注册文件。再次运行时,新流程扫描到这些残留,会认为“你已经配置过集群了”,然后拒绝继续,或者在冲突状态下执行。

正确的做法是清理后再跑:

$GRID_HOME/crs/install/rootcrs.pl -deconfig -force -verbose

这条命令会停止集群栈并清理注册信息。如果 deconfig 也因为集群栈起不来而执行不完整,可以先手动杀掉残留的 ohasd 等进程,再执行 deconfig。

还有一个细节容易被忽略:OCR 和 Voting Disk 如果用的是共享盘,deconfig 只清理软件层面的注册信息,不会自动把盘上的旧 OCR 数据抹掉。重复安装时,可能出现节点成员列表对不上、voting disk 版本不匹配等情况。必要时需要把 OCR 磁盘头清零,但这是一步高风险操作——执行前必须确认盘符一定是 OCR 盘,不是数据盘,最好先在磁盘管理层面把映射关系核对两遍。

4. ORA-12547 的真实含义:它几乎和监听器无关

4.1 lost contact 不等于监听坏了

如果你对 Oracle Net 不熟,看到 ORA-12547 的注释是 TNS:lost contact,第一反应大概率是去查监听器、tnsnames.ora。我在早期也犯过这个错,白白浪费了两个小时。

实际上,lost contact 的中文意思是“连接丢失”,它描述的是客户端和实例之间的链路在半途断了,至于断在哪,这个错误码本身并不说明。在安装配置阶段,绝大多数情况是:目标 ASM 实例根本不存在,配置助手发起的连接无法完成,链路直接被放弃,于是报 lost contact。

换句话说,你在界面上看到 ORA-12547,基本可以推断:集群栈还是没完全就绪,+ASM 实例没有起来。它只是把前面 CRS-5017 的后果在应用层暴露出来了。

4.2 修复后怎么验证 ASM 是否真的起来了

当集群栈那部分的 PRCR-1079、CRS-5017 都被解决之后,ORA-12547 通常会自动消失,但你不能只靠“界面不再报错”来下结论,应该主动验证 ASM 实例真实可用。

以 grid 用户执行:

crsctl stat res -t srvctl start asm -n 主机名 srvctl status asm asmcmd lsdg

crsctl stat res -t能看到 ora.asm 资源是不是 ONLINE;srvctl status asm能显示实例状态;asmcmd lsdg能进一步确认磁盘组能不能正常列举。如果 ASM 启动后又立刻退出,去 ASM 实例的 alert 日志里看具体报错,路径是 $GRID_HOME/diag/asm/+asm/主机名/trace/alert_主机名.log。

另外也顺手看一下监听器:lsnrctl status。ASM 的监听如果没起来,动态注册也会失效,一样可能导致连接类错误。虽然 ORA-12547 多数原因在实例,但监听器检查成本很低,别漏掉。

4.3 什么时候不用重装数据库软件

很多人在这个阶段慌起来,以为得把 Grid Infrastructure 卸载重装。我明确说:绝大多数情况不需要。只要根因是集群栈没起来,环境配置和残留清理的修复做完之后,安装界面上的配置助理是可以“重试”继续的,它会重新执行 ASM 实例创建、磁盘组配置这些步骤。

如果你在纯命令行环境,或者界面重试按钮已经失效,可以手动重跑配置助理命令。11g R2 安装过程中会生成一个记录所有配置命令的清单文件,位于 $GRID_HOME/cfgtoollogs/configToolAllCommands,里面保存了每一条本该由配置助理执行的命令,逐条以对应权限的用户执行即可。

真正需要重装的情况,通常只剩两种:一是 $GRID_HOME 里的文件权限被误操作搞得一团糟,二是 Oracle 二进制本身在复制阶段就损坏。否则,修好集群栈本身,没必要推倒重来。

5. 重跑 root.sh 的完整顺序清单

5.1 root.sh 重跑的正确姿势

当你判断环境已经修好、脏配置已清完、集群栈手动启动验证通过之后,就可以正式重新执行 root.sh 了。实际部署中我建议按下面的顺序来,不要打乱:

  1. 修复 /etc/hosts 解析、内核参数、依赖包、/dev/shm、磁盘空间等环境问题
  2. 以 root 执行$GRID_HOME/crs/install/rootcrs.pl -deconfig -force -verbose,清掉上一次失败的残留状态
  3. 确认 ASM 相关磁盘的属主和权限没问题(通常属主是 grid,用户组是 asmadmin)
  4. 以 root 执行$GRID_HOME/root.sh
  5. 观察 rootcrs.log 持续推进,直到出现资源启动相关日志及成功提示
  6. 最终验证:crsctl check crs、crsctl stat res -t、srvctl status asm、asmcmd lsdg

如果你的目标是 RAC 多节点,还要特别注意:第一个节点的 root.sh 必须先完整跑通,然后在第二个节点执行时,它才能正常加入集群并找到主节点。顺序乱了,后跑的节点就会一直卡着等心跳,看起来像是又出现 CRS-5017。

5.2 临场救命的三条经验

最后分享三条我自己的实战经验,都是在常规文档里不容易看到的。

第一条,执行 root.sh 时,如果担心黑盒看不懂脚本在干什么,可以直接用sh -x $GRID_HOME/root.sh跑一遍。这样每一步实际执行的命令都会打印在屏幕上,能很直观地看出脚本卡在哪个环节。当然,输出的信息量会非常大,建议配合tee同时落盘留存。

第二条,root.sh 执行期间千万不要因为“看起来没反应”就按 Ctrl+C。脚本在等资源启动时,单步超时可能长达几分钟,期间屏幕上无输出很正常。正确做法是tail -f日志,只要日志还在更新,就让它继续跑。贸然中断只会制造更多残留,把局面搞得更复杂。

第三条,学会用oifcfg getif检查网络接口配置。集群对网卡角色(public/private)有严格要求,如果 root.sh 阶段出现节点间通信异常,问题往往出在这里。手动执行这条命令看一眼网卡和子网,能少走很多弯路。

这套排查链路我从第一次踩坑到现在,已经验证过好几遍。只要图表里的三个错误码一起出现,九成以上都能按照“环境检查 -> 手动启栈 -> 清残留 -> 重跑 root.sh”的顺序解决。特别想再强调一次,root.sh 失败后最忌讳的就是不清理就直接“重试”,脏配置只会越叠越乱。宁可花十分钟把 deconfig 跑完,也别带着雷去赌一把运气。希望这份思路能帮正在面对同样报错的你,省掉几个小时的摸索时间。

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

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

立即咨询