这个操作我做过不止一次,每次做完都出一身汗。Oracle 19c RAC 环境下,OCR和votedisk同时丢失、而且没有任何可用备份,听起来像是DBA的末日场景——实际上没有备份不代表没救,只要你脑子里的知识还热乎,集群底层的运行态信息还活着,这条路完全可以走通。这篇文章把我真实操作的流程、判断逻辑、踩过的坑全部拆开讲清楚,适合正在面对类似故障、或者想在测试环境提前演练一遍的同行参考。
1. 故障全景:OCR和votedisk各司其职,同时丢失意味着什么
1.1 OCR是集群的“注册表”
OCR全称Oracle Cluster Registry,它存的是整个集群的核心配置信息——节点列表、集群资源定义、ASM实例配置、RAC数据库的注册信息、网络配置、GNS配置等等。可以把它理解成Windows注册表在Oracle集群里的亲戚:所有组件启动时都要读它,任何配置变更都要写它。
OCR在正常部署时会有三份副本,分布在不同的存储路径上,任何一份坏了,另外两份还能顶上。但问题恰恰出在“同时丢失”上:存储阵列逻辑损坏、误格式化、人为删除文件、或者底层LUN映射错乱,都可能把三份副本一锅端。这个时候你连集群都起不来,更别提数据库。
1.2 votedisk是集群的“投票箱”
votedisk解决的是脑裂判定问题。集群里每个节点通过votedisk进行心跳仲裁,当网络心跳中断、节点间无法通信时,votedisk的票数决定哪部分节点继续存活、哪部分节点被逐出集群。
votedisk在ASM环境下同样需要多个副本,默认配置三份,分布在不同的failgroup里。它丢失之后的直接后果是CSS进程无法确定集群法定人数,所有节点都不敢贸然启动,集群彻底瘫痪。
1.3 “无备份”场景到底是怎么发生的
很多人以为无备份就是没做备份策略,其实我遇到的情况往往更复杂:
ocrconfig -showbackup能显示备份文件,但文件本身损坏,ocrconfig -restore恢复失败;- 备份文件存放在本地盘,而本地盘恰好跟OCR所在存储一起被误操作清掉了;
- cdata目录权限被改、文件被手工挪走、或者备份目录所在文件系统损坏;
- 更常见的是存储级别的误操作——快照删除、卷回收、LUN重新映射,导致OCR、votedisk和自动备份全部消失。
所以“无备份”不一定是你没做备份,而是备份和原件一起阵亡了。这种时候千万别慌着重新初始化集群,一旦你执行了root.sh或者重装GI,那才是真的万劫不复——所有节点信息和配置痕迹都可能被覆盖掉。
2. 无备份恢复的真正思路:不依赖归档,靠运行态和GPNP
2.1 常规思路为什么走不通
正常情况下,OCR恢复就两条路:ocrconfig -restore从自动备份恢复,或者从另一节点的副本同步。无备份场景下这两条路全部堵死,但很多人忽略了一个关键事实:集群没死透的时候,OCR内容仍然残留在CSS进程的内存缓存里。
即便集群因为votedisk问题无法正常启动,节点本地的GPNP Profile(Grid Plug and Play Profile)文件仍然保存了集群的关键元数据,包括集群名称、OCR存储位置、ASM磁盘组信息等。GPNP相当于身份证,CSS启动时即使读不到OCR,也能通过GPNP拿到最基本的指纹信息。
2.2 三个恢复路径的前提判断
无备份重建不是一条路走到黑,先要判断现状属于哪种情况:
| 现状 | 可用的恢复思路 |
|---|---|
| 节点仍在运行,集群资源部分存活 | 直接尝试ocrconfig -repair,甚至可以从内存导出OCR信息 |
| 集群已宕,但ASM磁盘组完好 | 以排他模式启动,手动拉起ASM,挂载磁盘组,再重建OCR和votedisk |
| ASM磁盘组本身也丢失/损坏 | 先恢复ASM磁盘组,这通常是另一个独立的大型恢复项目,不在本文范围内 |
这三个判断直接影响操作路径。我最怕的就是一上来就乱执行命令,把还有机会利用的运行态信息搞丢。
2.3 选定方案:-repair + 重建votedisk的路线图
我这次要重点讲的方案,适用于第二种情况:集群已宕,但ASM层和存储层完好,丢失的只是ASM里的OCR文件与votedisk文件。整体路线是:
- 在其中一个节点以排他模式启动CRS,跳过OCR读取;
- 手动拉起ASM实例,挂载包含OCR的磁盘组;
- 使用
ocrconfig -repair -add重新注册OCR位置; - 恢复正常模式启动,让集群从GPNP和内存信息中自动构建OCR内容;
- 使用
crsctl replace votedisk重建votedisk; - 验证集群资源和RAC数据库回归。
这个方案不依赖任何备份文件,核心逻辑是“让集群自己重新生成配置文件”。
3. 动手前的环境盘点与信息锁定
3.1 节点清单与GI_HOME核对
动刀之前,先把家底盘清楚。我习惯列一个清单,逐项确认:
- 集群节点数量与主机名(比如node1、node2);
- 每个节点的GI_HOME路径,通常是
/u01/app/grid/19.0.0/grid; - Oracle用户和OSDBA组(通常grid用户安装GI);
- 集群名称,可以从
/etc/oracle/olr.loc或者GPNP profile中读取。
排他模式只能在单节点执行,其他节点必须全部处于停止状态。如果你不确定其他节点的状态,先通过ssh过去检查CRS进程是否存在,必要时手动执行crsctl stop crs -f。
3.2 关键参数锁定
这个环节是我在多次事故中总结出来的必备动作,千万别省。需要锁定的参数有:
# 查看OLR位置,OLR是每个节点本地的OCR,独立于共享OCR cat /etc/oracle/olr.loc # 查看GI版本信息 $GRID_HOME/bin/crsctl query crs softwareversion # 查看集群名称(如果GPNP还能读) $GRID_HOME/bin/gpnptool get # 尝试查看自动备份情况(确认无备份的结论) $GRID_HOME/bin/ocrconfig -showbackup如果ocrconfig -showbackup报错或者显示无备份文件,那就坐实了无备份的判断。OLR文件如果完好,至少说明这个节点还有本地身份信息,排他模式启动时成功率会高很多。
3.3 存储层面核验
这一步很多人容易忽略。OCR和votedisk都存放在ASM磁盘组里,所以必须先确认ASM磁盘组的状态。你需要用asmcmd或者通过ASM实例查询:
# 确认ASM实例的状态(如果还能起来) ps -ef | grep asm_pmon # 用ASM用户进入检查磁盘组 sqlplus / as sysasm SQL> select name, state, type, total_mb, free_mb from v$asm_diskgroup;重点确认:磁盘组是否处于MOUNTED状态,磁盘组可用空间是否够建OCR和votedisk。OCR对空间要求不大,几百MB就够,votedisk单副本也就几百MB,但磁盘组本身必须健康。
另外要记录下磁盘组名称和冗余模式。比如OCR放在+DATA这个磁盘组,冗余方式是NORMAL,那votedisk也会放在同一个组里,ASM会自动管理多副本。
4. 重建OCR的完整执行步骤:从维护模式到ocrconfig -repair
4.1 先让CSS在排他模式下起来
这一步是整个恢复的地基。排他模式(exclusive mode)可以让CSS不读取OCR和votedisk就直接启动,相当于给了一个“无证驾驶”的入口。
在node1上执行:
# 先确保本节点CRS进程是停止状态 crsctl stop crs -f # 以排他模式启动,跳过OCR和CRSD crsctl start crs -excl -nocrs-excl表示排他模式,-nocrs表示不启动CRSD资源守护进程。执行后观察集群日志,确认CSS进程正常起来了:
tail -f $GRID_HOME/log/$(hostname)/cssd/ocssd.log正常情况下能看到CSS启动成功,并进入“clustered”状态。如果CSS起不来,多半是OLR损坏或者网络心跳配置丢失,那就需要先处理这些前置问题。
4.2 手动拉起ASM实例并挂载磁盘组
排他模式下CRSD没有运行,ASM资源不会自动启动,需要手动拉起来:
# 切换到grid用户 su - grid # 启动ASM实例 export ORACLE_SID=+ASM1 sqlplus / as sysasm SQL> startup nomount;如果ASM的spfile本身就在OCR磁盘组里,startup nomount可能会报错找不到spfile。这时候需要手动指定参数文件:
SQL> startup nomount pfile='/tmp/asm_pfile.ora';有了实例之后,手动挂载磁盘组:
SQL> alter diskgroup DATA mount; SQL> select name, state from v$asm_diskgroup;这一步如果执行失败,说明ASM磁盘组本身也有问题。我遇到过磁盘组因为OCR丢失而处于“FORCED MOUNTING”状态,直接alter diskgroup DATA mount会卡住。这种情况下需要先检查磁盘头:
asmcmd lsdsk -k -p如果磁盘组实在无法挂载,那就得先用kfed修复磁盘头或从存储快照恢复磁盘组,属于另一个战场,本文暂不展开。
4.3 用ocrconfig -repair -add写入新OCR位置
手动拉起ASM并挂载磁盘组后,核心操作就是ocrconfig -repair命令。这个命令的特殊之处在于,它不依赖备份文件,而是基于节点本地的GPNP信息和运行态信息,直接修改OCR注册位置。
# 查询当前OCR注册情况(此时应该为空或全部失效) ocrconfig -repair -show # 添加新的OCR位置,这里以+DATA为例 ocrconfig -repair -add +DATA执行成功后,可以验证:
ocrcheck如果返回结果里能看到+DATA设备,并且显示Device/file integrity check succeeded,说明OCR位置已经注册成功。
-repair和-replace的区别要注意:-repair是告诉集群“这个位置作为OCR”,即使旧位置已经不可读也能强制执行;-replace则是先读旧位置再换成新位置,旧位置彻底不可读时可能失败。所以无备份场景下优先使用-repair -add。
4.4 退出排他模式,恢复正常启动
新OCR位置注册完成之后,需要退出排他模式,让集群以正常模式重新启动:
# 回到root用户 exit # 停止排他模式下的CRS crsctl stop crs -f # 正常启动CRS crsctl start crs等CRS启动完成后,重点检查CRSD是否正常接管:
crsctl stat res -t这时你可能会看到很多资源处于INTERMEDIATE或OFFLINE状态,这正常,因为集群刚恢复,很多东西还在重建。关键的检查点是:
ocrcheck输出里应当能看到:
Status of Oracle Cluster Registry is as follows : Version : 3 Total space (kbytes) : 262144 Used space (kbytes) : 2048 Device/File Name : +DATA Device/File integrity check succeeded看到“Device/File integrity check succeeded”就说明OCR已经在正常工作了。集群在启动过程中,会自动将内存中保留的配置信息写入新OCR文件,不需要你手动导入任何东西。
5. 重建votedisk与集群回归验证
5.1 判断votedisk是否真的需要重建
OCR重建只是第一步,votedisk如果不处理,集群依然无法稳定运行。先用下面命令查看votedisk状态:
crsctl query css votedisk正常输出长这样:
## STATE File Universal Id File Name Disk group -- ----- ----------------- --------- --------- 1. ONLINE 5e4e2e... /dev/sdb DATA 2. ONLINE 8c1a2f... /dev/sdc DATA 3. ONLINE a3d5e7... /dev/sdd DATA如果输出里全是LOST、OFFLINE、或者根本没有记录,那就需要重建。
还有一种容易被忽略的情况:OCR重建后,集群虽然能启动,但votedisk文件内容已经被破坏,CSS在运行时会持续报心跳错误。这种情况下即使votedisk显示ONLINE,也要强制重写。
5.2 替换votedisk的具体命令
确认需要重建后,使用crsctl replace votedisk命令完成替换。这里要注意,该命令要在CSS正常运行状态下执行,同时要确保有足够的权限(通常需要root或grid用户)。
# 把所有votedisk重写到+DATA磁盘组 crsctl replace votedisk +DATA这个命令的执行逻辑是:先检查目标磁盘组可用性,然后在磁盘组内创建新的votedisk副本,再把集群的votedisk指向切过去。
执行完成后再验证:
crsctl query css votedisk看到所有条目都是ONLINE状态,第一步就成功了。接下来重启一次CRS确认votedisk信息保存正常:
crsctl stop crs -f crsctl start crs5.3 验证集群资源和RAC数据库回归
集群起来之后,光看OCR和votedisk还不够,必须把整个栈验一遍:
# 检查集群整体状态 crsctl check crs # 查看所有资源状态 crsctl stat res -t # 检查ASM实例状态 crsctl stat res ora.asm -t # 检查数据库实例和监听状态 crsctl stat res ora.db -tRAC数据库通常会在CRS启动后自动注册并启动。如果数据库没有自动启动,可以手动执行:
srvctl start database -d ORACLEDB然后验证数据库实例在多个节点上都处于OPEN状态:
sqlplus / as sysdba SQL> select inst_id, instance_name, status from gv$instance;我还建议做一次数据库层面的快速验证——执行一个简单的查询、切换一次日志、或者跑一个AWR报告快照,确认集群和数据库不是“表面活、内里死”。
6. 这些坑我帮你踩过了
6.1 最容易栽跟头的地方
第一个坑:排他模式启动顺序搞错。必须先在所有节点停掉CRS,再在单节点执行crsctl start crs -excl -nocrs。如果其他节点还在运行,排他模式根本起不来,报错也不够直观,容易让人误判是OCR损坏之外的问题。
第二个坑:ASM spfile放在OCR磁盘组里。当OCR磁盘组丢失时,ASM实例可能也起不来,因为spfile也在这个磁盘组里。这时候要提前准备好pfile。我习惯在正常环境的/tmp下保留一份ASM pfile备份,这次就派上了大用场。
第三个坑:执行ocrconfig -repair -add之前没有检查磁盘组空间。虽然OCR占空间不大,但如果磁盘组本身已经满了,命令会一直卡住,日志里也不会报明确错误。先执行磁盘组空间检查是最稳妥的。
第四个坑:votedisk重建后忘记重启CSS验证。crsctl replace votedisk返回成功不代表重启后依然有效。有些人重建完直接以为完事了,结果下一次节点重启又起不来。必须完成一次完整的CRS停止再启动验证。
第五个坑:手滑执行了不必要的初始化。在无备份场景下,任何类似$GRID_HOME/root.sh、cluvfy、或者修改GPNP的命令都可能覆盖掉当前存活的指纹信息,让本来能恢复的局面变得不可恢复。操作前多想三秒。
6.2 日常维护建议
经历过这次事故之后,我把OCR/votedisk的日常检查固化到了运维脚本里:
| 检查项 | 命令 | 频率 |
|---|---|---|
| OCR状态 | ocrcheck | 每天 |
| OCR自动备份 | ocrconfig -showbackup | 每周 |
| votedisk状态 | crsctl query css votedisk | 每天 |
| 磁盘组空间 | asmcmd lsdg | 每周 |
| 集群日志错误 | grep -i error $GRID_HOME/log/$(hostname)/crsd/crsd.log | 每天 |
自动备份虽然叫“自动”,但它依赖本地cdata目录,这个目录既不在OCR磁盘组里,也不在共享存储上,很容易被忽略。我建议把cdata目录也纳入定时备份,最好复制到独立于数据库存储之外的备份服务器。
另外,既然都走到重建这一步了,顺手做一次OCR配置的导出留档也不亏:
ocrconfig -export /backup/ocr_export_$(date +%Y%m%d).dat这个导出文件虽然不算正式备份,但至少包含当前OCR里的全部配置,后面如果要查某个资源参数、核对集群配置,就不用去翻日志了。
这次操作最大的体会是:无备份不等于无解,但能活着从这种故障里走出来,靠的是平时把这些配置文件的结构、运行机制、恢复入口记在脑子里。真正到了存储阵列一锅端的那天,手边没有文档、没有同事、没有互联网,你能依赖的就是这些底层认知和肌肉记忆。希望各位永远用不上这篇文章,但需要的时候,它能帮你少走很多弯路。