news 2026/10/27 2:29:13

Oracle 11.2.0.3 补丁包 OPatch 应用与回滚实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Oracle 11.2.0.3 补丁包 OPatch 应用与回滚实战

简介:这份压缩包为 Oracle 11.2.0.3 数据库的补丁集更新 p20760997,适用于 Linux x86-64 平台,面向仍需维护 Oracle 11g 的数据库管理员与系统运维人员。其内容对应 11.2.0.3.15 版本更新,并包含 2015 年 7 月发布的关键补丁更新(CPU),可用于评估安全修复、版本升级与旧系统补丁合规性。压缩包为 zip 格式,体积约 100.73MB;上游未提供文件总数与文件类型明细,因此包内构成需以下载后的实际清单为准。目前已有 291 人学习或下载,说明该补丁在旧版 Oracle 维护场景中仍有一定关注度。对于需要核对补丁适用版本、梳理安全更新范围或留存补丁资料的技术人员,这份资源可作为补丁识别与维护决策的参考,帮助快速定位 11.2.0.3.15 与 CPUJUL2015 的对应关系,并为后续补丁验证、备份与变更管理提供依据。

1. 从 p20760997 补丁包说起:一个 11.2.0.3 场景的落地起点

数据库维护窗口就那么几小时,运维同学在跳板机上敲opatch apply,卡在 prereq 阶段反复重试——这是 oracle patch 场景里最常见的开场白。p20760997_112030_Linux-x86-64.zip的文件名本身就是一份说明书:p20760997是补丁编号,112030对应 11.2.0.3 这个内核版本,Linux-x86-64是平台标签。它把一组针对特定版本和平台的修复打包成 OPatch 能直接消费的目录结构,配套 inventory 元数据,在目标ORACLE_HOME上做增量替换;它解决的不是“装一个新软件”的问题,而是“让现有库在已知缺陷或已知安全项上达到一致状态”的问题。适合正在维护 11g R2 单实例或 RAC 的 DBA、刚接手补丁交接的运维,以及想搞清楚每条 opatch 命令背后到底动了什么文件的技术人员。

2. 解压先看目录:补丁包里哪几个文件决定成败

拿到 zip 之后第一件事不是apply,而是把压缩包解开,先站在目录层面判断“这是什么类型的补丁”。补丁编号能说明它是针对 11.2.0.3 Linux 平台的某个具体修复,但类型(PSU、CPU、单点补丁、Bundle Patch)不同,后续的 post-install 动作差别很大,README 是第一判据。

解压命令本身不复杂,要注意的是解压路径不要放在ORACLE_HOME里,也不要在共享目录里跑 OPatch 的apply,否则 inventory 记录的路径会和实际文件路径对不上,这是后面回滚翻车的根源之一。

# 解压到一个独立目录,路径里不要带空格,也不要放在 ORACLE_HOME 下 mkdir -p /u01/soft/patch_work cd /u01/soft/patch_work unzip -q p20760997_112030_Linux-x86-64.zip ls -l

命令说明:unzip -q的-q是静默模式,避免输出几千行文件列表把关键报错冲掉;mkdir -p保证中间目录不存在也能建起来。执行完你会看到一个以补丁号命名的目录(比如./20760997/),它才是 OPatch 真正要消费的-phBaseDir,zip 包本身不是。

2.1 目录骨架:README、etc、files、custom 四块各管什么

解压后的典型结构可以按职责拆成四块,先认清四块再决定跑哪条命令:

路径作用要不要动
README.html/README.txt版本要求、冲突说明、post-install 步骤必读,先读
etc/config/inventory.xml补丁元数据,OPatch 靠它做匹配校验只读,不改
etc/config/actions.xml文件动作清单,OPatch apply 的执行剧本只读,不改
files/真正要被替换或新增的文件本体不改,交给 OPatch
custom/scripts/post-install 或 pre-install 脚本按 README 执行

