首页
/
行业洞察
/
正文
INDUSTRY INSIGHT · 深度
Oracle 12.1.3补丁p33385024 OPatch实战指南
📅 2026/10/24 4:38:21
✍️ 爱科研究院
👁 阅读 3,247
简介面向 WebLogic Server 12.1.3 运维与中间件管理员的一份基础补丁包针对该版本已知缺陷与安全风险提供官方修复并为后续补丁如 p33494824的安装提供前置依赖适合需要做版本升级、漏洞修补与补丁链规划的技术人员参考。压缩包共 5 个文件约 917KB体量轻便。其中 3 个 xml 用于补丁元数据与组件配置描述1 个以补丁号 33385024 命名的目录承载实际更新文件另附 1 个 txt 说明文件便于安装前核对补丁信息与文件清单。目前已有 281 人学习下载可作为补丁管理流程中的实际样本。读者可获得官方补丁的原始目录结构与文件组织方式据此了解补丁包内部构成配合 WLST 静默安装、opatch lsinventory 校验等环节完成验证补丁说明与清单也有助于排查安装失败、依赖缺失等问题适合作为补丁归档与版本基线管理的参考。1. p33385024 落在 12.1.3.0.0 上一个 Generic 补丁包能解决什么很多维护 12.1.3 中间件环境的人收藏夹里都躺着类似p33385024_121300_Generic.zip这样的文件但真正拆开跑过一遍的没几个。文件名里的121300直接写明了它作用的版本段——12.1.3.0.0Generic表示这是跨平台的通用补丁包同一份压缩包可以喂给 Linux、AIX 乃至 Windows 上的同版本 ORACLE_HOME。它不是安装介质不能从零装出一套中间件它的作用是把若干修复增量地塞进一个已经跑着的 ORACLE_HOME靠的是 OPatch 这套补丁管理机制。适合谁手上还有 12.1.3 存量系统、又没法立刻做大版本迁移的运维和中间件工程师。想清楚这一层再动手后面那些报错才不会打得你措手不及。2. 动手前的环境盘点OPatch 版本、JDK 与三份备份补丁翻车十次里有六次不是补丁本身的问题而是环境没盘干净。OPatch 版本太老、JAVA_HOME 指了一个残缺的 JDK、ORACLE_HOME 的所有者和当前登录用户对不上、磁盘剩 3G 就想拆包——这些在opatch apply之前都该被发现。这一章做的事情看起来枯燥但它决定了后面能不能一次跑通。2.1 先看 lsinventory 再谈补丁把 ORACLE_HOME 的现状摸清拿到一个 ORACLE_HOME我第一件事不是解压补丁而是看它身上已经背了多少补丁。opatch lsinventory输出的补丁列表是后面做冲突判断的唯一依据。# 切到中间件属主用户执行避免权限问题 su - weblogic # 确认环境变量指向正确的 ORACLE_HOME echo $ORACLE_HOME echo $JAVA_HOME # 列出该 ORACLE_HOME 已安装的全部补丁简表 $ORACLE_HOME/OPatch/opatch lsinventory # 详细模式能看到每个补丁的组件、语言、安装时间 $ORACLE_HOME/OPatch/opatch lsinventory -detail /tmp/lsinv_before_$(date %Y%m%d).loglsinventory不带参数时输出的是应用在 ORACLE_HOME 级别的补丁摘要-detail会把每个补丁包含的组件、子系统、安装时间全部展开输出量很大所以建议重定向到文件而不是直接刷屏。这份/tmp/lsinv_before_*.log后面有大用打完补丁再跑一次两份 log 一 diff就能确认补丁是真的进去了而不是 opatch 报了个成功但 inventory 没写。我一般还会顺手记一下opatch lsinventory顶部输出的 OPatch 自身版本号下一节要用。如果lsinventory本身就报错比如提示 inventory 指针找不到那说明oraInst.loc有问题这时候别急着往下走——补丁装上去也注册不了。# inventory 指针位置Linux 通常在 /etc其他平台在 ORACLE_HOME 下 cat /etc/oraInst.loc 2/dev/null || cat $ORACLE_HOME/oraInst.loc # 输出里 inventory_loc 指向的就是中央清单目录确认它有写权限 ls -ld $(grep inventory_loc /etc/oraInst.loc | cut -d -f2)oraInst.loc里只有两个关键字段inventory_loc指向中央 inventory 目录inst_group是属组。补丁应用时 OPatch 要往这两个地方写东西权限不对就会在最后一步失败——注意是最后一步前面解压、校验全都正常特别容易让人误判成补丁包坏了。2.2 OPatch 版本不达标就先升版本号怎么对补丁包解压后第一层目录里通常有个README.txt里面会写明本次补丁要求的最低 OPatch 版本。这个值必须满足否则opatch apply会直接拒绝执行报的错大意是当前 OPatch 版本不满足补丁要求。# 查看当前 OPatch 版本 $ORACLE_HOME/OPatch/opatch version # 对比补丁 README 里声明的最低版本例如要求 13.9.x 以上 grep -i opatch /u01/patch/p33385024/README.txt | head -2012.1.3 这一段环境常见的 OPatch 是 13.9 系列如果版本落后做法不是凑合试试而是先把 OPatch 升级到位。升级 OPatch 本身是替换目录但有两个细节容易忽略一是升级前把旧OPatch目录改名备份而不是直接删出问题能退回去二是新的 OPatch 包解压后要把原目录下的ocm子目录如果存在和 inventory 相关配置保留下来否则 OPatch 可能找不到中央清单。# 备份旧 OPatch mv $ORACLE_HOME/OPatch $ORACLE_HOME/OPatch.bak.$(date %Y%m%d) # 解压新 OPatch 包包名以实际为准解压后目录名应为 OPatch cd $ORACLE_HOME unzip -q /u01/soft/p6880880_121000_Linux-x86-64.zip # 恢复 ocm 配置目录如果旧版本里有 [ -d $ORACLE_HOME/OPatch.bak.$(date %Y%m%d)/ocm ] \ cp -a $ORACLE_HOME/OPatch.bak.$(date %Y%m%d)/ocm $ORACLE_HOME/OPatch/ # 验证新版本可用 $ORACLE_HOME/OPatch/opatch version $ORACLE_HOME/OPatch/opatch lsinventory -detail /dev/null echo OPatch OKopatch version输出成功不代表万事大吉必须再跑一次lsinventory且退出码为 0才说明新 OPatch 能正常读取 inventory。这一步是很多人的盲区版本号对了但 inventory 读取失败等到 apply 的时候才暴露。还有一个隐性的坑是 JDK。OPatch 是个 Java 程序opatch脚本内部会找 JRE。如果机器的JAVA_HOME指向了一个从别处拷来的、缺libjvm.so的 JDK你会看到Cannot create Java virtual machine之类的报错看起来像内存不够其实是 JDK 残缺。# 直接指定 ORACLE_HOME 自带的 JDK 给 OPatch绕开环境变量干扰 export JAVA_HOME$ORACLE_HOME/jdk export PATH$JAVA_HOME/bin:$PATH # 确认 jvm 库存在 ls $JAVA_HOME/jre/lib/amd64/server/libjvm.so我一般会在执行所有 opatch 命令前强制导出一次JAVA_HOME不依赖 shell 里那份可能被改过的环境变量。这个习惯省下过不少次排查时间。2.3 三份必须的备份和一次磁盘空间核算补丁回滚依赖ORACLE_HOME/.patch_storage目录里保存的原始文件副本所以这个目录绝对不能删。但光靠它不够——如果 ORACLE_HOME 里有人手工改过配置或者塞过 jar 包回滚回来的也只是补丁应用那一刻的状态。所以正式动手前我做三份备份。第一份是 ORACLE_HOME 整目录归档。注意必须在所有 WebLogic 进程停掉之后做热备出来的归档里文件可能不一致回滚回去反而更麻烦。# 停服务后再执行-p 保留权限-z 压缩 tar -pczf /backup/oracle_home_$(hostname)_$(date %Y%m%d%H%M).tar.gz \ -C /u01/app \ middleware # 归档大小可能是十几个 G先确认目标分区空间 df -h /backup第二份是域配置目录。补丁改的是 ORACLE_HOME 里的二进制和 jar理论上不碰 domain 下的config/config.xml但补丁应用后第一次启动时 WebLogic 可能会重写部分配置一旦启动失败你想对比改了什么没有备份就只能靠记忆。# 域目录通常形如 /u01/app/middleware/user_projects/domains/base_domain tar -pczf /backup/domain_config_$(date %Y%m%d%H%M).tar.gz \ -C /u01/app/middleware/user_projects/domains \ base_domain/config base_domain/bin base_domain/security第三份是ORACLE_HOME/.patch_storage的单独归档。有人会问整目录都备了还单独备这个干嘛因为整目录归档动辄十几 G真要回滚时解压一次成本很高而.patch_storage通常只有几百 M单独备一份能在紧急情况下快速定位到需要还原的文件。tar -pczf /backup/patch_storage_$(date %Y%m%d%H%M).tar.gz \ -C $ORACLE_HOME .patch_storage # 空间核算补丁解压后约占 1~2G加上 .patch_storage 增量留出 5G 余量 df -h $ORACLE_HOME du -sh $ORACLE_HOME/.patch_storage空间这块给个经验值Generic补丁解压后的files目录展开通常在 1G 上下apply 过程还会往.patch_storage里写一份原始文件副本所以至少留 5G。剩 1G 就上的大概率在 apply 到一半时遇到No space left on device而这时候补丁已经写了一半处置起来比重来一遍痛苦得多。3. 冲突检查与解压把 prereq 跑成拦截闸门补丁包解压出来不等于可以装prereq系列命令是最后一道闸门。跳过这一步直接 apply 的人通常会在 apply 跑到一半时被冲突打断然后被迫走回滚流程——而回滚本身也是风险操作。这一章把解压位置、包结构、三条 prereq 命令的判读讲清楚让拦截发生在动手之前。3.1 解压前先看包结构Generic 包里到底有什么拿到 zip 先别急着unzip用unzip -l看一眼目录结构几十秒的事能省掉后面很多困惑。# 先列内容不解压 unzip -l /u01/soft/p33385024_121300_Generic.zip | head -40一个标准的补丁包解压后第一层目录名就是补丁号33385024里面通常包含这么几类东西路径作用是否要关注README.txt补丁说明、最低 OPatch 版本、前置条件、已知问题必读冲突判断的依据在这etc/config/inventory.xml补丁的组件清单与版本约束冲突检查读的就是它etc/config/actions.xml补丁要执行的动作定义一般不用改files/实际要替换或新增的文件树按 ORACLE_HOME 相对路径组织apply 时整体拷贝过去online/或offline/补丁的在线/离线目录形式与-online/-offline参数对应files/目录的结构很有意思它和 ORACLE_HOME 的内部布局是一一对应的比如files/wlserver/server/lib/xxx.jar就对应$ORACLE_HOME/wlserver/server/lib/xxx.jar。apply 的过程本质上是把files下的内容按路径覆盖过去同时把被覆盖的原文件存进.patch_storage。理解这一点后面排查补丁到底改了什么就有方向了。解压位置有三条硬要求路径不能有空格不能有中文磁盘要有空间。前两条听上去像废话但真有人把补丁放在桌面目录路径含用户名和中文然后 opatch 在处理路径时行为异常。# 建一个专用的补丁工作目录属主与 ORACLE_HOME 一致 mkdir -p /u01/patch chown weblogic:oinstall /u01/patch # 用中间件属主解压避免后续 OPatch 读写权限问题 su - weblogic -c cd /u01/patch unzip -q /u01/soft/p33385024_121300_Generic.zip # 确认第一层目录名就是补丁号 ls -ld /u01/patch/33385024解压后把README.txt完整读一遍。重点看三处最低 OPatch 版本、是否有必须先行安装的前置补丁、是否有必须停掉哪些进程的说明。有些补丁会明确要求先应用某个前置补丁README 里写了而你跳过了apply 时会报冲突那时候再回头补前置补丁顺序就乱了。3.2 三条 prereq 命令的判读无冲突、有冲突、已挂起opatch prereq是一组只检查不动手的命令我一般跑三条平台适用性、冲突检查、挂起补丁检查。三条都过了再谈 apply。cd /u01/patch/33385024 # 1) 补丁是否适用于当前平台与 ORACLE_HOME 版本 $ORACLE_HOME/OPatch/opatch prereq CheckPatchApplicableOnCurrentPlatform \ -phBaseDir /u01/patch/33385024 # 2) 与已安装补丁的冲突检查最关键的一条 $ORACLE_HOME/OPatch/opatch prereq CheckConflictAgainstOHWithDetail \ -phBaseDir /u01/patch/33385024 # 3) 是否存在被挂起suspended的补丁——这类补丁的文件已被临时移走 $ORACLE_HOME/OPatch/opatch prereq CheckSuspendedPatches \ -phBaseDir /u01/patch/33385024-phBaseDir指向的是解压后包含etc/和files/的那一层目录也就是/u01/patch/33385024不是它上一层/u01/patch。这个参数指错opatch 会报找不到inventory.xml很多人第一反应是包解压坏了其实只是路径少写了一级。三条命令的输出我按三种情况判读第一种全部输出Prereq checkConflictAgainstOHWithDetail passed.这类通过信息退出码为 0。这是最理想的状态可以直接进第 4 章。第二种输出里出现Conflicts with patch(es):并列出补丁号。这说明当前 ORACLE_HOME 里已有的某个补丁和要装的这个补丁改动了同一批文件。这种情况不能硬上硬上的结果是 apply 中途失败或者装完之后文件处于半新半旧的状态。第三种输出里出现Patch is suspended或者挂起相关提示。suspended 状态意味着之前有人对某个补丁做了opatch rollback -no_inventory之类的操作文件被移走了但 inventory 记录还在环境处于一种不一致状态。这种情况必须先处理挂起补丁让环境回到干净基线否则后续任何补丁都装不稳。# 查看哪些补丁处于 suspended 状态 $ORACLE_HOME/OPatch/opatch lsinventory -suspended # 处理挂起补丁先恢复-restore再决定去留 $ORACLE_HOME/OPatch/opatch rollback -id 挂起的补丁号 -restore-restore这个参数容易被忽略它的作用是把之前被移走的文件放回去、让该补丁回到正常已安装状态。恢复之后再决定是保留还是正式回滚主动权就在你手上了。3.3 冲突结果怎么处置回滚已有补丁还是放弃冲突检查报出冲突摆在面前的选择通常只有两个回滚已有补丁或者放弃这次安装。第三个选项——用-force硬装——听起来诱人实际是把两个改同一批文件的补丁叠在一起谁覆盖谁取决于执行顺序出了问题几乎无法定位。判断依据是补丁的层级关系。如果已有的补丁是比 p33385024 更新的同类补丁比如后续发布的累计补丁那么正确做法是放弃安装 p33385024因为你已经有更新的修复了。判断方法看 README 里的补丁描述和发布日期以及lsinventory里已有补丁的时间戳。# 看已有补丁的安装时间与描述 $ORACLE_HOME/OPatch/opatch lsinventory -detail | grep -A3 -i patch description | head -40如果已有补丁是一个独立的、只修了某一个小问题的补丁而 p33385024 是包含它的更大集合那正确做法是先回滚那个小补丁再装 p33385024。回滚必须走正规流程# 回滚前先停掉所有 WebLogic 进程 # 回滚指定补丁OPatch 会从 .patch_storage 还原文件 $ORACLE_HOME/OPatch/opatch rollback -id 冲突补丁号 # 回滚后再跑一次冲突检查确认干净 $ORACLE_HOME/OPatch/opatch prereq CheckConflictAgainstOHWithDetail \ -phBaseDir /u01/patch/33385024回滚的顺序是后装的先回。如果一个 ORACLE_HOME 上叠了三四个补丁且它们之间有依赖回滚顺序错了会报Patch is required by other patches。OPatch 的输出会明确告诉你哪个补丁依赖它照着提示逆序回就行。提示回滚之前务必确认.patch_storage目录完好。这个目录一旦被清理过有些空间清理脚本会把它当垃圾删掉回滚就会失败届时只能靠整目录归档恢复。这就是 2.3 节那份 ORACLE_HOME 备份存在的意义。还有一个常被问到的场景冲突报的是部分文件冲突也就是只有几个 jar 有交集。这种情况依然不建议 force因为 OPatch 的冲突判断是基于文件哈希的报冲突就说明两边的文件确实不一致强行覆盖后 inventory 里会留下两条指向同一文件的记录后续再打补丁时判断会彻底混乱。4. 正式应用 p33385024apply 的每一步、参数与静默批量前面三章都是准备这一章才真正改文件。opatch apply交互模式下会抛出一串提示很多人一路按 y 按过去其实每一问都对应一个决策。搞清楚这些提示在问什么静默模式和批量脚本才写得对。4.1 停服务与交互式 apply屏幕上每个提示在问什么停服务的顺序是 Managed Server 先、Admin Server 后启动顺序反过来。这个顺序不是仪式感是因为 Admin Server 承担配置分发职责它先停的话 Managed Server 会在超时后进入一种半死不活的状态端口还占着但不再响应。# 在域目录下执行按实际 server 名调整 DOMAIN_HOME/u01/app/middleware/user_projects/domains/base_domain # 先停所有受管节点 for s in app_server_1 app_server_2; do $DOMAIN_HOME/bin/stopManagedWebLogic.sh $s t3://127.0.0.1:7001 done # 最后停管理节点 $DOMAIN_HOME/bin/stopWebLogic.sh # 确认进程真的没了别只看脚本返回码 ps -ef | grep -i weblogic | grep -v grepstopManagedWebLogic.sh的第一个参数是 server 名第二个是 Admin Server 的监听地址。如果环境里配置了节点管理器Node Manager服务可能是被 NM 拉起来的这种情况下脚本停了之后 NM 可能又给你拉起来需要用stopNodeManager或者从 NM 侧停。ps -ef这一步别省脚本返回 0 但进程还在的情况我见过不止一次。停干净后执行 applycd /u01/patch/33385024 # 指定 ORACLE_HOME 执行避免环境变量指向别的 home $ORACLE_HOME/OPatch/opatch apply -oh $ORACLE_HOME交互过程大致分三段。第一段是版本与环境自检输出 OPatch 版本、ORACLE_HOME 路径、inventory 位置然后问你是否继续。这一问之前要核对屏幕上打印的 ORACLE_HOME 是不是你以为的那个——同一台机器上装了两套 12.1.3 的情况并不罕见-oh参数就是防这个的。第二段是补丁信息确认列出补丁号、组件、语言、是否包含online部分然后问Do you want to proceed? [y|n]。到这一步说明冲突检查已经过了可以按 y。第三段是 OCM配置管理相关的注册信息询问。如果环境没配 OCMOPatch 会提示跳过或者要求输入邮箱输入一个合法格式的邮箱地址即可继续。这一段纯粹是为了收集部署信息不影响补丁效果但在无人值守场景下它会卡住脚本所以静默模式必须处理这个问题。# 静默模式不产生任何交互提示适合脚本化 $ORACLE_HOME/OPatch/opatch apply \ -oh $ORACLE_HOME \ -silent \ -ocmrf /u01/patch/ocm.rsp参数逐个说-oh显式指定目标 ORACLE_HOME-silent关闭所有交互遇到需要确认的地方默认继续-ocmrf指向一个预填好的 OCM 响应文件把第三段那个邮箱询问也消掉。响应文件的具体字段名各版本略有差异做法是从环境里已有的模板复制一份改内容不要凭记忆手写。如果只是想看补丁会做什么而不实际改文件加-report或者-analyze# 只分析不改文件输出将要执行的动作清单 $ORACLE_HOME/OPatch/opatch apply -oh $ORACLE_HOME -analyze-analyze的输出能告诉你这个补丁会动多少个文件、有没有文件在当前 ORACLE_HOME 里不存在新增文件。新增文件多说明这是个包含新功能的补丁覆盖文件多说明是修复型补丁。这个信息在向业务方解释为什么要停机时挺有用。4.2 静默模式与 ocm.rsp批量节点怎么写单机手点没问题节点一多就必须静默。静默的关键是两件事响应文件备好日志重定向好。# 准备响应文件从已有的模板复制只改必要字段 cp $ORACLE_HOME/OPatch/ocm/ocm.rsp /u01/patch/ocm.rsp chmod 600 /u01/patch/ocm.rsp # 单节点静默应用日志带时间戳落到固定目录 LOG/u01/patch/logs/apply_$(hostname)_$(date %Y%m%d%H%M).log $ORACLE_HOME/OPatch/opatch apply \ -oh $ORACLE_HOME \ -silent \ -ocmrf /u01/patch/ocm.rsp \ $LOG 21 echo exit$? $LOG # 从日志里抓结论行不用通读全文件 grep -Ei success|fail|error|completed $LOG21不能漏。OPatch 的失败信息有相当一部分走的是 stderr只重定向 stdout 的话日得里看到的是正常往下跑退出码却非 0排查时容易被误导。chmod 600是给响应文件加权限里面可能有环境标识信息没必要让所有人可读。多节点场景下apply 本身是每个 ORACLE_HOME 各跑一次的关系。如果多个节点共享同一个 ORACLE_HOME比如通过共享存储那只能在一台上执行一次不要每台都跑——Generic补丁的files是写进 ORACLE_HOME 的共享目录跑两次会导致第二次报补丁已安装或者更糟的文件状态混乱。判断方式很简单# 确认各节点的 ORACLE_HOME 是否为同一份物理目录 for h in node1 node2 node3; do echo -n $h: ssh $h readlink -f \$ORACLE_HOME; stat -c %d:%i \$ORACLE_HOME done设备号加 inode 相同就是同一个物理目录只需打一次。不同则是各自独立的 home每个都要打。这个检查耗时不到一分钟但能避免一整类为什么两台机器行为不一致的疑难问题。4.3 应用后的验证lsinventory、文件比对与启动顺序apply 返回 0 不等于完事验证要做三层。第一层inventory 里能查到补丁$ORACLE_HOME/OPatch/opatch lsinventory -detail -patch 33385024正常输出会包含补丁号、组件列表、安装时间以及Patch is installed之类的状态描述。如果这里查不到说明 apply 虽然返回 0 但 inventory 没写成功多半是前面 2.1 节提到的 inventory 权限问题。第二层和打补丁前的 log 做比对# 重新抓一份当前清单 $ORACLE_HOME/OPatch/opatch lsinventory -detail /tmp/lsinv_after_$(date %Y%m%d).log # 只看补丁号级别的差异忽略时间戳噪声 diff (grep -i patch /tmp/lsinv_before_*.log | sort) \ (grep -i patch /tmp/lsinv_after_*.log | sort)diff 应该只显示新增了 33385024 这一条。如果还出现了别的补丁被移除那一定是中间有人执行过回滚这个环境需要重新评估。第三层文件层面抽样确认。从files目录里挑几个文件对比 ORACLE_HOME 里对应文件的修改时间和大小。# 抽样比对三个文件确认已被补丁版本替换 for f in wlserver/server/lib/weblogic.jar \ wlserver/common/bin/wlst.sh \ coherence/lib/coherence.jar; do ls -l $ORACLE_HOME/$f done时间戳应该落在 apply 执行的那个时间窗口内。如果某个文件的时间还是几个月前说明这个文件没被替换可能是权限不足导致拷贝失败——OPatch 日志里会有Unable to copy之类的记录只是不会中断整个 apply。验证过了再启动。启动顺序Admin Server 先起到RUNNING再起 Managed Server。# 启动管理节点后台跑并观察日志 nohup $DOMAIN_HOME/bin/startWebLogic.sh /u01/logs/admin_start.log 21 # 等状态变成 RUNNING 再继续别急着起受管 tail -f /u01/logs/admin_start.log | grep -m1 RUNNING # 再起受管节点 for s in app_server_1 app_server_2; do nohup $DOMAIN_HOME/bin/startManagedWebLogic.sh $s t3://127.0.0.1:7001 \ /u01/logs/${s}_start.log 21 done补丁改过类文件之后域目录下的servers/server/tmp和cache里可能残留着旧版本的序列化对象或编译缓存启动时偶发类冲突。常见做法是停服后清理这两个目录再启动位置在$DOMAIN_HOME/servers/server_name/下清之前同样建议先备份。5. 打补丁的五个翻车现场从报错到处置下面这五条都是真金白银换来的每一条都按现象 → 原因 → 解决写。遇到类似报错时按顺序对照比自己从日志头翻到尾快得多。5.1 报 not applicable on this Oracle Home版本段对不上现象opatch apply刚跑起来就退出日志里写Patch 33385024 is not applicable on this Oracle Home或者the patch is not applicable to the current platform。原因ORACLE_HOME 的实际版本不是 12.1.3.0.0。文件名里的121300是补丁的适用版本段如果目标 home 是 12.1.2 或者 12.2.1补丁的inventory.xml里版本约束会直接把它拒掉。另一个可能是平台标识不匹配虽然Generic号称跨平台但某些平台组合仍会被拒。解决先确认版本别猜。# 从 ORACLE_HOME 读版本比猜文件名可靠 cat $ORACLE_HOME/inventory/registry.xml | grep -i version | head -5 # 或者用 OPatch 的视角看 $ORACLE_HOME/OPatch/opatch lsinventory -detail | grep -i oracle home -A2版本确实对不上唯一正确的做法是去拿对应版本的补丁包不要试图改inventory.xml里的版本约束——那是把校验绕过而不是解决问题装上去之后文件版本错配运行时报的错会比现在难查十倍。5.2 apply 跑到一半报 No space left on device空间核算漏了 .patch_storage现象apply 进度条走到某个百分比后失败日志末尾是java.io.IOException: No space left on device此时 ORACLE_HOME 里的文件已经被改了一部分。原因只算了补丁包解压后的体积没算.patch_storage里要保存的原文件副本。Generic补丁的files展开加上备份副本实际占用通常是解压体积的两倍左右。解决清理空间后重跑但重跑前要先确认环境是否处于半应用状态。# 看 inventory 里有没有这条补丁的半截记录 $ORACLE_HOME/OPatch/opatch lsinventory -detail -patch 33385024 # 如果报了但在 .patch_storage 里没找到完整备份说明是半应用状态 ls -l $ORACLE_HOME/.patch_storage/33385024/ 2/dev/null | head半应用状态下最稳的处置是用 2.3 节的整目录归档回滚到打补丁之前清理空间后重来。试图接着装是不行的OPatch 没有断点续传的概念。回滚之后按 5G 余量的标准重新核算空间。5.3 启动报类找不到或 NoClassDefFoundError缓存没清现象补丁应用成功lsinventory也能查到但服务启动时报java.lang.NoClassDefFoundError或者莫名其妙的ClassNotFoundException报的类名看着眼熟jar 也确实存在。原因域目录下servers/server/tmp和cache里残留着补丁前的类缓存或序列化对象。WebLogic 启动时会读这些缓存来加速缓存里记录的类签名和补丁后的实际类对不上就会报这种看着有却找不到的错。解决停服状态清理缓存再启动。# 停服后执行先备份再清理 for s in AdminServer app_server_1 app_server_2; do d$DOMAIN_HOME/servers/$s [ -d $d/tmp ] mv $d/tmp $d/tmp.bak.$(date %Y%m%d) [ -d $d/cache ] mv $d/cache $d/cache.bak.$(date %Y%m%d) donemv比rm好出问题还能挪回来。清完之后首次启动会慢一些因为要重建缓存属于正常现象。5.4 多节点行为不一致只打了一部分 home现象集群里部分节点正常部分节点启动失败或者功能异常日志对比发现类版本不同。原因环境里存在多个独立的 ORACLE_HOME非共享存储补丁只打在了其中一部分。或者共享 ORACLE_HOME 的情况下有人在多个节点上重复执行了 apply导致 inventory 记录重复。解决先普查再统一。# 每个节点上查一遍补丁是否存在输出为空的节点就是漏打的 for h in node1 node2 node3; do echo $h ssh $h $ORACLE_HOME/OPatch/opatch lsinventory -detail -patch 33385024 \ | grep -i patch description || echo NOT INSTALLED done漏打的补上即可重复执行过的要看lsinventory里是否有重复条目有的话需要按 OPatch 的提示做一次 inventory 修复不建议手工编辑 inventory 文件。5.5 回滚报 patch is required by other patches顺序错了现象想回滚某个补丁OPatch 拒绝执行并列出依赖它的补丁号。原因后装的补丁依赖先装的补丁提供的文件直接回滚前者会把后者需要的文件抽走。OPatch 的依赖检查就是为了防这个。解决按依赖逆序回滚从最上层开始。# OPatch 报错信息里会列出依赖关系按它给的顺序从后往前滚 $ORACLE_HOME/OPatch/opatch rollback -id 最后装的补丁号 $ORACLE_HOME/OPatch/opatch rollback -id 次后装的补丁号回滚完每一层都跑一次lsinventory确认状态再继续下一层。不要连发一串命令然后一起看结果中间出问题时你分不清是哪一层失败的。6. 回滚预案与批量落地把补丁流程固化成脚本补丁这事装的时候想的是赶紧装完出事的时候想的是怎么退回去。回滚路径必须在 apply 之前就设计好而不是等启动失败才翻文档。这一章讲两件事回滚的正确姿势以及怎么把前面所有检查步骤做成一个可以重复执行的脚本。6.1 rollback 的前提、顺序与失败处理回滚的前提有三个缺一不可.patch_storage里该补丁的备份完整、inventory 记录完好、服务已全部停止。三个前提里最容易出问题的是第一个因为空间清理脚本经常把它当垃圾。# 回滚前先确认备份完整度目录里应该有 files 和 inventory 相关文件 ls -l $ORACLE_HOME/.patch_storage/33385024/ du -sh $ORACLE_HOME/.patch_storage/33385024/ # 停服后执行回滚 $ORACLE_HOME/OPatch/opatch rollback -id 33385024 -oh $ORACLE_HOME # 确认 inventory 里已经查不到了 $ORACLE_HOME/OPatch/opatch lsinventory -detail -patch 33385024rollback的-id参数是补丁号不带p前缀。回滚完成后lsinventory -patch应该报找不到该补丁这是预期结果。回滚失败最常见的原因是备份文件缺失报错通常是Unable to find the original file并列出具体路径。这种情况下 OPatch 无法继续只能从整目录归档恢复。恢复的操作是停服 → 把当前 ORACLE_HOME 改名留档 → 解压归档 → 恢复oraInst.loc指向 → 验证lsinventory。# 归档恢复的大致流程务必在维护窗口内做 mv $ORACLE_HOME ${ORACLE_HOME}.broken.$(date %Y%m%d) mkdir -p /u01/app tar -pxzf /backup/oracle_home_host_时间戳.tar.gz -C /u01/app # 恢复后确认 inventory 指针与属主 ls -ld /u01/app/middleware $ORACLE_HOME/OPatch/opatch lsinventory /dev/null echo restore OKtar的-p参数用于保留权限位这个不能省。少了它解压出来的文件属主和权限位可能和原来不一致WebLogic 启动时会因为读不到某些配置文件而失败。恢复完成后的验证除了lsinventory还要抽样看几个关键文件的属主是不是中间件用户。6.2 一个多节点批量校验脚本前面所有检查步骤单独跑一次不麻烦麻烦的是每次打补丁都要重跑一遍而且节点一多就容易漏。我的习惯是把它做成一个只读的巡检脚本在任何 apply 之前跑一次输出一份能不能打的结论。#!/bin/bash # patch_precheck.sh —— 补丁前置巡检只读不写 set -uo pipefail PATCH_ID33385024 PATCH_DIR/u01/patch/${PATCH_ID} NODESnode1 node2 node3 FAIL0 for h in $NODES; do echo $h # 1) ORACLE_HOME 是否可达、是否可写 home$(ssh $h echo $ORACLE_HOME) if [ -z $home ]; then echo [FAIL] ORACLE_HOME 未设置; FAIL1; continue fi # 2) 版本段是否匹配 12.1.3.0.0 ver$(ssh $h grep -o 12\.[0-9]\.[0-9]\.[0-9]\.[0-9] $home/inventory/registry.xml | head -1) echo [INFO] 版本: ${ver:-未识别} # 3) 磁盘余量低于 5G 直接判失败 avail$(ssh $h df -Pm $home | awk NR2{print \$4}) if [ $avail -lt 5120 ]; then echo [FAIL] 可用空间 ${avail}MB 5120MB; FAIL1 else echo [INFO] 可用空间 ${avail}MB fi # 4) 是否已装过该补丁避免重复 apply if ssh $h $home/OPatch/opatch lsinventory -detail -patch $PATCH_ID \ | grep -qi patch description; then echo [SKIP] 补丁已存在 else echo [INFO] 补丁未安装 fi # 5) 冲突检查只看退出码 if ssh $h cd $PATCH_DIR $home/OPatch/opatch prereq \ CheckConflictAgainstOHWithDetail -phBaseDir $PATCH_DIR /dev/null 21; then echo [PASS] 无冲突 else echo [FAIL] 存在冲突需人工判读; FAIL1 fi done echo 结论 [ $FAIL -eq 0 ] echo 全部节点可进入 apply 阶段 || echo 存在阻塞项先处置再 apply exit $FAIL脚本里的几个设计选择值得说明。set -uo pipefail只开了未定义变量检查和管道错误检查故意没开-e因为巡检要跑完所有节点、收集全部问题中途退出会让后面的节点失去检查机会。df -Pm用 POSIX 格式输出并以 MB 为单位避免不同文件系统的输出列数差异导致 awk 取错列。第 4 步的已装过就跳过很关键它挡住了重复 apply 这个最常见的误操作。退出码的设计让它能直接接进 CI 或者发布流水线0 表示可以继续非 0 表示有阻塞。我一般会把这个脚本和 apply 脚本分开巡检通过之后再人工触发 apply不做成全自动——补丁这种操作中间留一个人工确认点是有价值的。从那以后我每次打补丁前都强制走一遍这个巡检哪怕只是单个节点、哪怕补丁包看起来再简单。真正让我养成习惯的是早期一次漏查磁盘空间的经历apply 跑到 80% 卡死回滚又因为.patch_storage写了一半而不完整最后靠整目录归档恢复停机窗口硬生生多出三个小时。巡检脚本那几十行代码换的就是这三个小时。希望帮到你。本文还有配套的精品资源点击获取
📌 标签:
工业官网
设计趋势
AI 建站
SEO
获取完整报告 →
RELATED ARTICLES
推荐阅读
2026/10/24 4:33:21
白金4.83远控源码拆包:中文键盘记录模块的落地实践与避坑指南
2026/10/24 4:33:21
有源电力滤波器仿真中PI与重复控制的复合谐波抑制策略
2026/10/24 4:33:21
Qt/C++实战工业MES:多线程架构、PLC采集与防错追溯全解析
2026/10/24 5:48:54
ArkUI Image组件全解析:从资源加载到缩放裁切,解决图片显示难题
2026/10/24 5:48:54
Windows下MinGW编译libmesh:工具链配置与避坑指南
2026/10/24 5:48:54
高考语文默写72篇:从背诵到情境默写的全攻略
2026/10/24 5:48:54
Windows下用MinGW编译libMesh:环境配置、编译与避坑指南
2026/10/24 5:48:54
CAsyncSocket 异步套接字与 MFC 消息驱动 TCP 收发链路
2026/10/24 5:43:54
C#虹软ArcFace SDK 3.0 WinForms实战:活体检测+本地人脸库+线程安全封装
2026/10/24 0:02:52
UDP协议实现局域网音量与关机控制:后台常驻与批量管理
2026/10/24 0:02:52
MATLAB缩进快捷键与批量格式化实战指南
2026/10/24 0:02:52
用Poco实现Qt风格信号与槽的跨平台C++方案
2026/10/24 4:01:50
OpenResearch实战:Claude Code、Codex、OpenCode、Cursor 工作流搭建与故障排查
2026/10/24 4:01:49
知识管理核弹:用Obsidian构建第二大脑的工程化方案(TaoToken 统一 Key 接入版)
2026/10/24 0:59:24
金融AI落地指南:从调研报告到技术选型与工程实践
2026/10/23 10:58:39
我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
2026/10/23 10:58:39
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026/10/23 10:58:39
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)