1. 绪论:高可用性架构的初始化命门
Oracle Real Application Clusters (RAC) 作为企业级关键业务数据库的核心架构,其高可用性(High Availability, HA)并非源自单一组件的坚固,而是依赖于一套精密、多层级且高度自动化的软件堆栈——Oracle Grid Infrastructure (GI)。对于数据库管理员(DBA)和系统架构师而言,理解这一堆栈的启动序列(Startup Sequence)不仅是理论认知的需要,更是故障诊断(Troubleshooting)的基石。当一个集群节点重启后无法加入集群,或者整个集群在维护后无法启动时,能够在大脑中构建出一张清晰的“启动流程图”,并精准定位到故障发生的层级,是解决问题的关键。
从早期的 Oracle 10g Clusterware 到现代的 Oracle 19c Grid Infrastructure,该软件堆栈经历了从扁平化到分层化、从脚本驱动到守护进程驱动、从静态配置到动态即插即用(Grid Plug and Play)的根本性变革 。特别是在 19c 版本中,与 Linux systemd 的深度集成,引入了新的依赖关系和潜在故障点 。
本报告将基于 Oracle 10g 至 19c 的演进历程,深度解构 Grid Infrastructure 的启动流程。我们将剥离出每一层级的守护进程、代理(Agent)及资源依赖关系,构建一套严谨的诊断逻辑框架。通过对日志结构、关键配置文件(OLR, OCR, Voting Disk)以及系统级信号(Systemd targets, Socket files)的微观分析,本报告旨在为处理最复杂的启动故障提供详尽的技术指引。
2. 架构演进与进程层级体系
在深入诊断流程之前,必须建立对 Clusterware 架构演进的深刻理解。诊断策略的有效性取决于对“谁启动了谁”这一因果链条的掌握。
2.1 遗留架构(Pre-11gR2):扁平化设计的局限
在 Oracle 10g 版本中,Clusterware 的架构相对扁平。启动过程主要由 /etc/inittab 触发 init.crs 脚本,进而直接启动三个核心守护进程:CSSD (Cluster Synchronization Services Daemon)、CRSD (Cluster Ready Services Daemon) 和 EVMD (Event Manager Daemon) 。
-
控制机制:主要依赖
$ORA_CRS_HOME/scls_scr目录下的控制文件(如system.cssd,system.crsd)来管理进程的启停状态。 -
诊断局限:这种设计缺乏层级隔离。如果
init.crs脚本执行失败,或者某个核心守护进程(特别是 CSSD)崩溃,往往导致整个节点立即重启(Node Panic)。故障隔离性较差,日志也相对分散。
2.2 现代架构(11gR2 至 19c):分层与代理模型
从 11gR2 开始,Oracle 引入了革命性的 OHAS (Oracle High Availability Services) 概念,将集群软件划分为两个独立的层级:
-
OHAS 层(下层堆栈):负责节点的“自举”(Bootstrapping)。它不依赖于网络或磁盘心跳,仅依赖本地配置(OLR)。它的任务是让节点“准备好”加入集群。
-
CRS 层(上层堆栈):负责集群资源的管理(数据库、监听、VIP)。它依赖于 OHAS 层提供的网络和存储服务。
这种分层通过引入 Agent(代理)模型 实现了权限分离和故障隔离。守护进程(Daemon)不再直接启动资源,而是通过特定的 Agent 来执行操作:
-
orarootagent:以 root 权限运行,负责配置网络接口、加载驱动等高权限操作。 -
oraagent:以 grid 用户权限运行,负责管理普通集群资源 。
2.3 19c 与 Systemd 的深度融合
在 Oracle Linux 7/8 及 RedHat 7/8 上运行 Oracle 19c 时,传统的 SysV init (init.d) 启动机制已被 systemd 取代。虽然 $GRID_HOME/bin/ohasd 仍然是核心进程,但其生命周期由 oracle-ohasd.service 单元文件管理 。 这一变化意味着诊断的第一步不再是检查 init.ohasd 脚本的日志,而是使用 systemctl status oracle-ohasd.service 和 journalctl 来排查 OS 级别的依赖性故障(如文件系统挂载超时、cgroup 权限拒绝等)。
3. 深度解析:Grid Infrastructure 启动序列详解
启动过程是一个确定性的有限状态机(Finite State Machine)。我们将按照时间轴,将启动过程划分为七个关键阶段(Level),每个阶段都有其特定的先决条件(Prerequisites)、核心进程(Processes)和潜在故障点(Failure Points)。
3.1 Level 0: 操作系统引导与 Systemd 初始化
阶段目标:操作系统加载完毕,触发 Grid Infrastructure 的入口服务。
技术细节: 在现代 Linux 系统中,systemd 是 PID 1 进程。在多用户目标(multi-user.target)或图形界面目标(graphical.target)加载过程中,systemd 会加载 /etc/systemd/system/oracle-ohasd.service。
-
依赖关系:该服务通常配置了
After=syslog.target network-online.target remote-fs.target。这意味着如果网络服务未完全上线或远程文件系统(如 NFS 挂载的/u01)未就绪,OHASD 将不会启动 。 -
执行机制:Service 单元调用
ExecStart指令,通常指向/etc/init.d/init.ohasd run包装脚本。
诊断检查点:
-
命令:
systemctl list-dependencies oracle-ohasd.service -
日志:
journalctl -u oracle-ohasd -
常见故障:
-
Unit Masked:服务被禁用或 Mask。
-
Cgroup 权限错误:在 19c (19.3) 中,存在已知 Bug,即
init.ohasd脚本尝试向/sys/fs/cgroup/.../tasks写入 PID 时因权限不足而失败,导致服务反复重启并超时 。
-
3.2 Level 1: OHASD 守护进程初始化
阶段目标:启动集群软件的根进程 ohasd.bin,并加载本地配置。
技术细节: ohasd.bin 启动后,首先需要访问 OLR (Oracle Local Registry)。与 OCR 不同,OLR 存储在本地节点(通常是 /etc/oracle/olr.loc 指向的路径,如 $GRID_HOME/cdata/<hostname>.olr)。OLR 包含了启动 OHAS 层所需的所有资源定义(如 GPNPD、CSSD 的路径和参数)。
诊断检查点:
-
进程检查:
ps -ef | grep ohasd.bin。注意,系统中应存在ohasd.bin reboot进程。 -
日志位置:
$GRID_HOME/log/<node>/ohasd/ohasd.log。 -
常见故障(Case 1):
-
OLR 损坏或丢失:如果 OLR 文件不可读,
ohasd会在日志中记录OHAS00106: Failed to initialize Oracle Local Registry并退出。此时需使用ocrconfig -local -restore进行恢复 。 -
Socket 权限问题:
ohasd在/var/tmp/.oracle(或/tmp/.oracle)目录下创建 IPC 套接字文件。如果这些文件由错误的用户(如之前的 root 安装遗留)拥有,ohasd将无法绑定 socket,导致启动失败(Error:ORA-27504,CRS-4535).
-
3.3 Level 2: OHASD 代理 (Agents) 孵化
阶段目标:ohasd 并不直接干活,它通过孵化四类代理进程来管理下层资源。
技术细节: ohasd 根据 OLR 中的配置,启动以下 Agent:
-
orarootagent(Root 权限):负责管理需要 root 权限的底层驱动和守护进程(如加载 ACFS 驱动、启动ctssd、crsd)。 -
oraagent(Grid 用户权限):负责管理网络发现(mDNS)、GPNP、EVMD 和 ASM 实例。 -
cssdagent:专门负责启动和监控ocssd。它持有至关重要的“IO Fencing”逻辑,一旦发现ocssd挂死,它将负责重启节点(Reboot Node)。 -
cssdmonitor:辅助监控节点健康状况 。
诊断检查点:
-
进程检查:
ps -ef | grep agent。应看到分别属于 root 和 grid 用户的 agent 进程。 -
日志位置:
$GRID_HOME/log/<node>/agent/ohasd/oraagent_grid/和orarootagent_root/。 -
常见故障(Case 2):
-
Agent 二进制损坏:如果
oraagent.bin损坏,日志中会出现CRS-5802或 Segfault 错误。 -
资源组依赖失败:Agent 启动后会尝试启动其负责的资源。如果资源配置错误(如日志目录权限不对),Agent 会报告资源启动失败。
-
3.4 Level 3: 集群基元构建 (Cluster Primitives)
阶段目标:建立节点身份、网络通信和时间同步。
技术细节: 由 Agent 启动的一系列守护进程开始工作:
-
mdnsd(Multicast DNS):提供集群私网内的名称解析服务。 -
gpnpd(Grid Plug and Play Daemon):读取并分发 GPnP Profile (profile.xml)。该文件至关重要,它包含集群名称、网络接口定义、ASM 磁盘发现字符串(Discovery String)以及 Voting Disk 的位置签名 。 -
gipcd(Grid IPC Daemon):负责管理私网通信,支持冗余互联(HAIP - High Availability IP)。它接管了操作系统层面的 bonding 工作,提供负载均衡和故障切换 。 -
ctssd(Cluster Time Synchronization Service):负责节点间的时间同步。如果发现 NTP 配置,它将运行在观察者模式(Observer Mode);否则运行在活动模式(Active Mode) 。
诊断检查点:
-
日志位置:
gpnpd.log,gipcd.log,mdnsd.log。 -
常见故障(Case 5 & 6):
-
GPnP Profile 丢失:如果
gpnpd无法读取 profile,集群无法确定 Voting Disk 位置。 -
HAIP 故障:如果
gipcd无法在私网接口上创建 HAIP 地址(169.254.x.x),后续的 CSSD 将无法通信。需检查物理链路和防火墙设置。
-
3.5 Level 4: 集群成员资格构建 (CSS & Voting)
阶段目标:ocssd 启动,通过表决盘(Voting Disk)和网络心跳建立集群成员关系。
技术细节: cssdagent 启动 ocssd.bin。ocssd 执行以下逻辑:
-
从 GPnP Profile 获取 Voting Disk 位置。
-
访问 Voting Disk(通常位于 ASM 磁盘头)。
-
通过私网发送网络心跳(Network Heartbeat)。
-
向 Voting Disk 写入磁盘心跳(Disk Heartbeat)。
-
如果获得多数票(Voting Quorum),节点加入集群.
诊断检查点:
-
日志位置:
$GRID_HOME/log/<node>/cssd/ocssd.log。这是排查节点驱逐(Eviction)的核心日志。 -
常见故障(Case 3):
-
Split Brain(脑裂):如果私网中断,节点间无法通信,集群将分裂。拥有 Voting Disk 数量多(或节点号小)的子集群存活,其他节点被驱逐(Reboot)。日志中会显示
clssnmPollingThread: node <N>... heartbeat fatal. -
Voting Disk 不可访问:如果存储路径故障,无法读取 Voting Disk,
ocssd将因无法仲裁而终止。
-
3.6 Level 5: 存储层启动 (ASM)
阶段目标:启动 ASM 实例,挂载磁盘组,为上层应用提供存储服务。
技术细节: 在 11gR2+ 中,ASM 实例是由 OHASD 的 oraagent 管理的资源。
-
Flex ASM (12c/19c):在 Flex ASM 架构中,ASM 实例可能不在本地运行,而是通过网络连接到远程节点的 ASM 实例(ASM Client/Server 模式)。但对于本地 CRSD 的启动,必须确保存储服务可用 。
-
ASM 启动依赖:ASM 实例依赖于 CSSD(作为 ASM 的客户端需要注册到 CSS)。ASM 启动后,会挂载参数文件中指定的磁盘组(特别是包含 OCR 的磁盘组)。
诊断检查点:
-
日志位置:ASM 实例的 Alert Log (
$ORACLE_BASE/diag/asm/+asm/+ASM1/trace/alert_+ASM1.log)。 -
常见故障:
-
ORA-15032 / ORA-15077:无法发现磁盘或磁盘组挂载失败。
-
ASMLib/AFD 加载顺序:在 Systemd 环境中,如果
oracleasm.service或oracle-afd.service启动晚于 OHASD,ASM 实例可能因找不到设备路径而失败.
-
3.7 Level 6: 上层堆栈初始化 (CRSD)
阶段目标:启动 crsd.bin,加载 OCR,接管用户资源。
技术细节: 当 ocssd 报告集群健康且 ASM 报告磁盘组已挂载时,orarootagent 启动 crsd.bin。
-
OCR 访问:
crsd必须独占访问 OCR(Oracle Cluster Registry)。OCR 存储了所有用户资源(VIP, DB, Listener, Service)的元数据。 -
PID 文件:
crsd会检查$GRID_HOME/crs/init/<node>.pid以防止重复启动。
诊断检查点:
-
日志位置:
$GRID_HOME/log/<node>/crsd/crsd.log。 -
常见故障(Case 4):
-
OCR 无法读取:如果 ASM 实例运行正常但 OCR 所在的磁盘组(如
+DATA)未挂载,CRSD 将无限期等待或报错退出。 -
权限错误:CRSD 以 root 运行。如果 OCR 文件的底层设备权限被修改(非 root/grid),CRSD 可能崩溃。
-
3.8 Level 7: 用户资源启动
阶段目标:CRSD 孵化其 Agent,启动数据库、监听、SCAN 等。
技术细节: CRSD 同样使用 orarootagent(管理 VIP, SCAN VIP, Network)和 oraagent(管理 Database, Listener, Service)。
-
依赖图:CRSD 计算资源依赖关系树。例如:Service 依赖于 Database,Database 依赖于 ASM Diskgroup,VIP 依赖于 Public Network。
诊断检查点:
-
命令:
crsctl stat res -t。 -
日志位置:
$GRID_HOME/log/<node>/agent/crsd/oraagent_grid/。 -
常见故障(Case 7):
-
Resource Dependency Failure:数据库无法启动通常是因为其依赖的 ASM 磁盘组资源未 ONLINE。
-
Listener 启动失败:端口冲突或
listener.ora配置错误。
-
4. 故障诊断工具箱与策略
面对复杂的启动流程,依靠单一的日志查看(tail -f)往往效率低下。Oracle 提供了一套强大的诊断工具集。
4.1 Trace File Analyzer (TFA) Collector
TFA 是 Oracle 12c/19c 的标准诊断收集器。它解决了日志分散(ADR 结构与 Legacy 结构并存)的问题。
-
核心功能:自动识别集群所有节点,按时间段裁剪日志,统一打包。
-
使用示例:
Bash# 收集过去4小时的所有相关日志(OS, CRS, DB, ASM) tfactl diagcollect -last 4h -
优势:TFA 能够自动解析 ADR 目录结构,收集
systemd日志、messages、以及所有 Grid/DB 组件的 Trace 文件.
4.2 Cluster Health Monitor (CHM) / OSWatcher
启动失败常常是资源争用(Resource Starvation)的结果。
-
OSWatcher (OSWBB):记录历史 OS 指标(vmstat, iostat, top)。
-
CHM (Cluster Health Monitor):提供秒级的系统指标记录。当节点因“心跳丢失”被 CSSD 驱逐时,CHM 数据是判断“网络中断”还是“CPU 挂死”的唯一依据。如果 CHM 显示驱逐时刻 CPU 使用率 100% 且运行队列极高,则通过增加实时优先级或隔离负载可解决问题.
4.3 Cluster Verification Utility (CLUVFY)
CLUVFY 不仅用于安装前检查,也是启动故障的强力排查工具。
-
功能:验证网络连通性、共享存储可访问性、用户等价性(SSH)、权限一致性。
-
使用示例:
Bash# 验证集群所有节点在安装后的状态 cluvfy stage -post crsinst -n all -verbose -
价值:它能快速发现单点配置漂移(Drift),例如某节点的
/var/tmp权限被意外修改,或某个网卡的 MTU 设置不一致.
4.4 Cluster Health Advisor (CHA)
在 19c 中,CHA 能够基于模型识别性能异常。虽然它更多用于运行时监控,但在分析因资源不足导致的反复重启(Restart Loop)时极具价值。CHA 的数据存储在 GIMR(Grid Infrastructure Management Repository)中.
5. 核心故障场景深度剖析
5.1 场景一:Socket 文件引发的通信阻断
现象:crsctl check crs 报 CRS-4535: Cannot communicate with Cluster Ready Services,或者 ohasd 启动后无响应。 机理:Oracle Clusterware 进程间通信(IPC)严重依赖位于 /var/tmp/.oracle (或 /tmp/.oracle)下的 Socket 文件。这些文件就像进程间的“电话线”。 诊断:
-
检查目录内容:
ls -l /var/tmp/.oracle。 -
权限陷阱:在 Oracle Restart(单机)环境中,这些 Socket 应由
grid用户拥有;而在 RAC 集群环境中,许多 Socket(如sOHASD_UI_SOCKET)必须由root用户拥有 。 -
修复:在完全停止 CRS (
crsctl stop crs -f) 后,安全做法是清空该目录(注意不要删除目录本身,或者让脚本重建),让ohasd重启时重新生成正确的 Socket。
5.2 场景二:Systemd cgroup 权限逃逸
现象:在 Oracle Linux 7/8 (Kernel 4.x+) 上安装或升级 19c 后,节点重启,ohasd 服务显示 failed。 日志:journalctl -u oracle-ohasd 显示类似 Permission denied 写入 /sys/fs/cgroup/.../tasks。 机理:init.ohasd 脚本试图将进程 PID 写入 cgroup 任务列表以进行资源控制,但 Systemd 的较新版本加强了 cgroup 的写权限控制,导致 root 用户执行的脚本也无法直接写入。 修复:这是 19.3 的已知 Bug。需要修补 init.ohasd 脚本,移除或修改写入 cgroup 的逻辑,或者应用最新的 GI Release Update (RU).
5.3 场景三:脑裂与节点驱逐 (Split Brain & Fencing)
现象:节点突然重启。 诊断流程:
-
锁定时间点:查看
alert.log或uptime确定重启时间。 -
检查 CSSD 日志:在幸存节点的
ocssd.log中查找Escalating to kill或heartbeat fatal。 -
判定原因:
-
网络分区:日志显示无法接收对方网络心跳,但在磁盘心跳上能看到对方。此时 CSSD 依据“最大节点数”或“最小节点号”原则,决定杀死对方。
-
IO 挂死:如果本地节点无法写入磁盘心跳,通过自我监控机制(
cssdmonitor),本地节点会触发 Panic 重启以避免数据损坏.
-
-
关键区分:通过 CHM 数据区分是“网络真的断了”还是“OS 忙得无法处理网络包”。
5.4 场景四:Flex ASM 代理故障
现象:数据库实例无法启动,报错 ORA-01078 且无法连接 CSS。但 crsctl check crs 显示 CRS 在线。 机理:在 12c/19c Flex Cluster 中,DB 节点可能不运行本地 ASM 实例,而是作为 ASM Client 连接到其他节点的 ASM。 诊断:检查本地的 ASM 代理进程。检查网络层(GIPCD)是否允许跨节点通信。如果 GIPCD 故障,跨节点的 ASM 请求将失败,导致 DB 无法访问存储.
6. 总结与建议
Oracle RAC Clusterware 的启动是一个高度依赖顺序和状态的复杂过程。从 Systemd 的触发,到 OHASD 的自举,再到 CSSD 的集群构建和 CRSD 的资源接管,任何一个环节的微小配置偏差(权限、网络、存储)都可能导致链式反应的失败。
高效诊断的黄金法则:
-
自底向上:永远先检查 OS 和 Systemd 服务状态,再检查 OHASD,最后检查 CRSD。
-
关注依赖:如果 CRSD 不启动,不要只看 CRSD 日志,先确认 ASM 和 CSSD 是否健康。
-
利用工具:放弃手动翻阅海量日志,熟练使用
tfactl、cluvfy和oclumon是现代 DBA 的必备技能。 -
保护现场:在执行暴力重启或清理操作前,务必先运行 TFA 收集当前状态,为根因分析(RCA)保留证据。
通过建立严谨的诊断思维模型,我们将能够从看似混乱的报错信息中抽丝剥茧,迅速恢复系统的可用性。