这四个区块里,etc/config/是 OPatch 的“黑匣子”,补丁能不能打、打了会不会和现有补丁冲突,全靠这里的元数据和ORACLE_HOME上的 inventory 对撞。files/下面按rdbms/admin、lib、bin分层,看到lib/下有.so就是库层变更,看到rdbms/admin/下有.sql通常意味着应用层也要补一步catbundle或postinstall,这一步漏了,补丁表面装上了,数据字典版本却没对齐。

2.2 README 只抓三段,别从头读到尾

README 动辄几十页,真正影响操作的是三段。第一段是“Prerequisites”,搜关键字OPatch和minimum,把要求的最低 OPatch 版本号抄下来;第二段是“Patch Installation”,看它是纯opatch apply,还是要求先跑preinstall.sql、再apply、最后跑postinstall.sql;第三段是“Post Installation”,确认是catbundle.sql psu apply还是catcpu.sql,这直接决定 DB 端要不要再动一次。

一个实用的过滤方式,别靠眼睛扫:

# 在补丁目录里定位关键段落,避免漏读 cd /u01/soft/patch_work/20760997 grep -n -i -E "opatch|minimum|post.?install|catbundle|catcpu|conflict" README.html | head -40

参数说明:-i忽略大小写,-E开扩展正则,-n带行号方便回看上下文,head -40只取前 40 条,避免输出太长。看到 “post-install” 附近有catbundle或@?/rdbms/admin/字样,就说明这次打完还要连库跑 SQL,窗口时间要多留 10~15 分钟。

注意:不同补丁的 README 命名和章节顺序不一样,grep命中的行号只是入口,真正执行前还是要回到原段落把前后文读完,尤其是“Known Issues”一节,很多冲突说明就藏在那里。

2.3 inventory.xml 和补丁元数据:判断“这个补丁和我现有环境配不配”

etc/config/inventory.xml里最关键的是补丁适用版本、平台标识和子补丁清单。打开看头部,如果出现112030和Linux-x86-64这两个值,说明平台层面是对得上的;如果里面罗列了子补丁 ID,说明这是一个 composite patch,回滚时要用主补丁号一次回滚,不是逐个回滚子补丁。

# 看补丁声明的版本与平台,快速判断是否匹配目标库 cd /u01/soft/patch_work/20760997 grep -E "version|platform|112030|Linux" etc/config/inventory.xml | head -20

这一步不是走形式。补丁 ID 的版本段和实际要应用的ORACLE_HOME版本必须一致,opatch apply在 prereq 阶段会做一次校验,但人工先看一眼能省掉一次失败尝试的时间。尤其是手上有多个版本的ORACLE_HOME、或者同一台机器上同时跑 GI 和 DB 两套 home 时,先确认补丁属于哪个 home,比事后lsinventory对不上要省事得多。

3. 让 OPatch 先过关:版本、JDK 与空间的三道校验

补丁本身没问题,卡人的往往是 OPatch 这一环。11.2.0.3 时代的 OPatch 和 JDK 是绑定的,OPatch 版本偏老,会在apply第一步直接拒绝执行,报“OPatch version is lower than minimum”。与其等它报错,不如把三道校验前置做完再动库。

3.1 先看 OPatch 版本和它依赖的 JDK

OPatch 是 Java 写的,opatch version能跑通,说明当前 shell 能找到ORACLE_HOME下的 JDK。先看版本,再看 README 要求的最低版本,两者对上再往下走。

# 切到 oracle 用户,确认环境变量和 OPatch 版本 su - oracle echo "ORACLE_HOME=$ORACLE_HOME" echo "ORACLE_SID=$ORACLE_SID" $ORACLE_HOME/OPatch/opatch version

命令说明:su - oracle的-不能省,它会把 oracle 用户的 profile 加载进来,ORACLE_HOME和ORACLE_SID才会生效;opatch version的返回值形如OPatch Version: 11.2.0.3.x,把最后一段和 README 里的最低版本比对。版本低了不要硬打,直接去补丁目录里看 README 有没有附带 OPatch 升级说明,或者先从同一版本分支里取一个匹配的 OPatch 目录替换掉,替换前把旧的OPatch目录整体备份。

