1. 节点重新添加的适用场景与前置思路
先说说什么情况下你会碰到“Oracle 19c 集群节点重新添加”这个操作。
最常见的是这两种:一是集群里某个节点因为硬件故障、系统崩溃或误操作导致GI(Grid Infrastructure)层面状态异常,修复后需要让这个节点重新回到集群里正常工作;二是节点系统重装、主机名或IP变更后,原先注册在集群里的信息已经失效,需要先清理掉旧的配置,再以干净的状态把节点加回来。不管哪种场景,核心诉求都是同一个:让集群恢复到“所有节点都在线、数据库服务正常对外”的完整状态。
很多人容易把“重新添加节点”和“新装一个集群节点”搞混,实际上两者差距非常大。新装节点是从零开始,直接在目标主机上执行gridSetup.sh选择“添加节点”即可;而重新添加则往往伴随着旧节点残留信息的清理、CRS注册信息的修复、甚至是表决盘和OCR里脏数据的剔除。这一步要是没做干净,后续添加十有八九会报错。
还有一个常被忽略的点:不要一上来就动手。在重新添加之前,务必先搞清楚这个节点“为什么掉出去”。如果是因为网卡配置错了、私网不通、心跳超时被集群踢出去,那你在修复配置前就重加,结果一定是刚加进来又被踢出去,来回折腾好几轮。我见过不少初级DBA在这个环节反复踩坑,最后发现根因是交换机端口被禁用了。
所以,整个“节点重新添加”的链路,我的建议是按这个顺序走:先收集信息,再清理环境,然后添加节点,最后做验证。信息没摸清之前不要碰任何命令。
2. 环境检查与清理:动手前必做的三件事
2.1 检查原有集群的健康状态
这个步骤看似多余,实际上能省掉你后面大量排错时间。在目标节点上,先用crsctl status resource -t看看集群层面还有没有这个节点的残留资源,比如ora.node1.vip、ora.node1.LISTENER.lsnr这类资源是否还挂在集群里。同时用olsnodes -s检查各节点的状态,如果目标节点显示的是Inactive或者干脆没显示,那基本可以确认它已经不在集群配置里了。
另外还要检查一下ASM实例和数据库实例的状态。原先这个节点上运行的实例是已经彻底停掉了,还是处于abort状态?如果数据库实例还在内存里挂着,直接做节点添加,可能导致ASM实例冲突或者数据库实例重复注册到集群里,后面的问题会很麻烦。
我习惯在操作前用一个脚本把当前集群状态完整导出来留档,包括crsctl stat res -t的输出、olsnodes -n -v -p的输出、srvctl status database的输出,这样不管操作过程中出了什么问题,至少有一个基线可以对照。
2.2 彻底清理解散后的节点残留
如果这个节点之前是正常从集群里移除掉线的,那情况会好很多,因为crsctl delete node或DBCA卸载实例时已经清理了大部分信息。但如果是异常掉线,比如节点直接失联、机器重装过系统,那集群里的残留信息很可能五花八门。
残留主要集中在几个地方:CRS里的节点列表(olsnodes还能看见它)、OCR里注册的资源、GI的家目录(GI_HOME)里残留的配置文件、/etc/hosts和DNS里的记录、还有$ORACLE_HOME/network/admin/tnsnames.ora里的历史配置。
清理的推荐路径是:如果CRS还认识这个节点但状态异常,先尝试把节点删除干净:
crsctl stop crs # 在目标节点上执行,如果节点能起来 # 然后在正常节点上执行 crsctl delete node -force 节点名如果crsctl delete node报错或者节点在CRS里已经是完全消失的状态,那就不需要这步了,直接在目标节点上把GI_HOME和ORACLE_HOME底下的日志、监听文件、网络配置清理干净,确保主机名和IP解析正常即可。
这里有个坑要注意:如果节点是重装过系统的,那GI_HOME的inventory信息可能会与实际安装位置对不上,导致后续执行添加节点脚本时报“路径已存在”或“inventory不一致”的错误。碰到这种情况,建议把目标节点的/etc/oraInst.loc和$GI_HOME/inventory/ContentsXML/目录一并检查,必要时手动修正或者删掉重建。
2.3 核对网络与共享存储配置
这一步决定了加完节点后集群是否稳定,一定要认真核对。Oracle 19c RAC对网络的要求是:至少两块网卡,一块配public IP(和业务网络互通),一块配private IP(节点间心跳通信),两个网段绝对不能混。很多生产环境的故障都是因为管理员图省事把private IP和业务网段放在了一起,结果心跳包和业务流量互相干扰,集群频繁脑裂。
检查网络时可以这样操作:
# 查看当前节点网卡信息 ip addr show # 检查私网网段的互通 ping -c 4 私网IP对端 # 检查心跳设备名,确认没有启用了默认路由 route -n共享存储方面,最简单的检查方式就是确认ASM磁盘组里的磁盘在目标节点上能看到,且权限归属正确。Oracle 19c的ASM磁盘通常由grid用户和asmadmin组管理,权限是crw-rw----,所有者是grid:asmadmin。这个权限不对,ASM实例起不来,节点添加必然失败。
另外还要检查一下设备持久化配置,比如UDEV规则或者multipath配置文件,确保每次重启之后/dev/oracleasm/disks/下面的设备名不会变。设备名变来变去是重加节点时最容易出问题的点之一。
3. 节点添加实操全流程
3.1 使用grid用户执行addNode前的关键参数
准备工作完成后,就可以开始正式的添加流程了。在目标节点上,用grid用户登录,找到GI_HOME目录下的gridSetup.sh,执行添加节点。注意,gridSetup.sh有两个模式:可以加CRS集群节点,也可以只加GI Home里的软件节点。我们这里显然是要加CRS集群节点,所以会用到-addNode参数。
一个完整的添加命令大致长这样:
cd $ORACLE_HOME ./gridSetup.sh -addNode -silent -ignorePrereq \ -newNodeName 节点名 \ 需要的话还可以指定private IP等参数实际生产环境我建议先跑一遍完整性检查(prerequisite check),用-silent加-ignorePrereq的话会把很多硬件和依赖检查都跳过,虽然省时间但容易埋雷。更稳的做法是先用图形界面或gridSetup.sh -prereqOnly把预检跑一遍,确认所有不通过项都能接受或者已经处理,再真正执行添加。
如果是通过图形界面操作,流程就很直观:启动gridSetup.sh后选择“Add Node”,然后填要加的节点名和private、public IP,系统会提示你输入其他节点的root密码,然后自动把GI安装过去。整个过程中比较耗时的是软件复制的环节,走网卡传输几百兆或几个G的文件,快慢取决于网络环境。
添加结束后,脚本会提示你在目标节点执行root脚本,类似:
/tmp/xxx/discSetup.sh 或 $ORACLE_HOME/root.sh这个root脚本是必须执行的,它负责完成权限调整、注册CRS服务、启动OHASD等关键动作。很多人容易漏掉这一步,或者忘了以root身份执行,结果CRS服务根本起不来。
3.2 使用dbca向集群数据库添加实例
GI层面添加完节点后,集群数据库还不会自动在新节点上跑起来。你还需要用DBCA(Database Configuration Assistant)给目标数据库添加实例。
确认一下还有哪些数据库实例需要添加:
srvctl config database # 查看数据库的整体配置 srvctl status database # 查看实例在线情况如果新节点还没有任何实例,执行:
dbca -silent -addInstance \ -nodeList 新节点名 \ -gdbName 数据库名 \ -instanceName 实例名前缀 \ -sysDBAUserName sys \ -sysDBAPassword 密码这一步要注意的是:实例名的命名规则通常是在全局库名基础上加一个数字后缀,比如oradb1、oradb2,要确保和已有实例不冲突。DBCA往新节点添加实例的同时,还会自动完成redo log group、undo tablespace的调整,以及将新节点的listener注册到集群监听服务里,所以不需要手动创建这些对象。
如果数据库启用了PDB,那实例添加完成后PDB会在新实例上自动打开(取决于容器数据库的配置)。如果不希望PDB在新实例上自动打开,可以在DBCA执行前先修改容器的open_mode或者通过srvctl控制数据库在指定节点上的启动策略。
3.3 使用asmca检查ASM磁盘组与表决盘状态
最后一步就是验证ASM层面是否正常。新节点上ASM实例通常会在GI启动时自动拉起来,但磁盘组里的磁盘是否能被新节点看到、表决盘(voting file)是否能正常读写,都需要检查。
可以用asmcmd检查:
# 查看磁盘组与磁盘状态 asmcmd lsdg asmcmd lsdsk -k # 确认ASM实例状态 srvctl status asm -node 新节点名如果发现磁盘组在新节点上是MOUNTED状态但某些磁盘的状态是OFFLINE或者UNKNOWN,那大概率是权限或设备名问题,回到第2.3节再排查一遍。
表决盘的检查方式:
crsctl query css votedisk如果输出里显示的磁盘号和正常节点不完全一致,可以用:
crsctl add css votedisk 磁盘路径 crsctl delete css votedisk 无效磁盘路径来修正表决盘列表。这一步一旦做错,可能会影响整个集群的仲裁能力,操作前一定慎之又慎,最好在变更窗口做,并保留原有crsctl query css votedisk的输出作为回滚依据。
4. 常见问题与排查实录
4.1 预检不通过:缺少必需的依赖包或内核参数值不满足
在添加节点时,预检经常因为缺少依赖包被卡住。Oracle 19c尤其是对compat-libstdc++、oracle-database-preinstall-19c这类包很严格。另外内核参数也是高频问题,比如vm.swappiness、kernel.shmmax、fs.file-max、kernel.sem这些值如果不满足要求,预检一样会报红。
处理方式不是无脑把预检-ignorePrereq掉,正确的做法是先看完整预检报告,判断哪些项只是warning,哪些是error。warning级别可以接受,error级别必须先处理完再继续。比如内核参数,可以直接修改/etc/sysctl.conf后执行sysctl -p刷新;缺包就用系统的包管理器安装。
注意:如果你是在麒麟操作系统、统信UOS这类国产化系统上部署Oracle 19c,预检报错会更多一些,因为Oracle官方对国产系统的认证和依赖包覆盖不如海外主流发行版那么完善。这种情况下要逐项分析报错原因,必要时手动创建
oracle用户和oinstall、dba用户组,手动设置环境变量,才能跳过预检继续安装。
4.2crsctl delete node -force报错,或添加时提示OCR里已有节点记录
这种情况很典型,特别是节点异常掉线后,CRS里残留的内容会导致新添加节点的报错。报错一般类似“PRCN-2018:The specified node(s) are not a part of the cluster”或“PRCR-1017:The node is not known”。
我的处理经验是:如果delete node清不干净,可以用crsctl add node -force或者手工操作OCR,把旧的节点记录删掉。具体命令:
# 查看集群节点列表,确认残留节点 olsnodes -n -s # 手工从OCR里移除旧节点名称 crsctl delete res 资源名 -force不过手工删OCR里的资源风险很高,非必要不要碰,更不建议在没有备份的情况下动OCR。更稳妥的做法是:把目标节点彻底清理干净(卸载GI、删掉inventory、清空OCR里对应的节点条目),重新从正常的集群节点发起添加。如果你的集群本来就只有两个节点,删掉一个之后只剩一个,那还要注意仲裁问题——单节点集群添加新节点和双节点集群添加是完全不同的流程。
4.3 数据库实例在新节点上启动失败,报ORA-00304或ORA-01157
这两个错误经常相伴出现,原因是控制文件和数据库文件读取异常。最常见的原因是新节点访问共享存储的时候,设备权限不对,或者因为ASM磁盘组在目标节点上的mount顺序不对,导致无法正常读库文件。
先检查ASM的告警日志:
tail -200 $ORACLE_HOME/rdbms/log/节点名_ORA_进程号.log # 或者直接看ASM实例的告警日志 tail -100 $GI_HOME/rdbms/log/ASM_asm_节点名.log日志里如果明确写着ORA-01157: cannot identify/lock data file,那就可以聚焦在ASM磁盘可见性和权限上。确认磁盘组状态正常后,再尝试手工把实例从无状态改成开启:
srvctl start instance -db 数据库名 -instance 实例名 -starttype open如果一次起不来,不要反复试,先把ASM层面的问题解决掉再启动数据库实例,否则重复尝试可能引发更多的hang住和锁问题。
4.4 节点添加完成后,私网心跳时通时断,集群频繁报脑裂
这个问题的成因往往不在Oracle层面,而在网络侧。心跳走的是专用私有网段,交换机上如果portchannel配置错误、允许VLAN不对、或者网线接触不良,都会造成心跳包延迟变大或丢包,触发CSS层面的超时判定。
排查方式:
# 在目标节点上观察私网网卡的错误计数 netstat -in # 持续ping对端私网IP,观察丢包 ping -c 100 -i 0.2 对端私网IP # 检查集群日志里是否有明显的IPC timeout tail -200 $GI_HOME/log/节点名/cssd/ocssd.log如果是丢包严重,第一件事不是调Oracle参数,而是找网络团队修链路。把交换机端口、网线、光纤模块逐一排查。有时候只是节点重启后网卡没有正确UP,执行ifconfig 网卡名 up就能解决。
如果链路正常但心跳依然报超时,再考虑调整misscount和reboottime参数。但这两个参数一定要谨慎动,调大了会延长脑裂检测时间,调小了会导致误杀正常节点。一般情况下保持默认值就好,确需调整时先和原厂支持确认。
4.5 图形界面无法启动,报DISPLAY或X11转发错误
如果你是通过远程图形界面做节点添加的,经常会碰到DISPLAY环境变量没设置好或者X11转发权限不足的问题。解决方式很简单,用Xshell、MobaXterm这类支持X11转发的客户端,登录前开启X11转发,登录后检查echo $DISPLAY是否正常。
如果是无桌面的服务器环境,那建议果断走命令行silent模式,不要和图形界面死磕。逐项准备应答文件里的参数,执行一次addNode即可。silent模式虽然看不到进度,但可以通过日志跟踪进度:
tail -f $ORACLE_HOME/cfgtoollogs/cfgTool/目录下的日志文件5. 节点添加完成后的完整验证清单
5.1 集群资源和监听、VIP是否都正常接管
节点添加完成后,不能只看crsctl stat res -t里节点状态是ONLINE就完了。重点还要确认VIP、LISTENER、SCAN、ONS这些依赖网络的资源,在新节点上是否都处于在线状态。很多时候节点能加进来,但VIP因为IP被占或子网掩码不对起不来,然后业务连接就会受影响。
验证命令:
# 确认所有集群服务的总体状态 crsctl stat res -t # 查看监听状态 lsnrctl status 监听名 # 验证VIP能否ping通 ping -c 3 新节点的VIP地址如果VIP起不来,多半是public IP的子网掩码或网关配错了。检查ifconfig里的掩码是否和规划一致,同时确认/etc/hosts里的VIP解析指向正确的IP。
再补充一个常见问题:有些环境配置了SCAN IP,节点添加后如果SCAN监听没有在新节点上起来,应用连接串可能还是能通过其他节点的SCAN监听工作,但会导致连接分布不均。可以用nslookup SCAN域名或srvctl config scan确认SCAN的每个IP都正常。
5.2 数据库实例、PDB和服务的在线情况
数据库层面要验证的不光是实例能启动,还包括实例的服务注册、PDB的open状态、以及负载均衡策略是否符合预期。
验证命令:
# 查看数据库所有实例的状态 srvctl status database -db 数据库名 -v # 查看具体的服务状态 srvctl status service -db 数据库名 # 如果数据库是CDB架构,还需要查看PDB状态 sqlplus -s / as sysdba show pdbs;如果PDB在新节点上没有自动打开,可以用:
alter pluggable database all open;然后确认新实例的联机日志、Undo表空间是否都正常建立。DBCA在添加实例时会自动创建一套新的redo日志组和undo表空间,但如果平时做过手动扩展,建议顺带检查一下这些表空间在目标节点上的配置是否一致,避免某个实例的undo空间明显偏小、业务高峰期报ORA-01555或ORA-30036。
5.3 备份OCR、备份惊喜包、恢复演练建议
所有节点都恢复正常后,千万别忘了备份OCR(Oracle Cluster Registry)。OCR是集群的“大脑”,里面记录了所有资源、节点、ASM实例、数据库实例等关键配置,OCR一旦损坏,整个集群都可能起不来。
备份命令:
crsctl backup ocr /tmp/ocr_backup_日期.bak # 查看当前OCR备份策略 crsctl query ocr backup另外还建议把ASM的参数文件、监听配置文件、tnsnames.ora这些关键配置文件做一个快照归档。将来如果还需要类似操作,直接可以从这套干净的基线重新开始。
最后再分享一个习惯:每次做完节点变更,我都会在维护文档里记录三个时间线——变更前集群状态、变更中遇到的问题、变更后验证结果。看似多花十几分钟,但下次出问题排查时,这份记录能帮你节省几个小时。
6. 补充:常见报错速查表
顺手整理一份我折腾Oracle 19c集群节点重新添加时遇到的报错和对应处置办法,都是实际碰过的故障,直接照着排查会比较快。
| 报错信息 | 常见原因 | 处理方式 |
|---|---|---|
| PRCN-2018:节点不在集群配置中 | 节点已被强制删除或从未加入 | 使用图形界面重新执行添加节点;先确认旧节点记录已清除 |
| PRCR-1017:节点不可知 | OCR中节点记录损坏或残留 | 检查olsnodes -n -v输出;确认节点名、IP准确无误 |
| CRS-5017:资源ora.xxx.vip无法启动 | 公共IP被占用或子网掩码错误 | 检查IP占用情况;核对主机名解析和网卡子网规划 |
| ORA-00304:无法读取控制文件 | ASM磁盘权限或mount顺序异常 | 检查ASM实例状态;核实磁盘组权限和asm_diskstring配置 |
| ORA-01157:无法标识或锁定数据文件 | 设备名漂移或磁盘离线 | 检查UDEV/multipath配置;确保设备名固定,重新挂载磁盘组 |
| INS-20802:集群验证失败 | 依赖包缺失或内核参数不满足 | 安装oracle-database-preinstall-19c,手工修正sysctl.conf |
| CRS-1006:私网心跳超时触发脑裂 | 网卡故障或私网链路问题 | 检查netstat -in丢包;排查交换机端口、网线;必要时调整misscount |
| CSSD-6016:检测到网络路由失败 | 私网配置了默认路由或路由冲突 | 检查route -n,确认私网网卡没有默认路由,必要时永久删除冲突路由 |
| EVMD-0045:事件日志无法获取 | 操作系统时间不同步 | 启用NTP或chrony同步,确保各节点时间差在合理范围内 |
| ORA-15032+ORA-15075:ASM磁盘无法mount | ASM磁盘组已经由其他节点以不同方式挂载 | 确认集群状态一致后,用asmcmd检查磁盘组归属状态 |
这张表如果在操作时能帮上一点忙,那这篇文章的目的就算达到了。
7. 动手前最后的三个提醒
如果你和我一样,经历过凌晨接到告警电话、赶去机房处理集群节点失联的场面,那你一定明白,Oracle 19c集群节点重新添加这类操作,真正的难点从来不是照着文档执行命令,而是周边环境的完整排查和风险的预先控制。
第一个提醒,不要只盯着Oracle层面。节点加不进去、加进去又掉出来,头号嫌疑往往是操作系统层面的问题,比如防火墙把私网端口封了、SELinux没有关闭、/etc/hosts配置错误、系统时间不同步。这些基础项没搞定,Oracle姿势再正确也白搭。
第二个提醒,尽量在维护窗口内做完整流程演练。生产环境没条件演练的话,至少在一套测试环境把流程跑通一遍。我自己就在一次升级操作前,先在测试环境把两个节点重新添加跑了两遍,第二遍才注意到私网网卡的MTU设置和交换机不一致,预检能过但心跳就是不稳定。这种问题不在测试环境先暴露出来,到了生产环境就非常被动。
第三个提醒,也是最重要的:不要为省事跳过验证。官方文档里通常只写到“添加节点完成”,但实际工作中,节点加完只是开始,OCR备份、监听验证、VIP验证、PDB验证、以及应用连接测试,一个都不能省。有次客户以为节点加完就万事大吉,结果第二天业务方反馈部分连接失败,一查发现新节点的listener只注册了主机名服务,SCAN监听没有正常接管,折腾了一圈才解决。
节点的重新添加,说到底是一次对集群自愈能力的体检。把每一步都走稳,你收获的不仅是一个恢复正常的节点,还有对整个RAC架构更深一层的感觉。实操中碰到任何奇怪报错,先深呼吸,回到基础项目逐项核对,大部分问题都离不开IP、共享存储、权限这“老三样”。希望这篇记录能让你少走几个弯路。