直接修改PATH顺序无效,因系统缓存命令路径、shell已加载旧版opatch或Oracle工具硬编码调用$ORACLE_HOME/OPatch/opatch;必须替换原OPatch目录、校验JRE完整性并修复inventory。
为什么直接改 PATH 顺序不顶用
很多人把新 opatch 解压到 $oracle_home/opatch 后,只执行 export path=$oracle_home/opatch:$path 就以为完事了——但实际运行 opatch version 还是旧版本。根本原因是:系统可能缓存了命令路径(hash -r 没清),或者 shell 启动时已从其他位置(比如 /usr/local/bin 或老版本 oracle_home)加载过同名二进制。更隐蔽的是,某些 oracle 工具(如 datapatch)内部硬编码调用 $oracle_home/opatch/opatch,根本不走 path。
必须显式覆盖并验证 OPatch 目录结构
Oracle 不认“软链接”或“重命名后放旁边”,它只认 $ORACLE_HOME/OPatch 这个固定路径下的完整目录。所以正确做法是:
- 先备份原目录:
mv $ORACLE_HOME/OPatch $ORACLE_HOME/OPatch_bak - 解压新版
OPatchZIP 包,确保解压后顶层就是OPatch/目录(不是p6880880_122010_Linux-x86-64/OPatch/) - 把解压出的
OPatch目录直接移到$ORACLE_HOME/下:mv OPatch $ORACLE_HOME/ - 检查权限:
chown -R oracle:oinstall $ORACLE_HOME/OPatch(尤其注意opatch可执行文件和jre/子目录)
验证:切换到 oracle 用户,执行 which opatch 应该返回 $ORACLE_HOME/OPatch/opatch;再跑 $ORACLE_HOME/OPatch/opatch version 看输出是否匹配你下载的版本号(例如 12.2.0.1.28)。
Java 路径错位会导致 opatch 直接失败
新版 OPatch(尤其是 12.2.0.1.13+)自带 jre/ 子目录,但它默认优先用自己带的 JRE。如果这个 JRE 缺失、损坏或版本太低(比如只有 Java 1.7),就会报 Java (1.7) could not be located. OPatch cannot proceed!。这不是环境变量问题,而是 OPatch 自身依赖没满足。
- 最稳妥做法:删掉
$ORACLE_HOME/OPatch/jre,然后复制数据库主目录里的 JDK:rm -rf $ORACLE_HOME/OPatch/jre && cp -r $ORACLE_HOME/jdk/jre $ORACLE_HOME/OPatch/ - 别用系统全局 Java(
/usr/java)替代——OPatch对 JDK 路径有硬依赖,且要求与 Oracle Home 的 JDK 版本兼容 - 验证方式:在
$ORACLE_HOME/OPatch下执行./opatch version,不报 Java 错误才算过关
别忽略 inventory 检查这一步
opatch lsinventory -detail 不只是看装了啥补丁,它会触发 Oracle Inventory 的完整性校验。如果输出里出现 Inventory load failed 或 OPatch failed with error code 73,说明 inventory 损坏,后续所有 opatch apply 都会失败,哪怕 OPatch 版本完全正确。
- 修复命令(需 root 权限):
$ORACLE_HOME/oui/bin/runInstaller -ignoreSysPrereqs -force -silent -attachHome ORACLE_HOME=$ORACLE_HOME ORACLE_HOME_NAME=OraDB12c_home1 - 注意:
ORACLE_HOME_NAME必须和oraInst.loc里注册的一致,可通过cat /etc/oraInst.loc | grep inventory_loc找到 inventory 路径,再查里面ContentsXML/inventory.xml确认名称 - 修复后务必再跑一次
opatch lsinventory -detail,确认无报错再继续打补丁
真正卡住人的往往不是补丁本身,而是 OPatch 调用链里某一个环节(inventory、JRE、PATH 缓存)没对齐,导致错误信息模糊、复现困难。