提示:替换 OPatch 目录时,只换OPatch本身,别动OPatch/auto之外的东西,也不要改oraInst.loc里指向的 inventory 目录,否则原来的补丁记录会被“看不见”。

3.2 环境变量和目录所有者:权限问题的根子

OPatch 对ORACLE_HOME的读写权限要求很硬:执行apply的用户必须对ORACLE_HOME和 inventory 目录都有写权限。常见做法是用oracle用户直接跑,不要用root加sudo跑完再改回属主,inventory 里记录的 owner 会跟实际不一致,后续lsinventory和回滚都受影响。

# 确认关键目录的属主和权限,避免“能读不能写” ls -ld $ORACLE_HOME $ORACLE_HOME/OPatch $ORACLE_HOME/inventory ls -ld /u01/app/oraInventory id oracle

命令说明:ls -ld只列目录本身,不展开内容;/u01/app/oraInventory是oraInst.loc里指定的中央 inventory 位置,必须在同一用户可写。如果发现属主是root或者权限是dr-xr-xr-x,先把权限修正到oracle:oinstall再继续,别急着往下跑apply。

另外,共享存储上挂载的ORACLE_HOME还要检查挂载选项里有没有noexec,有些补丁会调用ORACLE_HOME下的二进制做校验,noexec会导致校验阶段就失败,报错信息还很不直观。

3.3 prereq 和冲突检测:把“能不能打”提前问清楚

opatch apply其实内置了 prereq 和冲突检测,但分开跑一遍能看到更详细的检查项,失败时也能定位到具体是哪一条不过。冲突检测要指定-phBaseDir,指向解压出来的补丁目录本身。

cd /u01/soft/patch_work $ORACLE_HOME/OPatch/opatch prereq CheckConflictAgainstOHWithDetail -phBaseDir ./20760997 $ORACLE_HOME/OPatch/opatch prereq CheckSystemSpace -phBaseDir ./20760997

命令说明:第一条检查补丁和当前ORACLE_HOME上已装补丁是否有文件级冲突,输出里如果有Conflict字样,说明同一批文件被另一个补丁改过,要按 README 的顺序先回滚或先打前置补丁;第二条检查磁盘空间,files/下的文件总大小加上回滚需要的备份空间,一般要预留 2 倍以上。输出最后一行通常是Prereq "checkSystemSpace" passed或failed,看到 failed 就回去补空间。

冲突检测通过不代表万事大吉,它只覆盖 inventory 层面,不覆盖运行中的实例。真正执行apply前,单实例建议把库停到nomount或完全关闭,RAC 至少保证目标节点上的实例已经停掉。补丁包里如果含lib/下的库文件,运行中的进程会持有文件句柄,apply会报Text file busy或文件替换失败。

4. 应用 oracle patch:单实例静默与 RAC 逐节点的两条路径

校验都过了,才轮到真正的apply。单实例和 RAC 的差异不在命令本身,而在“一次跑几个节点、跑完怎么同步”。单实例路径简单直接,RAC 路径的关键是“逐节点 + 先 GI 后 DB”的节奏,顺序错了 inventory 会出现节点间不一致。

4.1 单实例:静默应用 + 备份留后路

单实例先把实例停到只剩后台进程,然后用-silent跑 apply,把有限的窗口留给真正耗时的文件替换。apply 过程中 OPatch 会把被替换的文件备份到ORACLE_HOME/.patch_storage下,这是回滚的后悔药,备份目录不要手动清理。

# 单实例:先停库,再静默 apply export PATH=$ORACLE_HOME/bin:$PATH sqlplus / as sysdba <<'EOF' shutdown immediate; exit; EOF cd /u01/soft/patch_work/20760997 $ORACLE_HOME/OPatch/opatch apply -silent

命令说明:shutdown immediate用immediate而不是abort,让检查点正常落盘,回滚时数据文件状态更干净;opatch apply -silent执行时当前目录必须是补丁目录,OPatch 会从etc/config/actions.xml里读动作清单,-silent只是关掉交互提示,不减少任何检查。执行成功后最后一行通常是OPatch succeeded,此时files/下的内容已经被复制进ORACLE_HOME。

