在Oracle RAC集群的运维工作中,打补丁是一件需要格外谨慎的事情。与单实例数据库不同,RAC涉及多个节点、CRS集群软件和数据库实例的协同,一旦某个节点补丁出现异常,可能引发节点重启、实例驱逐甚至整个集群不可用。掌握规范的补丁回滚流程,是每一位DBA必备的应急技能。本文将以Linux平台下的Oracle 19c RAC为例,完整讲解补丁回滚的操作步骤和注意事项。

一、什么情况下需要回滚补丁
补丁回滚并不是一个常规操作,通常只在补丁引发新问题时才执行。常见的触发场景包括:打完补丁后数据库实例无法正常启动、监听出现异常无法注册服务、业务SQL出现非预期的执行计划劣化或ORA错误、CRS集群资源频繁offline,以及第三方应用与新补丁存在兼容性冲突等。这些问题有的在重启实例后立即暴露,有的则在业务高峰期才显现,因此打完补丁后的观察期非常重要。
在决定回滚之前,需要先做一轮基本排查,确认问题确实由补丁引起,而不是其他环境变更导致。可以通过对比打补丁前后的alert日志、GI的crsd.log和cssd日志来定位原因。如果一时无法确定,可以采用滚动方式先回滚一个节点,观察问题是否消失,再决定是否回滚其余节点。这种做法在业务不能长时间停机的场景下尤其实用。
需要注意的一点是,如果补丁中包含数据字典脚本(比如datapatch执行的部分),那么仅回滚二进制文件并不等于完全回到补丁前状态,还必须用datapatch重新执行回滚操作修改数据字典,这一点在后面会详细说明。
二、回滚前的准备工作
回滚操作虽然步骤不复杂,但准备工作直接决定了操作能否一次成功。首先要确认当前安装了哪些补丁,在每个节点分别执行以下命令,记录补丁号和安装时间,这些信息要保留下来作为回滚的依据:
# 查看GI HOME已安装的补丁 $ORACLE_HOME/OPatch/opatch lspatches # 查看数据库HOME已安装的补丁 su - oracle $ORACLE_HOME/OPatch/opatch lspatches # 查看详细的补丁清单 $ORACLE_HOME/OPatch/opatch lsinventory -detail
其次要检查OPatch版本是否满足要求。部分较新的RU补丁要求OPatch版本不低于12.2.0.1.x,如果版本过低,先从MOS下载对应版本的OPatch并替换。可以通过opatch version命令确认当前版本。
另外要确认opatch的inventory完整性。执行opatch lsinventory时如果报错找不到Central Inventory,需要检查/etc/oraInst.loc文件中inventory_loc参数指向的目录是否正确,否则回滚会因为找不到补丁元数据而失败。最后,整理一份回滚操作计划表,写清楚每个节点的执行顺序、停启实例的顺序、预计时间窗口和回退方案,并提前通知业务方可能的短暂服务中断。
三、使用opatch rollback执行回滚
Oracle官方推荐的回滚工具是opatch,通过rollback子命令可以卸载指定的补丁。RAC环境下要逐个节点操作,先回滚一个节点验证正常后再处理下一个。下面以回滚数据库HOME上的补丁为例,假设补丁号为32545013:
# 1. 停止该节点上的数据库实例和监听 su - oracle srvctl stop instance -d orcl -n racnode1 srvctl stop listener -n racnode1 # 2. 使用root用户停止该节点的集群栈(回滚DB补丁一般不需要,回滚GI补丁必须) # crsctl stop crs # 3. 切换到oracle用户执行回滚 cd $ORACLE_HOME opatch rollback -id 32545013 # 4. 验证补丁是否已移除 opatch lspatches
回滚GI HOME上的补丁时流程略有不同。GI补丁通常安装在Grid用户下,回滚前必须以root身份执行crsctl stop crs停掉本节点的集群栈,否则文件被占用会导致回滚失败。如果打的是组合补丁(比如GI和DB打包在一起的版本),则需要在两个HOME中分别回滚。回滚完成后用root执行crsctl start crs拉起集群,再用crsctl stat res -t确认所有资源状态正常。
opatch还支持离线回滚参数-silent用于脚本化批量操作,适合节点较多的环境。回滚过程中如果遇到文件被锁定的报错,通常是Oracle进程未完全退出,可以用ps -ef | grep $ORACLE_HOME检查残留进程并手动清理后再重试。
四、执行datapatch完成数据字典回滚
从12c开始,数据库补丁分为二进制部分和数据字典部分。二进制回滚完成后,还需要在数据库打开状态下执行datapatch,让数据字典中的补丁记录与实际二进制保持一致。这一步经常被遗忘,导致后续查询dba_registry_sqlpatch时状态显示异常,甚至触发数据库自检报错。操作步骤如下:
-- 以oracle用户登录其中一个实例执行 cd $ORACLE_HOME/OPatch ./datapatch -rollback 32545013 -- 检查回滚结果 sqlplus / as sysdba SET LINESIZE 200 SELECT patch_id, patch_type, status, action_time FROM dba_registry_sqlpatch ORDER BY action_time;
如果回滚的是纯粹的GI补丁或者不涉及SQL文件变更的补丁,datapatch会提示无需操作,这一步可以跳过。判断标准是查看补丁的README文件中是否包含datapatch相关说明,或者执行后观察其输出。执行datapatch时建议只在一个实例上运行,它会自动处理RAC所有实例的元数据。
完成数据字典回滚后,将之前停止的实例用srvctl start instance重新拉起,观察alert日志确认无报错,再用select * from v$version和相关功能测试验证业务恢复正常。最后记得更新运维文档,记录本次回滚的原因、涉及补丁号和执行时间,为后续升级规划提供参考。
五、回滚过程中的常见问题与规避建议
实际操作中有几类高频问题值得注意。第一是inventory损坏导致回滚失败,报错信息通常包含PrereqOptions或Detail信息,此时不要强行删除补丁目录,而应先执行opatch lsinventory -detail定位异常HOME,必要时用opatch util cleanup清理opatch缓存后再试。第二是ACFS文件系统挂载的HOME,回滚前要确认文件系统有足够空间存放回滚产生的备份文件。
第二类问题是回滚后实例无法启动,报ORA-01092或ORA-00704之类的错误,多数原因是datapatch未执行或执行失败,数据字典与二进制版本不匹配。解决办法是以upgrade模式启动实例,手动重跑catbundle或datapatch相关脚本修正。遇到这种情况不要慌,alert日志中会有明确的脚本执行记录可供追踪。
从管理角度出发,建议每次打补丁前都对HOME做一次备份,可以用tar打包或使用存储快照,这样即使opatch回滚失败也有兜底手段。同时在测试环境完整演练一遍打补丁和回滚流程,把每一步的输出记录成检查清单,生产环境操作时按清单逐项核对。RAC环境的操作容错空间比单实例小得多,多一分准备,就少一次深夜应急。
Oracle RAC补丁回滚opatch rollback修改时间:2026-09-13 02:38:37