Oracle 11.2.0.4 PSU补丁安装全流程:OPatch与catbundle实战指南 简介面向 Oracle 数据库运维人员2024 年 7 月发布的 11.2.0.4 补丁集编号 p36575425适用于 Linux x86-64 平台用于修复 Oracle 数据库 11.2 系列在长期运行中暴露的安全漏洞与稳定性问题。压缩包约 536MB包含 2000 个文件主要类型为 o、so、xml、sql、jar、class 等其中库文件与可执行组件支撑补丁安装SQL 脚本和 XML 配置用于升级与校验。已有 944 人学习下载适合负责生产库日常维护的 DBA 参考。该 PSU 整合了自上一补丁以来的关键修复并附有 PatchSearch.xml 等元数据可协助核对补丁信息、评估变更影响。由于 Oracle 11.2.0.4 属于长期支持版本定期应用此类季度补丁是保障数据库安全合规、降低运行风险的重要措施。1. 季度补丁集 p36575425为什么 11.2.0.4 的 PSU 值得花一个维护窗口还在维护 Oracle 11.2.0.4 单机或 RAC 环境的团队对标题里的生产补丁集 p36575425发布标识 240717Linux x86-64 平台应该不陌生。PSU 是季度安全修复与稳定性修复的打包产物一次替换几十个二进制文件、几十个 Bug 修复比逐个打 one-off patch 省心得多。这篇文章面向还在跑 11.2.0.4 的数据库管理员目标不是背下 opatch 命令而是把「下载核对 → 备份 → 冲突检查 → apply → SQL 变更 → 验证回滚」这条完整链路走通。很多人不敢打 PSU总把补丁安装当成玄学怕打坏、怕回不去。实际 opatch 自带失败自动回滚机制真正让维护窗口翻车的往往是准备不足比如没备份 ORACLE_HOME、没做冲突检查、或者打完二进制忘了跑 SQL 脚本。下面我按自己的维护习惯把整套流程从准备到收尾完整写一遍。2. 动手前把三件事做扎实备份、opatch 升级、补丁目录核对2.1 备份 ORACLE_HOME让后悔药在 apply 之前就生效PSU 替换的是 ORACLE_HOME 下的二进制文件、脚本和部分配置文件数据文件原则上不碰。但生产环境没有后悔药一旦 apply 到一半主机断电或磁盘写坏干净的 home 备份就是唯一退路。我一般会在补丁窗口开始前一小时做一次全量打包而不是在 apply 前几分钟才动手。mkdir -p /backup/psu_20240725 tar -czf /backup/psu_20240725/oracle_home_$(date %Y%m%d_%H%M).tar.gz \ --exclude$ORACLE_HOME/rdbms/dbs \ $ORACLE_HOME这里排除rdbms/dbs是因为里面放着参数文件、密码文件等运行时文件它们不该被旧版本覆盖如果你平时习惯把 spfile 放在 $ORACLE_HOME/dbs 下排查问题时反而需要保留这个排除项按实际环境取舍拿不准就整个打包。归档完成后顺手做一次校验tar -tzf /backup/psu_20240725/oracle_home_*.tar.gz | tail -5 ls -lh /backup/psu_20240725/oracle_home_*.tar.gz逻辑说明tar 备份必须确认归档首尾文件都在不能只看打包命令无报错就以为成功。补丁包本身是 zip解压过程要临时空间tar 备份同样要吃磁盘空间所以备份前先确认/backup目录所在文件系统余量。$ORACLE_HOME在 shell 里必须能展开用echo $ORACLE_HOME验证一次很多环境变量没 export 导致备份了空目录这种坑我踩过不止一次。2.2 先升级 opatch旧版工具装不进新补丁11.2.0.4 默认自带的 OPatch 版本很老面对 2024 年的季度 PSU 经常直接报不支持。补丁包里不会附带新版 opatch需要单独从官方支持站点获取。先检查当前版本$ORACLE_HOME/OPatch/opatch version期望输出类似OPatch Version: 11.2.0.4.x。如果版本是 11.2.0.0.0 或明显低于补丁要求先备份旧 OPatch 目录再覆盖安装新版mv $ORACLE_HOME/OPatch $ORACLE_HOME/OPatch.bak_20240725 unzip -q p6880880_112000_Linux-x86-64.zip -d $ORACLE_HOME参数说明p6880880是 OPatch 工具的通用补丁号它不区分数据库版本只区分平台所以解压回$ORACLE_HOME即可。覆盖后马上复验版本号别等 apply 时才暴露问题。旧的OPatch.bak目录别急着删等整个 PSU 窗口结束、确认无回滚需求再清理。这里有个常被忽略的细节OPatch 升级后$ORACLE_HOME/OPatch/opatch的权限和属主必须保持 oracle:oinstall工具解压默认保留 zip 内权限如果之前目录权限被改过解压后要chown -R oracle:oinstall $ORACLE_HOME/OPatch否则后续所有 opatch 命令都会以权限报错开始。2.3 核对补丁号、平台和校验值货不对板是补丁安装的第一道坑标题里的p36575425-112040-Linux-x86-64已经写明了补丁号、版本和平台但下载过程经常出岔子。解压前先做 MD5 校验以官方发布页给出的校验值为准md5sum p36575425_112040_Linux-x86-64.zip解压后进入补丁目录确认结构完整应有etc/、files/、Install/等目录。用cat etc/config/actions看一眼平台信息或者直接看README开头几行。重点检查两点一是补丁目录名与-phBaseDir指向一致二是解压后的文件属主是否为 oracle。很多人用 root 解压导致补丁文件属主变成 rootopatch apply 时权限校验直接失败。压一个常见情况实际生产环境下载的补丁包可能是从某个内部共享服务器拷贝的拷贝过程丢文件或损坏是常事。解压后检查files/目录里文件数量是否和发布说明一致或者跑一次find files -type f | wc -l做个粗略校验。这一步不花多少时间但能避免维护窗口进行到一半才发现补丁包不完整。3. 冲突检查与空间校验让 opatch 在动手前替你踩一半的坑3.1 用 CheckConflictAgainstOHWithDetail 检查补丁冲突opatch 的 prereq 子命令能在不动二进制的前提下检查补丁与当前 ORACLE_HOME 的兼容性。我每次都会做两层检查先是通用的 conflict check再是 detail 级别。命令如下cd $ORACLE_HOME/OPatch ./opatch prereq CheckConflictAgainstOHWithDetail \ -phBaseDir /tmp/p36575425 \ -invPtrLoc /etc/oraInst.loc参数说明-phBaseDir指向解压后的补丁目录不能用 zip 文件路径-invPtrLoc指定 oraInst.loc 的位置很多机器上它在/var/opt/oracle/oraInst.loc不确定就cat /etc/oraInst.loc先确认。prereq只检查不落盘输出末尾如果出现Prereq checkConflictAgainstOHWithDetail passed.说明没有冲突可以继续。如果出现Conflict列表直接进 3.2 处理。注意这个检查只针对「当前 ORACLE_HOME 已安装的补丁」与「新补丁」之间的冲突不检查数据库实例级兼容性所以它不能替代后续的启动验证。它最大的价值是在 apply 之前把「打不上 / 必须回滚旧补丁」这类问题提前暴露出来避免维护窗口白开。3.2 冲突时先处理存量补丁再谈新 PSU检查报告里一旦出现冲突最常见的场景是这个 ORACLE_HOME 里先前打过 one-off patch而新 PSU 已经包含了该 one-off 修复于是 opatch 认为两份变更针对同一对象拒绝继续。这时候不要硬闯先看冲突明细./opatch lsinventorylsinventory 列出当前已安装补丁列表把冲突的 one-off 补丁号找出来。处理策略很直接先用opatch rollback -id 旧补丁号撤掉 one-off再重新跑 CheckConflict。如果 one-off 的修复确实已经进入新 PSU回滚后不需要再补打如果 PSU 发布说明里没包含它就需要在 PSU 应用完成后重新以 one-off 方式叠加。还有一个容易误判的场景多个 PSU 之间的冲突。严格来说 PSU 是累积包新版 PSU 应当包含旧版 PSU 的全部内容但 opatch 检测到两个 PSU 同时存在时同样会拒。常规操作是先 rollback 旧 PSU 再 apply 新 PSU不要试图同时保留两份。这里提前做 lsinventory 的价值就出来了它让你在窗口前就知道要预留多少回滚时间。3.3 dryRun 与空间检查别让 ORACLE_HOME 在应用中途报磁盘满apply 之前的第二道保险是 dry run。它模拟整个应用过程但不实际替换文件常见命令是./opatch apply -phBaseDir /tmp/p36575425 -dryRun执行完看输出里的Dry Run successful字样。dryRun 会占用短暂时间并且会访问 oraInventory所以不要在业务高峰期跑。它虽然做完整流程预演但不会检测所有文件拷贝目标的空间余量因此还要手工查磁盘df -h $ORACLE_HOME du -sh /tmp/p36575425参数说明df -h看的是 ORACLE_HOME 所在文件系统剩余空间du -sh看补丁包大小。只装一个 PSU 时空间风险不大但如果同一窗口还要叠加 opatch 升级、补丁解压、tar 备份三者峰值都在同一文件系统上空间就可能吃紧。我给自己定的经验线ORACLE_HOME 所在分区剩余空间要大于补丁目录大小两倍以上否则先扩容或清理旧日志再开窗口。空间检查属于那种“不做没事、做了才放心”的步骤。真在 apply 中途写满磁盘opatch 会尝试自动回滚但回滚本身也需要空间两个动作同时挤占磁盘结局往往是被迫手工修复 inventory。提前 5 分钟跑一趟 df能省掉后面 5 小时。4. 核心维护窗口停库、apply、catbundle 的先后顺序4.1 停实例和监听把文件替换环境攥在自己手里opatch apply 会直接覆盖 ORACLE_HOME 下的运行文件。只要数据库实例还开着进程就会占用或缓存旧二进制替换出去轻则起库报错重则文件被破坏。所以标准顺序是通知业务方后关闭实例再停监听。sqlplus / as sysdba SQL shutdown immediate; SQL exit lsnrctl stop LISTENERshutdown immediate 会等待当前事务结束业务高峰期可能卡住很久。如果设置了维护窗最好在窗口开始前 15 分钟就发 shutdown 命令给事务收尾留余量。结束后确认进程真的没了ps -ef | grep pmon | grep -v grep这条命令应该没有任何输出。如果有说明实例还在强制 kill 前先确认是否卡在 checkpoint 等合法阶段不要一上来就 kill -9。监听同理ps -ef | grep tnslsnr | grep -v grep应为空。这里要把一个顺序说清楚先实例后监听不要颠倒。实例关闭时还要通过监听处理的连接早停监听会导致 shutdown immediate 期间新连接进不来反而拖慢收尾。RAC 环境则要逐节点处理不能用同一 ORACLE_HOME 直接对两个节点同时 apply通常的做法是先在第一个节点停掉该节点的 ASM 和 DB 资源完成后再切到下一个节点。4.2 opatch apply 的执行参数与日志解读环境干净、备份在手、冲突检查通过后正式应用命令其实很简短cd $ORACLE_HOME/OPatch ./opatch apply \ -phBaseDir /tmp/p36575425 \ -invPtrLoc /etc/oraInst.loc参数说明-phBaseDir后跟补丁解压目录-invPtrLoc是 oraInst.loc 的绝对路径。如果机器上只装了一套数据库-invPtrLoc有时可以省略但多套环境共存时省略会导致 opatch 找错 inventory后果是补丁打到别的 ORACLE_HOME 上所以这个参数我从来都是显式写。apply 过程中屏幕会滚动大量输出最后一段通常是补丁清单和耗时统计看到OPatch succeeded即成功。执行耗时一般在 515 分钟取决于机器性能和补丁体积。中途断掉不要慌opatch 会自动回滚但回滚结束后也要看日志确认是否真回到了应用前状态。日志位置固定ls -lt $ORACLE_HOME/cfgtoollogs/opatch/ | head -3最新的那个 opatch_*.log 就是对应当前会话的日志。用这几个关键字定位结果grep -E OPatch succeeded|Return Code 0|OPatch failed|WARNING \ $ORACLE_HOME/cfgtoollogs/opatch/opatch_*.log | tail -10逻辑说明OPatch succeeded与Return Code 0缺一不可。只出现 succeeded 而 Return Code 非 0 是异常状态需要继续排查出现 FAILED 则说明自动回滚已触发下一步不是重试 apply而是看日志定位根因。apply 成功后先别急着启动实例下面还有 SQL 变更要做。4.3 启动实例并执行 catbundle.sql 完成数据字典升级二进制替换完之后数据字典版本还停留在旧版。11.2.0.4 的 PSU SQL 部分不是 12c 之后的 datapatch 机制而是用 catbundle.sql 应用。这一步最容易被新手跳过跳过的后果就是数据库能启动但行为异常甚至部分新特性直接不可用。标准做法sqlplus / as sysdba SQL startup upgrade; SQL $ORACLE_HOME/rdbms/admin/catbundle.sql psu applystartup upgrade以升级模式打开数据库允许数据字典版本变更catbundle.sql后面的psu apply两个参数告诉脚本要应用 PSU 补丁集。脚本执行时间通常 1030 分钟执行完后退出 SQL*Plus查看生成的日志ls -lt $ORACLE_HOME/rdbms/admin/catbundle_*.log | head -3 grep -E ORA-|Error $ORACLE_HOME/rdbms/admin/catbundle_PSU_*.log | tail -20日志文件命名规则是catbundle_PSU_SID_时间戳.log搜到 ORA- 错误要逐条分析常见的 ORA-00942 等往往是因为脚本在非 upgrade 模式下跑导致缺对象。确认无误后关库恢复正常模式再启动sqlplus / as sysdba SQL shutdown immediate; SQL startup;最后把监听拉起来。顺序上先实例后监听和 4.1 的逻辑对应。至此二进制和数据库字典两边都到位了。5. PSU 安装避坑记录五个翻车场景与排查路径5.1 opatch 报权限不足或 inventory 被锁现象执行opatch apply时提示Unable to lock inventory或者直接报Permission denied甚至部分 OUI-10060 类错误。原因最常见的是 oracle 用户对$ORACLE_HOME/oraInventory没有写权限或者这个目录被 root 解压的补丁文件污染了属主。还有一种闹心情况另一个 opatch 进程正在跑inventory 锁还没释放。解决先查ls -ld $ORACLE_HOME/oraInventory确认属主chown -R oracle:oinstall修正再看ps -ef | grep opatch | grep -v grep如果有残留进程等它结束再重试。还把$ORACLE_HOME/.patch_storage或者.inventory_backup目录权限检查一遍这些目录权限错了同样会锁死 inventory。5.2 apply 提示已有补丁冲突但事前检查没发现现象预检查时 CheckConflict 通过正式 apply 却报conflicts with patches already applied。原因预检查时-invPtrLoc指向了错误的 oraInst.loc检查的是另一个 ORACLE_HOME 的 inventory或者检查之后有人同期打了一个 one-off patch动作串了。解决先跑opatch lsinventory确认真实环境里到底有哪些补丁再比对冲突列表。确认当前 home 里有存量 one-off 时按 3.2 的方式先 rollback 再重试。排查中要特别留意输出里的Home路径前置检查的 Home 和 apply 的 Home 不一致是这类问题的根源。5.3 二进制替换成功实例启动报内部错误现象apply 正常结束catbundle 跑完了但启动时报 ORA-600 类内部错误或者出现在特定功能测试时异常。原因八成是数据字典和应用版本不匹配catbundle 没执行成功或日志里藏了 ORA-00942 没注意剩下一成是旧 one-off 补丁的修复没有被新 PSU 包含产生行为回退。解决先回滚补丁恢复到 apply 前恢复业务后慢慢分析。回滚前把$ORACLE_HOME/rdbms/admin/catbundle_*.log完整归档这些都是定位依据。紧急恢复时用 2.1 的 tar 备份重建 home 更快所以备份这一步绝不能省。如果猫定后确认是某个 one-off 修复丢失在 PSU 上重新叠加该 one-off 即可但一定要先跑 prereq 验证兼容性。5.4 单机环境用 opatch auto 打补丁跑到一半失败现象有人图省事在单实例环境用opatch auto代替opatch apply结果报错并只完成了一半流程。opatch auto 是 RAC 场景设计给 GI_HOME 和 DB_HOME 两套 home 滚动打补丁的工具单机没有集群资源它会尝试扫描 ASM 和集群组件环境不满足就直接失败。解决单实例老老实实用opatch apply -phBaseDir。RAC 环境也建议逐节点手动执行先关一个节点的实例apply 完验证正常再切下一个节点整体风险比 opatch auto 全自动滚动更可控。5.5 补丁后无效对象暴增UTLRP 也清不干净现象应用完成后查dba_objects大量INVALID状态对象跑完 utlrp.sql 后数量只降了一点点。原因一部分是数据字典版本升级后 SYS 和 SYSTEM 对象需要重编译utlrp 能处理另一部分是业务侧对象本来就依赖缺失或引用第三方库不存在和补丁无关还有一类是 catbundle 执行时处于非 upgrade 模式导致脚本部分失败。解决先按属主分组看无效对象来源select owner, object_type, count(*) from dba_objects where status INVALID group by owner, object_type order by 3 desc;SYS 和 SYSTEM 下的对象优先跑 utlrp 重编译业务 schema 下的大量失效先查依赖对象是否还存在不要一股脑归咎补丁。确认是 catbundle 失败导致的则回到 4.3 重跑一次 SQL 应用步骤。6. 验证闭合与回滚后悔药把维护窗口安全收尾6.1 用 lsinventory 与版本号确认补丁生效catbundle 跑完、实例正常启动后第一个验证命令就是确认补丁在 inventory 里注册成功$ORACLE_HOME/OPatch/opatch lsinventory | grep -i 36575425输出应包含补丁编号、应用时间、平台信息。同时跑一把opatch lsinventory -detail确认补丁应用到正确的 ORACLE_HOME 路径防止 5.2 里那种打错 home 的情况。补丁生效后sqlplus -v看到的版本号通常不会变仍是 11.2.0.4.0因此版本号不变不要误判为失败PSU 不会修改基础版本号它只替换二进制内容和数据字典版本。6.2 重编译无效对象与回归启动11.2.0.4 打完 PSU 后有一批视图、包需要重编译标准动作是调 UTLRP 脚本sqlplus / as sysdba SQL $ORACLE_HOME/rdbms/admin/utlrp.sql脚本会自动并行重编译失效对象结束时会印出重编译计数。完成后重新查一次无效对象和 5.5 的查询一致。剩几个 SYS 下的已知对象不消失是正常的比如某些账号相关的对象本来就是失效状态和补丁无关。之后按业务模块做一轮开关库、连接、基本 DML 的回归测试特别是之前报过 Bug 的场景重点验证。6.3 回滚操作与下一次升级前的快照习惯如果回归发现问题需要回滚命令本身并不复杂$ORACLE_HOME/OPatch/opatch rollback -id 36575425但回滚前必须再次关闭实例和监听回滚后还要重新跑一遍数据字典回滚脚本不是滚完二进制就结束了。更重要的是回滚意味着这个维护窗口要做的事没完成下一次窗口要重新评估补丁版本而不是简单重试同一操作。我自己的习惯每打完一个 PSU 就把 ORACLE_HOME 打包一份留存并给$ORACLE_HOME/cfgtoollogs/opatch/和catbundle_*.log做一次快照下一次升级时直接对照这些基线来判断问题是不是新补丁引入的。这些年打下来最深的教训是补丁安装本身很少失败失败几乎都出在没给环境留好后路。一旦开始打补丁就把自己当成在改手术备份、检查、逐步验证每一环都不能省。有一次在预生产环境因为忘带-invPtrLoc把补丁打到了同机另一套测试库的 home 上从此每次执行前强制先跑一遍opatch lsinventory确认路径。希望这些经验能帮到你少走几趟弯路。本文还有配套的精品资源点击获取