apply 成功后先别急着起库,看 README 有没有 post-install SQL。11.2.0.3 的 PSU 类补丁通常要在库启动到open之后跑一次 bundle 脚本,把数据字典里的补丁记录写进去:

# 起库到 open,再跑 post-install 脚本(具体脚本名以 README 为准) sqlplus / as sysdba <<'EOF' startup; exit; EOF cd $ORACLE_HOME/rdbms/admin sqlplus / as sysdba @catbundle.sql psu apply

命令说明:@catbundle.sql psu apply是 11.2.0.3 PSU 场景的常见写法,参数psu表示 patch set update,apply表示正向登记;如果是 CPU 补丁,脚本名和参数会换成catcpu.sql。跑完要再执行一次@utlrp.sql编译失效对象,这一步漏掉,应用连上来可能报一堆ORA-04063。

4.2 RAC:逐节点-local,先 GI 后 DB

RAC 上最稳妥的做法是逐节点应用,一个节点打、其他节点照常提供服务,打完一个再滚动到下一个。命令上要给-local,让 OPatch 只处理当前节点,而不是试图一次性推所有节点。

# RAC 每个节点上分别执行,-local 表示只处理本节点 cd /u01/soft/patch_work/20760997 $ORACLE_HOME/OPatch/opatch apply -local -silent

命令说明:-local是关键参数,没有它,OPatch 在某些版本上会去读集群层面的 inventory 并尝试跨节点操作,失败的报错还很难定位;-silent同单实例。每个节点打完,在本节点上跑一次opatch lsinventory确认补丁号出现在列表里,再滚动到下一个节点。

GI home 和 DB home 都要打补丁时,顺序按 README 来,绝大多数情况下是“先 GI、后 DB”,因为 DB 侧的一些校验会读 GI 的版本。GI 侧打完通常还要按 README 执行root.sh或crsctl stop/start滚动重启集群件,这一步由 root 执行,命令要抄准,别凭记忆敲。

注意:RAC 滚动过程中,如果某个节点 apply 失败,先停下来看该节点的$ORACLE_HOME/cfgtoollogs/opatch/下的日志,不要继续往后面的节点推。节点间 inventory 不一致比单点失败更难收拾。

4.3 应用后动作:三类检查确认“真装上了”

OPatch succeeded只说明文件替换动作完成,不等于补丁生效。要按三层确认:文件层看lsinventory里有没有补丁号,库层看数据字典里的补丁记录,应用层做一次简单连接测试。

# 文件层:确认补丁出现在 inventory 里 $ORACLE_HOME/OPatch/opatch lsinventory | grep -i 20760997 # 库层:确认数据字典里的补丁记录 sqlplus -S / as sysdba <<'EOF' set pages 100 lines 200 select patch_id, version, action, status, action_time from dba_registry_sqlpatch order by action_time desc fetch first 5 rows only; exit; EOF

命令说明:lsinventory | grep是最快的文件层确认;dba_registry_sqlpatch是 11.2.0.3 之后登记 SQL 补丁的视图,status为SUCCESS才算真正登记成功。如果视图不存在,说明这个库的版本或补丁类型不支持该视图,退回查registry$sqlpatch或直接看catbundle的输出日志。应用层就做一次sqlplus登录加一条select 1 from dual,确认监听和实例都正常。

5. 补丁排查:四类报错对应的现象、原因与解法

补丁打不上去,报错信息往往只有一句,真正的原因藏在日志里。下面四类是在 11.2.0.3 补丁场景里反复出现的,按“现象 → 原因 → 解决”写清楚,遇到时按顺序对照。

5.1 现象:OPatch version ... is lower than minimum,apply 直接退出

原因:OPatch 版本低于 README 要求的最低版本,apply在解析补丁元数据之前就做了版本门槛检查,所以还没走到文件替换就退出。

解决:先opatch version确认当前版本,再把 README 里要求的最低版本抄下来比对。版本不够时,从同版本分支取一个匹配的 OPatch 目录整体替换,替换前mv OPatch OPatch.bak,替换后重新跑opatch version和opatch lsinventory确认 inventory 还能正常读。不要试图改 README 或者绕过检查,版本不匹配时后面的 prereq 行为也不可信。

