应使用checkconflictagainstohwithdetail和checkconflictamongpatcheswithdetail;回退前须确认数据库/监听已停、无残留进程、补丁id准确;冲突需查supersede关系;rollback后必须手动执行sql层回退脚本。
冲突检测命令到底该用哪一个
oracle 的 opatch prereq 有多个冲突检测子命令,选错就等于白跑——不是漏报就是误报。最常被误用的是 checkconflicts(老版本遗留),它只做粗略比对,不识别补丁间的依赖/覆盖关系;真正该用的是带 withdetail 后缀的两个命令:
-
CheckConflictAgainstOHWithDetail -ph ./:检查待打补丁与当前 Oracle Home 中已安装补丁是否冲突(必做) -
CheckConflictAmongPatchesWithDetail -phBaseDir /path/to/patches/:检查多个待打补丁之间是否互斥(比如同时解压了两个 one-off 补丁)
注意:opatch prereq 不支持 -skip_duplicate 或 -skip_subset,它会把“被包含”的补丁标为 superset,这不算错误——只有明确标出 conflict 的才需处理。如果报错 Unable to create Patch Object,大概率是 -ph 目录里混进了非补丁文件(如 cpu_root.sh),删掉再试。
回退 rollback 前必须确认的三件事
别急着 opatch rollback,很多问题其实不是补丁本身的问题,而是环境没清理干净。执行前务必确认:
- 数据库和监听已 shutdown(RAC 还要停 CRS,单机也得
lsnrctl stop) - 当前
ORACLE_HOME下没有正在运行的后台进程(ps -ef | grep $ORACLE_HOME看一眼) - 要回退的补丁 ID 确实存在且唯一:用
opatch lsinventory -patch_id查,别凭印象输错数字(比如把27734982写成27734983)
回退命令本身很简单:opatch rollback -id 27734982,但一旦失败(比如权限不足或文件被占用),OPatch 不会自动清理中间状态,后续再打补丁容易卡在半途。所以回退后建议立刻跑一次 opatch lsinventory 确认补丁已消失,再查 dba_registry_history 看 SQL 层变更是否也一并撤销。
冲突时别硬上,先看它到底在吵什么
当 CheckConflictAgainstOHWithDetail 报冲突,输出里会列出具体冲突的补丁 ID 和 bug 号,例如:
Conflicting bugs are: 17332800<br>Conflict with 16902043
这时不要直接删旧补丁。先查这两个补丁的关系:
-
opatch lsinventory -bugs_fixed | grep 16902043确认它确实装过 - 去 MOS 搜
17332800,看官方说明是否属于“被新补丁 supersede”(即覆盖)还是真冲突 - 如果是 supersede 关系,通常只需回退旧补丁再打新补丁;如果是真冲突(比如两个补丁都改了同一行 C 代码),就得联系 Oracle Support 要 merged patch
一个典型坑是:PSU 和个别 one-off 补丁共存时,PSU 的 Readme 里往往明确写了“不兼容哪些 one-off”,但管理员跳过这步直接开干,结果冲突报错才回头翻文档。
rollback 后为什么数据库版本没变、但功能异常
回退成功 ≠ 数据库完全还原。尤其对 PSU/ RU 类补丁,opatch rollback 只处理二进制层,SQL 层变更(如数据字典对象、系统视图定义)可能还留在库里。现象是:opatch lsinventory 显示补丁没了,但 SELECT * FROM v$version 还是新版本号,或者某些新功能还能调用。
根本原因是没执行配套的 SQL 回退脚本。正确做法是:
- 回退前记下
dba_registry_sqlpatch里对应补丁的patch_id - 回退后进 SQL*Plus,手动运行
@?/rdbms/admin/catbundle.sql psu rollback(路径和参数依版本而异,19c 之后多用datapatch -rollback) - 最后跑
@?/rdbms/admin/utlrp.sql编译失效对象,否则 PL/SQL 包可能报ORA-04068
最容易被忽略的是:回退操作本身不会自动触发 datapatch,它不像打补丁时那样有提示。这个空档,就是功能看似正常、实则埋雷的高发区。










