资讯动态

Oracle 11g补丁安装全流程:从包识别到SQL注册验证

发布时间:2026/10/27 2:29:07 来源:尧图企业网站定制
简介面向Oracle数据库DBA与运维人员的11.2.0.3.15补丁集更新包对应补丁号20760997适用于Linux x86-64平台并集成2015年7月CPU安全更新主要用于修复已知安全漏洞、性能与稳定性问题适合版本升级、安全加固或补丁应用前的资料核对。压缩包为zip格式体积约100.73MB文件总数显示为0、类型明细暂未提供描述中可见PatchSearch.xml补丁搜索配置与20760997补丁程序等内容实际以解压结果为准。已有291人浏览学习说明该补丁在旧版本环境维护中仍有一定参考需求。对仍运行11.2.0.3的旧系统该包可作为补丁归档、安全审计与升级前评估的参考材料读者可据此了解补丁的适用版本、平台范围与CPU包含关系并借助包内说明核对适用性、依赖关系与安装注意事项为数据库安全加固和日常维护提供依据。1. 补丁包先看清p20760997_112030_Linux-x86-64 对应哪个库版本上周有人丢给我一个包名字叫p20760997_112030_Linux-x86-64.zip说 oracle patch 打完了但库起不来。我打开一看opatch lspatches里确实有记录可startup之后报了一串组件失效。问题不在补丁本身在于打之前没人把文件名读明白112030不是批次号也不是平台码它是 11.2.0.3.0 压成六位的版本段Linux-x86-64才是平台。版本段对不上你手上的 Oracle Homeopatch 可能照样返回成功但 SQL 注册那一步会悄悄跳过最后留下一个“看着装好了、实际半残”的库。这套流程适合还在维护 11g 老库、需要按季度跟补丁的运维和 DBA新手照着能走通熟手可以对照检查自己漏了哪一步。2. 装前环境核对内核、属主与 OPatch 版本三件事补丁装挂的人十个里有八个不是倒在opatch apply而是倒在 apply 之前没核对。补丁包本身只是几个二进制和一堆 SQL它能不能落地取决于你的 Oracle Home 是不是它认识的那个 Home、OPatch 够不够新、文件系统还剩多少。这一章的三件事必须在解压之前做完做完之后你对“这个包能不能打”会有一个明确结论而不是打到一半靠猜。2.1 先确认这个 zip 是给哪个 Oracle Home 的第一步永远是以 oracle 用户登录而不是 root。Oracle 的补丁工具大量依赖$ORACLE_HOME和$ORACLE_SID用 root 跑出来的结果要么权限错乱要么读到另一个 Home。登录后先把环境变量和平台确认一遍再进库看版本两条路互相印证。# 必须是 oracle 用户且环境变量来自 oraenv 或 .bash_profile id echo ORACLE_HOME$ORACLE_HOME echo ORACLE_SID$ORACLE_SID uname -m # 期望输出 x86_64 uname -r # 记下内核版本部分老版本对内核有最低要求uname -m回x86_64才说明平台对得上如果回i686那是 32 位内核这个包直接用不了。$ORACLE_HOME的路径也要留意同一台机器上装了 11.2.0.3 和 12.1.0.2 两套 Home 是常事环境变量指错一次补丁就打到另一个库上去了。-- 以 sysdba 登录后执行确认库的版本与补丁文件名里的版本段一致 select banner from v$version; -- 如果是 RAC还要看这一行决定后面用不用 -local 逐节点打 select * from v$option where parameter Real Application Clusters;v$version第一行通常形如Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production这里的11.2.0.3.0就是文件名里112030展开的样子。对不上就别往下走了先去确认这个补丁包是不是拿错了。RAC 那一条如果返回TRUE说明后面每一步都要考虑节点opatch apply默认会尝试处理所有节点网络不通或对方节点没停库时会卡住稳妥做法是加-local一个节点一个节点来。2.2 OPatch 版本对不上后面全白搭OPatch 是补丁的搬运工它自己也有版本。补丁包解压后目录里有个README.txt或README.html开头几行会写OPatch version required一般要求不低于 11.2.0.3 分支的某个小版本。实操里我一般不抠那个最低值直接换到该分支能拿到的最新 OPatch省得在 prereq 阶段被拦一次。# 查当前 OPatch 版本输出形如 OPatch Version: 11.2.0.3.x $ORACLE_HOME/OPatch/opatch version # 换 OPatch 的标准动作先备份再解压新版本最后修属主 cd $ORACLE_HOME mv OPatch OPatch.bak.$(date %Y%m%d) unzip -q /u01/stage/p6880880_112000_Linux-x86-64.zip -d $ORACLE_HOME chown -R oracle:oinstall $ORACLE_HOME/OPatch chmod -R 750 $ORACLE_HOME/OPatch $ORACLE_HOME/OPatch/opatch version # 再确认一次mv而不是直接覆盖是为了留一条退回的路新 OPatch 万一和更早的补丁不兼容把OPatch.bak.*改回来就行。解压用-d $ORACLE_HOME是因为压缩包里自带OPatch这一层目录解到 Home 下正好落位。chown和chmod两步不能省root 解压出来的文件属主是 rootopatch 运行时写日志会直接报权限拒绝。注意12c 以后的 OPatch 不能拿去给 11g 的 Home 用反过来也一样跨大版本替换是另一个高频翻车点。2.3 空间、属主和一份能救命的备份补丁应用时会在$ORACLE_HOME/.patch_storage下留一份原始文件副本用于回滚所以空间需求不是补丁包大小而是它的三到五倍。我见过补丁包 300MB、应用时把 4GB 的 Home 撑爆的情况报错是No space left on device而且往往发生在 apply 中途比一开始就失败更麻烦。# 看 Home 所在文件系统和 /tmp 的余量建议 Home 至少留 3GB df -h $ORACLE_HOME df -h /tmp du -sh $ORACLE_HOME/.patch_storage 2/dev/null # 补丁前的库存快照出问题就靠它比对 $ORACLE_HOME/OPatch/opatch lsinventory -detail \ /u01/stage/lsinventory_before_$(date %Y%m%d).log-detail会把已打的补丁号、组件版本、Home 路径全列出来这份日志的价值在于事后比对装完之后哪些补丁号多了、哪些组件版本变了一眼能看出来。备份这件事我吃过亏所以现在是硬性动作库停在 mount 或直接shutdown immediate之后用 RMAN 做一次全备加归档备份或者至少把$ORACLE_HOME打包一份放别的盘。原因是opatch rollback只回退二进制不回退catbundle.sql或datapatch做过的数据字典变更SQL 那一层想退只能靠备份恢复。备份这一步花二十分钟能省掉后面一整天。3. 解包与冲突检查apply 之前把黑匣子打开补丁包解压出来不是一个文件而是一个带编号的目录里面etc/config存着补丁元数据files下是按 Oracle Home 相对路径摆好的二进制和 SQL。这个结构决定了你不能随便换个地方解压也不能用 root 解压完就直接打。这一章要做的事是把“这个补丁会改哪些文件、和现有补丁冲不冲突”提前问清楚而不是等 opatch 报错再回头查。3.1 上传、解压与属主修正暂存目录我习惯放在$ORACLE_BASE之外的独立挂载点比如/u01/stage避免补丁包把数据盘撑满。上传方式看环境能直连就scp中间隔着跳板机就用sftp分段传传完先核对大小和校验和再解压。# 建独立暂存目录避免和已有的补丁混淆 mkdir -p /u01/stage/p20760997 cd /u01/stage # 传完先校验md5 与提供方给出的一致再往下走 md5sum p20760997_112030_Linux-x86-64.zip # 解压到独立目录-q 静默、-d 指定落点 unzip -q p20760997_112030_Linux-x86-64.zip -d /u01/stage/p20760997 # 用 root 上传的话属主和权限要改回来 chown -R oracle:oinstall /u01/stage/p20760997 chmod -R 750 /u01/stage/p20760997 ls -l /u01/stage/p20760997unzip -d指定落点的好处是解压结果干净不会和暂存目录里其他补丁的编号目录混在一起。chmod 750是 Oracle 一贯的目录权限习惯组内可读可执行、其他用户无权限补丁目录沿用这个设置不会和 Home 的权限模型打架。解压后进到编号目录里扫一眼确认有etc、files、README.txt三样东西缺任何一样说明包不完整重新下载。cd /u01/stage/p20760997/20760997 ls -l cat README.txt | head -60 # 重点看 OPatch 要求和前置补丁说明README 里除了 OPatch 版本还会写“需要先打哪些前置补丁”。这一句经常被跳过结果就是 apply 时报一串冲突然后再回来翻文档。3.2 lsinventory 与 prereq 的两条基线opatch 提供了两组只读命令一组看现状一组看可行性。现状用lsinventory可行性用prereq两组都跑完你对这次操作的成功率心里就有数了。cd $ORACLE_HOME/OPatch # 现状已装补丁清单重点是最后那几行 patch 编号 ./opatch lsinventory # 可行性一检查补丁与当前 Home 的冲突 ./opatch prereq CheckConflictAgainstOHWithDetail -ph /u01/stage/p20760997/20760997 # 可行性二检查目标文件系统是否有足够空间 ./opatch prereq CheckSystemSpace -ph /u01/stage/p20760997/20760997 # 可行性三检查 Home 内是否有活动进程占用将被替换的文件 ./opatch prereq CheckActiveFilesAndExecutables -ph /u01/stage/p20760997/20760997-ph后面跟的是补丁编号目录的绝对路径不是 zip 文件。这三条prereq都是只读的跑多少次都不会改动 Home可以放心在业务库上执行。CheckActiveFilesAndExecutables这一条尤其值得单独跑库没停干净、监听还在、或者某个客户端进程占着libclntsh.so它都会直接指出来省掉 apply 到一半失败再回滚。输出里出现Prerequisite check xxx passed才算通过出现failed时后面会跟具体原因通常是“文件被占用”或“补丁冲突”按第 5 章的排查思路处理。3.3 冲突检测与回滚预案冲突分两种一种是补丁与已装补丁的二进制冲突另一种是同一个 Home 上已经存在更新版本的同类补丁。前者 opatch 会在CheckConflictAgainstOHWithDetail里报出来后者需要你自己看lsinventory的补丁列表判断——比如季度补丁是累积的打了 7 月的再回头打 4 月opatch 可能允许但把新版本降回旧版本属于自找麻烦。# 冲突检测的更细粒度版本会列出具体冲突文件 cd /u01/stage/p20760997/20760997 $ORACLE_HOME/OPatch/opatch prereq CheckConflictAgainstOHWithDetail -ph ./ # 万一要回退先记住这个命令的形状补丁号来自文件名的 p 后面那串 # $ORACLE_HOME/OPatch/opatch rollback -id 20760997-ph ./这种写法在已经cd进编号目录的前提下更省事.就代表当前目录。回滚命令我只建议在“补丁打完了才发现不兼容”时用而且前提是$ORACLE_HOME/.patch_storage里那份原始副本还在——有些人清空间时顺手把这个目录删了等于把回滚能力一起删了。真正完整的回滚预案是三层的第一层opatch rollback -id回退二进制第二层从 RMAN 备份恢复数据文件把 SQL 变更一并退掉第三层是应用侧的回退方案比如应用连接串或驱动版本要不要跟着调。三层里最容易被忽略的是第二层因为大家默认“补丁装坏了回滚一下就行”而实际上 SQL 注册那一步做完之后单靠 opatch 是退不干净的。注意.patch_storage目录不要手工清理里面的备份文件是 opatch 回滚的唯一依据。4. 应用补丁opatch apply 与 SQL 注册两步走前面的检查全绿才轮到真正动手。这个过程分两段中间隔着一次启库第一段停库、跑opatch apply改二进制第二段启库、跑 SQL 脚本改数据字典。很多人只做了第一段就以为完事第二段漏掉表现就是库能起来、补丁也显示装了但查询性能问题和已知 bug 一个没修——因为修复 SQL 根本没进字典。4.1 停库停监听的正确顺序停的顺序是先库后监听起的时候反过来。这个顺序不是仪式感是因为监听先停会让应用侧连接报错刷屏而库先停能让会话干净退出减少CheckActiveFilesAndExecutables失败的概率。export ORACLE_SIDorcl # 第一步干净关闭实例immediate 让会话回滚退出不要用 abort sqlplus -s / as sysdba EOF shutdown immediate; exit EOF # 第二步停监听 lsnrctl stop # 第三步确认没有残留进程占着 Home ps -ef | grep -E ora_pmon|tnslsnr | grep -v grepshutdown immediate会回滚未提交事务并做检查点正常库几十秒内完成如果卡住超过五分钟看 alert log 里是不是有大的回滚段在恢复这时候不要直接kill -9那会让下次启动多做一次实例恢复反而更慢。ps -ef那一步的输出应该是空的。如果还有ora_pmon_orcl在说明库没关干净如果有tnslsnr在说明监听没停。这两种情况下继续 apply多半会在CheckActiveFilesAndExecutables那一步被拦下。单机环境到这一步就够了。RAC 环境要把每个节点的实例和监听都停掉或者用-local逐节点滚动先停节点一打节点一起节点一再停节点二以此类推。滚动打补丁期间数据库整体可用但catbundle.sql只能在一个节点跑一次因为它改的是共享的数据字典。4.2 opatch apply 的参数取舍与输出解读opatch apply有几个参数值得记住用对了能省很多交互和等待。cd /u01/stage/p20760997/20760997 # 先干跑一次只看它会做什么不落盘 $ORACLE_HOME/OPatch/opatch apply -report # 正式应用-silent 免交互适合脚本化 $ORACLE_HOME/OPatch/opatch apply -silent # RAC 逐节点时加 -local只处理本机 # $ORACLE_HOME/OPatch/opatch apply -local -silent-report是很多人不知道的参数它会把补丁将要改动的文件、要执行的脚本全列出来但不实际修改任何东西。在正式 apply 之前干跑一遍等于把黑匣子提前打开看一眼。-silent则跳过“是否继续”的交互提示适合写进自动化脚本手工操作时如果不加opatch 会停下来等你输入y隔着屏幕容易误以为卡死。输出里要盯三处一是中间出现的ApplySession applying interim patch后面跟的补丁号确认是 20760997二是靠近结尾的OPatch succeeded.三是日志路径一般在$ORACLE_HOME/cfgtoollogs/opatch/下文件名带时间戳。如果结尾是OPatch failed with error code N别急着重跑先去日志里搜ERROR和failed错误码对应的原因在日志里都写清楚了。# 出错后第一时间看日志比反复重试有用 ls -lt $ORACLE_HOME/cfgtoollogs/opatch/ | head -5 grep -nE ERROR|failed|Exception $ORACLE_HOME/cfgtoollogs/opatch/opatch*.log | tail -304.3 SQL 注册catbundle 还是 datapatch二进制改完之后补丁里带的 SQL 修复还没生效必须通过脚本注册进数据字典。这一步按版本分岔11.2.0.3 用catbundle.sql12.1 及以后用datapatch。用错工具的结果是脚本报“找不到对象”或者干脆静默什么都不做。# 先启库SQL 注册需要实例处于 OPEN 状态 sqlplus -s / as sysdba EOF startup; exit EOF # 11.2.0.3 环境跑 catbundle参数固定为 psu apply cd $ORACLE_HOME/rdbms/admin sqlplus -s / as sysdba EOF ?/rdbms/admin/catbundle.sql psu apply exit EOFcatbundle.sql的两个参数不能省psu表示按 PSU 方式注册apply表示执行而不是只生成脚本。脚本运行期间会在当前目录生成catbundle_*.log这个日志必须留着后面验证和排错都靠它。运行时长看库的大小小库几分钟组件多的大库十几分钟很正常。# 12.1 及以后的环境改用 datapatch-verbose 输出每个补丁的注册细节 $ORACLE_HOME/OPatch/datapatch -verbosedatapatch是 12c 引入的工具它会自己扫描$ORACLE_HOME/sqlpatch下待注册的补丁逐个执行并记录到dba_registry_sqlpatch。-verbose建议一直加着输出里能看到每个补丁是SUCCESS还是FAILED比事后查表快。RAC 环境下这两个工具都只在一个节点执行一次不要在多个节点重复跑重复跑会报“补丁已应用”然后跳过虽然不致命但日志会乱。注意跑完 SQL 注册后建议再执行一次?/rdbms/admin/utlrp.sql重编译失效对象尤其是组件多的库。5. 常见问题排查五个真实翻车场景补丁操作的报错不多但每一条都很具体关键在于看日志的哪一段。下面五条是我这几年实际碰到过的按“现象、原因、解决”的顺序写遇到同类问题可以直接对号入座。5.1 应用阶段卡住的三个坑坑一CheckActiveFilesAndExecutables一直失败提示某个.so被占用。现象是 prereq 明确报了文件名但你用ps -ef看库已经停了。原因通常是监听没停干净或者应用服务器上的客户端进程还连着$ORACLE_HOME下的库文件也可能是同机另一个 Home 的进程误占。解决办法是用fuser或lsof精确定位占用者把对应进程停掉再重试RAC 环境还要确认另一个节点没在跑。# 定位到底是谁占着这个文件 fuser -v $ORACLE_HOME/lib/libclntsh.so lsof $ORACLE_HOME/lib/libclntsh.so 2/dev/null坑二opatch apply报 error code 73日志里是Patch conflict。现象是 apply 中途退出提示与已安装的某个补丁冲突日志会列出冲突的补丁号。原因是这个补丁包含的修复已经被更高版本的累积补丁覆盖或者两个补丁改的是同一批文件。解决思路是先判断哪个更新如果已装的是更新版本这个包就不该打如果确实需要得先回滚冲突的那个补丁或者换成合并后的补丁包。不要试图手工覆盖文件那会把 Home 的库存记录搞乱。坑三opatch apply跑到一半报No space left on device。现象是进度条卡在某个百分比然后失败日志里是写入失败。原因是 Home 所在文件系统的剩余空间不够.patch_storage留副本或者/tmp满了导致解压临时文件写不进去。解决是先清理能清的旧日志、旧 trace、旧补丁暂存扩不了空间就只能先回滚再换盘。回滚前确认.patch_storage里对应补丁的目录还在如果中途失败已经破坏了副本就得从备份恢复 Home。5.2 补丁装完库起不来的两个坑坑四库能启动但registry$history里查不到这次补丁的记录。现象是opatch lspatches显示补丁在列查询数据字典却没有任何 SQL 变更记录业务上感知到的 bug 也没修。原因就是第 4.3 节说的那一步漏了或者catbundle.sql跑的时候库不在 OPEN 状态导致中途报错退出。解决是确认库已 OPEN重新执行?/rdbms/admin/catbundle.sql psu apply然后看生成的日志里有没有ERROR如果提示“已应用”说明记录是有的只是查的表不对11.2.0.3 要查registry$history而不是dba_registry_sqlpatch。坑五启动后大量对象 INVALID或者报 ORA-04063。现象是startup完成后查询dba_objects发现失效对象数量异常应用连上来报存储过程有错误。原因是 SQL 注册过程中途失败留下半成品或者组件版本与补丁不匹配。解决顺序是先跑?/rdbms/admin/utlrp.sql重编译再查dba_registry看各组件状态是不是VALID如果重编译也修不好去$ORACLE_HOME/rdbms/log和$ORACLE_BASE/admin/$ORACLE_SID/下翻当时的日志定位失败点必要时用备份恢复后重打。-- 补丁后必查失效对象数量和组件状态 select count(*) from dba_objects where status INVALID; select comp_id, status, version from dba_registry order by comp_id;6. 装完怎么验证三条命令确认补丁真的落地了补丁打完opatch 说成功、脚本也说成功都不算数得自己查。验证分三层二进制层看补丁在不在SQL 层看字典记录有没有运行层看库起来之后有没有异常报错。三层都过这次操作才算闭环。# 第一层二进制层确认补丁号出现在已装列表里 $ORACLE_HOME/OPatch/opatch lspatches | grep -i 20760997 # 清单里看详情确认应用时间和描述 $ORACLE_HOME/OPatch/opatch lsinventory -detail | grep -A3 -i 20760997lspatches输出的是“补丁号 描述”的清单行数不多一眼能扫完。grep有输出说明二进制层没问题如果没有输出但 apply 明明成功了多半是环境变量指到了另一个 Home回头查$ORACLE_HOME。-- 第二层SQL 层。11.2.0.3 查 registry$history select action_time, action, namespace, version, id, comments from registry$history where action like %PSU% or action like %PATCH% order by action_time desc; -- 12.1 及以后改查 dba_registry_sqlpatch -- select patch_id, patch_type, action, status, action_time, description -- from dba_registry_sqlpatch order by action_time desc;registry$history里最近一条记录的action_time应该就是你跑catbundle.sql的时间comments里能看到补丁批次信息。如果时间对不上或者压根没记录说明 SQL 注册那一步没落库回第 4.3 节补跑。这一步是区分“装了”和“装好了”的关键我见过太多只查lspatches就收工的情况。第三层是运行层看 alert log 和失效对象。库启动之后tail一下 alert log搜ORA-和Errors in file正常情况下应该只有启动信息没有报错再跑一遍失效对象计数dba_objects里INVALID的数量应该和打补丁前持平明显变多就说明 SQL 注册有残留。# alert log 位置随版本略有差异常见路径如下 tail -200 $ORACLE_BASE/diag/rdbms/$ORACLE_SID/$ORACLE_SID/trace/alert_$ORACLE_SID.log \ | grep -nE ORA-|Errors in file最后养成一个习惯把这次操作的lsinventory前后快照、catbundle日志、备份位置记到一张变更单上下次再打补丁直接拿来做基线。补丁这件事最怕的不是装失败是装完了没人说得清装到哪一步、能不能退回去。从那以后我每次动补丁之前lsinventory -detail存档和 RMAN 备份这两步都强制走一遍多花二十分钟换的是出问题时能睡个整觉。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