5.2 现象:冲突检测报Conflict,或 apply 到一半报文件校验不通过

原因:ORACLE_HOME上已经装过另一个补丁,且两者修改了同一个文件;也可能是之前某次 apply 中途失败,inventory 记录的补丁状态和实际文件状态不一致。

解决:先用opatch lsinventory -detail把已装补丁列出来,对照 README 里的冲突说明确认先后顺序,按顺序回滚冲突补丁、再打当前补丁。如果是上次失败留下的半成品状态,不要直接再 apply 一次,先opatch rollback -id <上次失败的补丁号>把状态清干净,再重新走 prereq。rollback也失败时,看$ORACLE_HOME/cfgtoollogs/opatch/下的日志定位是哪个文件恢复不了,必要时从.patch_storage里手动恢复对应文件,手动恢复前先把当前文件备份。

5.3 现象:Prerequisite check "checkSystemSpace" failed,或 apply 报No space left on device

原因:/u01或ORACLE_HOME所在分区剩余空间不够。补丁应用需要同时容纳新文件、旧文件备份和日志,实际需求通常是补丁大小的 2~3 倍。

解决:先df -h看目标分区,再du -sh看.patch_storage和cfgtoollogs占了多大。空间不够时优先清理历史日志和旧的备份目录,不要删.patch_storage里当前补丁的备份,那是回滚的依据。空间实在紧张,把补丁目录放到另一个分区,-phBaseDir指向新位置,但ORACLE_HOME所在分区本身仍然要有足够空间放备份。

5.4 现象:RAC 里只有一个节点lsinventory能看到补丁号

原因:某个节点 apply 时漏了-local,或者 apply 成功但后续的 post-install 动作没在该节点执行,导致节点间 inventory 或数据字典状态不一致。

解决:在缺补丁的节点上单独重跑opatch apply -local -silent,不要在其他节点上重跑,避免把已经打好的节点再覆盖一遍。补完之后逐节点执行opatch lsinventory | grep <补丁号>做核对,并把每个节点的输出保存下来对比。数据字典层面的不一致,通过dba_registry_sqlpatch在每个实例上查一遍确认。

6. 回滚与收尾校验:lsinventory 和 rollback 必须走一遍

补丁打成功了不等于这件事结束,真正让人安心的是“知道怎么退回去”。我一般会在补丁应用完成后,趁着窗口还没关,把回滚路径完整走一遍验证,再决定是否保留。opatch rollback依赖.patch_storage里的备份,备份目录一旦被清理,回滚就只能靠恢复备份库,代价完全不是一个量级。

6.1 先看 lsinventory,再谈回滚

回滚前先确认补丁在 inventory 里的准确 ID 和状态,ID 抄错一个数字,rollback 就会报“patch not found”,然后在日志里绕半天。

# 确认补丁 ID 和当前状态,输出里会列出已装补丁及回滚信息 $ORACLE_HOME/OPatch/opatch lsinventory -detail | sed -n '/Patch Description/,/^$/p' | head -40

命令说明:-detail会输出每个补丁的描述、ID、应用时间和可回滚标记;sed -n '/.../,/^$/p'截取补丁描述段落,head -40控制输出长度。看到目标补丁号且带Rollbackable: Yes才说明备份完整,可以回滚。

6.2 rollback 的执行顺序

回滚顺序和应用顺序相反:先停库,再opatch rollback,然后按 README 决定要不要跑回滚后的 SQL 脚本,最后起库验证。

# 停库后执行回滚,-id 后跟补丁号 sqlplus / as sysdba <<'EOF' shutdown immediate; exit; EOF cd /u01/soft/patch_work/20760997 $ORACLE_HOME/OPatch/opatch rollback -id 20760997 -silent

命令说明:rollback的当前目录同样要是补丁目录,OPatch 要从这里读actions.xml反向执行;-silent关掉交互。回滚完成后lsinventory里该补丁应该消失,dba_registry_sqlpatch里对应记录状态会变成回滚相关值。RAC 场景同样逐节点-local执行,顺序和应用时相反,最后回滚的那个节点先回滚。

6.3 一张收尾自检表和一个习惯

窗口结束前,我会把下面这几项过一遍,全部有据可查才关窗口:

检查项命令或入口通过标准
补丁已登记opatch lsinventory目标补丁号在列表内
数据字典已同步dba_registry_sqlpatchstatus为SUCCESS
失效对象已编译@utlrp.sql无新增INVALID对象
回滚路径可用.patch_storage存在目标补丁Rollbackable: Yes
节点间一致每个节点lsinventory补丁号一致
应用可连sqlplus登录 + 简单查询连接与查询正常

有一次我在测试环境图省事,打完补丁直接清掉了.patch_storage想省空间,结果第二天应用侧反馈一个存储过程行为异常,想回滚回不去,只能整库恢复到前一天的备份,白白多耗了一个维护窗口。从那以后我每次打完补丁,都会先确认Rollbackable: Yes,再把整个补丁目录和对应的cfgtoollogs一起打包归档,归档做完才允许清空间。这个习惯看起来笨,但真出事时能救命。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/27 2:28:58

贪心算法核心思想与应用场景详解

1. 贪心算法核心思想解析贪心算法&#xff08;Greedy Algorithm&#xff09;是一种在每一步选择中都采取当前状态下最优决策的算法策略。这种"只看眼前最优"的特性&#xff0c;使其在解决某些特定类型问题时展现出惊人的效率。我第一次接触这个概念是在解决背包问题的…

作者头像 李华
网站建设 2026/10/27 2:28:45

SVM算法原理与实践:从基础到核技巧应用

1. SVM算法基础认知第一次接触支持向量机(SVM)是在研究生阶段的模式识别课上。教授用粉笔在黑板上画出一个二维平面上的点集&#xff0c;然后问我们&#xff1a;"如何用一条直线最好地区分这两类数据&#xff1f;"这个问题看似简单&#xff0c;却引出了机器学习中最优…

作者头像 李华
网站建设 2026/10/27 2:27:35

无标题项目的需求挖掘与敏捷开发实践

1. 项目概述作为一名从业多年的技术博主&#xff0c;我经常遇到这样的情况&#xff1a;一个看似简单的项目标题背后&#xff0c;往往隐藏着复杂的实现逻辑和丰富的技术内涵。今天我想分享的是关于"无标题"这个特殊命题的深度思考与实践经验。"无标题"这个表…

作者头像 李华
网站建设 2026/10/27 2:26:43

YOLOv8工业级优化与可视化应用实战

1. 项目背景与核心价值2025年作为计算机视觉技术发展的关键节点&#xff0c;YOLOv8凭借其卓越的实时检测性能已成为工业界实际部署的首选架构。这个项目不同于常规的目标检测教程&#xff0c;而是聚焦于工程实践中两个最关键的痛点&#xff1a;如何将YOLOv8的检测结果转化为具有…

作者头像 李华
网站建设 2026/10/27 2:25:38

K3 Wise基础资料同步:SQL脚本实现高可靠主数据一致性

简介&#xff1a;本资源是一套专为金蝶K3 Wise系统实施与运维人员设计的基础资料同步SQL脚本集&#xff0c;适用于ERP系统初始化、多账套数据迁移及日常主数据一致性维护等典型场景&#xff0c;尤其适合具备SQL基础的中级开发或实施工程师快速落地数据同步任务。压缩包内共15个…

作者头像 李华
网站建设 2026/10/27 2:24:27

科研写作目录管理工具与自动化技巧全解析

1. 科研写作中的目录管理痛点写论文最烦人的环节之一就是目录管理。我至今记得研究生时期&#xff0c;每次导师要求调整章节顺序时&#xff0c;手动更新目录页码的痛苦经历。那时Word的目录功能还不完善&#xff0c;经常出现页码错位、格式混乱的情况&#xff0c;改一次目录就得…

作者头像 李华