Oracle 11.2.0.4 PSU补丁p36575425安装实战与避坑指南
简介面向 Linux x86-64 平台的 Oracle Database 11.2.0.4 PSU 补丁集官方编号 p36575425对应 2024 年 7 月发布的季度补丁更新。该补丁集适用于 64 位 Linux 下的 Oracle 11.2.0.4 长期支持版本是 DBA 进行补丁升级、安全加固与故障修复的重要输入由于 PSU 按季度累积发布它汇总了自上一补丁包以来的关键安全更新与缺陷修复适合负责生产库变更与合规审计的团队使用。压缩包体积约 536MB内含约 2000 个文件其中目标文件(.o)与动态库(.so)用于替换数据库二进制组件SQL 脚本多用于数据字典与系统视图升级XML 文件记录补丁配置与清单信息另有 JAR 包、静态库等辅助文件整体可覆盖补丁安装、验证与回滚场景。目前已有 944 人学习/下载。使用该补丁集可将 Oracle 11.2.0.4 环境升级至 11.2.0.4.240717 补丁级别及时获得官方安全加固与性能优化降低已知漏洞引发的生产风险并为后续向更高版本迁移提供稳定中间状态。1. Oracle 11.2.0.4 补丁集 PSU p36575425先搞懂季度补丁机制再动手很多环境跑着 11.2.0.4平时不敢动出了漏洞又必须打补丁。p36575425-112040-Linux-x86-64 是 2024 年 7 月发布的 PSU 季度补丁集日期 240717它把安全修复和稳定性修复打成一个大补丁一次 apply 就能把 Oracle Home 拉到一个统一基线。这篇笔记直接讲怎么把它落到生产库装前检查什么、opatch 参数怎么设、SQL 脚本什么时候跑以及几个我实际踩过的坑。适合还在维护 11.2.0.4 的 DBA也适合用模拟项目X做 Oracle 实验的开发者。2. PSU 与 DBBP 的选型边界动手前先看清这三件事在对 p36575425 动手之前先明确一个底层问题你手上到底该打 PSU 还是 DBBP。很多 DBA 在 11.2.0.4 上分不清这两类补丁选错了策略后面维护成本完全不同。这一章把概念、选型和安装前的检查工作一次说透。2.1 PSU 和 DBBP 怎么选稳定优先还是特性优先PSUPatch Set Update和 DBBPDatabase Bundle Patch在 11.2.0.4 上经常被拿来对比。PSU 是季度发布的补丁包包含的高风险修复项相对收敛重点是安全漏洞和已经被广泛验证过的稳定性问题DBBP 则更像一个特性集除了修复之外还会把一些新行为带进来。我用一个实际例子说明差别。某生产环境经历了一次业务高峰期的性能退化排查下来是某个内部包的行为被 DBBP 里的新代码改动影响到了而 PSU 通常不会引入这种级别的行为变化。从那以后凡是核心交易库我只推荐 PSU实验环境才考虑 DBBP。对比项PSUDBBP发布节奏季度季度风险等级相对收敛相对偏高包含内容安全修复、稳定性修复安全修复、新行为、部分增强适用场景生产核心库实验性或开发环境回滚难度看字典脚本执行情况字典脚本变更更多回滚更艰难p36575425 从补丁命名和发布周期来看属于 PSU适合直接用于生产库的季度例行维护。它在补丁集内部会带database子目录包含文件头、修复清单和 relink 脚本这些都是后续安装时 opatch 会去读取的内容。2.2 装前必做的三项检查OPatch 版本、当前基线、磁盘空间很多安装失败不是因为补丁本身有问题而是环境没准备好。我每次动手前都会强制走一遍下面的检查流程耗时不到五分钟能省掉后面至少一小时排错时间。su - oracle export ORACLE_HOME/u01/app/oracle/product/11.2.0/dbhome_1 export ORACLE_SIDORCL export PATH$ORACLE_HOME/bin:$ORACLE_HOME/OPatch:$PATH # 检查 OPatch 工具版本 $ORACLE_HOME/OPatch/opatch version # 检查当前已安装补丁清单 $ORACLE_HOME/OPatch/opatch lsinventory # 检查安装分区和临时目录可用空间 df -h /u01 /tmp这段脚本里的关键点是环境变量。ORACLE_HOME必须指向实际运行的 Oracle 主目录而不是 ORACLE_BASE路径写错会导致 opatch 读错 inventory甚至把补丁装到另一个无关目录里。ORACLE_SID用于后续连接数据库补丁安装本身不强制要求实例状态但后面的字典脚本必须要用到。opatch version的输出结果要重点看版本号。11.2.0.4 环境中 OPatch 版本低于最低要求时opatch apply 会在前置检查阶段直接拒绝执行这是最常见的第一道门槛。我一般会拿着版本号去核对补丁包自带的 README避免看走眼。opatch lsinventory的作用是列出当前 Home 里所有已安装的补丁。这个输出信息量很大我主要看两件事当前基线是什么、是否已经有和 p36575425 冲突或重复的补丁。如果之前手动打过某个单补丁而这个补丁已经被包含在本次 PSU 里那么 apply 时就会报冲突需要先卸载旧补丁。磁盘空间检查不能只盯一个目录。11.2.0.4 的 PSU 在 apply 过程中会在$ORACLE_HOME里生成大量的备份文件和临时文件同时 opatch 日志也会占用$ORACLE_HOME/cfgtoollogs的空间。我建议$ORACLE_HOME所在分区至少预留补丁包体积的三倍空间/tmp也要留足解压空间。2.3 看懂补丁包目录结构到底哪个目录是真正的 PSU下载下来的 zip 包名是p36575425_112040_Linux-x86-64.zip解压之后很多人容易搞混哪个目录才是 opatch 要用的补丁路径这里很容易埋雷。# 解压到统一目录 mkdir -p /u01/psu cd /u01/psu unzip p36575425_112040_Linux-x86-64.zip # 修正属主避免 oracle 用户读取文件权限不足 chown -R oracle:oinstall /u01/psu # 查看补丁包主目录结构 ls -l /u01/psu/36575425 ls -l /u01/psu/36575425/database补丁包解压后通常会出现一个以补丁号命名的目录36575425它下面还会再分database、opatch等子目录。database目录才是 PSU 的真正内容它内部包含files、etc等目录opatch 的-phBaseDir参数必须指向这个内层database目录而不是外层36575425。我见过有人在命令行里把-phBaseDir /u01/psu/36575425写进去结果 opatch 报错说找不到补丁 action 文件查了半天才发现是路径少了一层。补丁结构在每次发布时可能略有调整最保险的办法是解压后看 README它会明确写出本次-phBaseDir应该指向哪里。另外一个小细节补丁包里的opatch子目录存放的是与本次补丁匹配的 OPatch 工具更新包不是补丁本身。如果你的opatch version检查不过关可以用这个子目录里的工具去更新 OPatch更新方式和 p6880880 独立更新包一样但省去了一次下载步骤。3. 安装 PSU 的完整流程从停库到 SQL 脚本的四个阶段安装 PSU 不是解压后直接 apply 那么简单。整个流程应该分成准备停库、冲突检查、二进制补丁应用、字典脚本应用四个阶段。每一个阶段都有自己的验收点跳过任何一个都会在后续运行期暴露出问题。3.1 准备与停库留好后路的两个备份动作补丁安装前最重要的是把后悔药准备好。Oracle 11.2.0.4 的 PSU 虽然支持 opatch rollback但前提是 apply 过程没有破坏关键文件而且字典脚本尚未执行。更多时候人们发现补丁装完有问题时字典脚本早已跑完这时候回滚就不是一条命令能解决的问题。# 记录补丁前状态方便后续对比 $ORACLE_HOME/OPatch/opatch lsinventory /tmp/lsinv_before_$(date %Y%m%d).txt # 使用 RMAN 备份数据库推荐至少备份控制文件与系统表空间 rman target / EOF backup current controlfile; backup tablespace system; EOF # 小型实验环境才会做整目录压缩备份生产库不建议 # tar -czf /tmp/oracle_home_backup_$(date %Y%m%d).tar.gz $ORACLE_HOME # 停止监听和数据库实例 lsnrctl stop sqlplus / as sysdba EOF shutdown immediate; EOF第一个备份动作是记录补丁基线把安装前的 opatch 清单存成文件。这个文件在安装后用来做 diff 对比能快速判断新补丁是否出现在 Inventory 里以及在回滚时核对原状态。第二个备份动作建议用 RMAN 备份控制文件和系统表空间。PSU 的字典脚本涉及sys下的核心对象如果字典脚本执行到一半失败单纯重跑并不一定能恢复干净。有控制文件和系统表空间的备份在手至少可以把实例恢复到执行字典脚本之前的状态。生产环境不建议做tar -czf $ORACLE_HOME这种整目录备份Oracle Home 通常好几个 GB打包耗时很长而且在数据库运行状态下打包会造成文件不一致压缩包根本不可用。这个操作我只在虚拟机里基于模拟项目X做实验时才会用。停库阶段要注意shutdown immediate的等待时间。如果现场有长时间未提交的事务这个命令可能持续几分钟不要强行shutdown abort否则实例不一致会导致后续 relink 和字典脚本遇到意外的 ORA- 错误。3.2 冲突检查用 prereq 把矛盾提前暴露出来补丁装到一半才发现冲突是最被动的。opatch 提供了预检查机制可以在正式 apply 前把冲突、依赖、空间问题全部暴露出来。cd $ORACLE_HOME/OPatch ./opatch prereq CheckConflictAgainstOHWithDetail -phBaseDir /u01/psu/36575425/databaseCheckConflictAgainstOHWithDetail是 11.2.0.4 里常用的冲突检查命令它会将目标补丁与当前 Oracle Home 中已安装的补丁做比对。这里有个容易忽略的细节-phBaseDir必须指向补丁包内部的database目录这是一个高频踩坑点。如果输出结果里有Conflict字样说明补丁包与已安装的某个补丁存在文件级或目录级冲突直接 apply 大概率会失败。处理方式要分情况讨论如果旧补丁完全是本次 PSU 的组成部分可以先把旧补丁回滚掉如果旧补丁是另一个独立修复需要先确认它与 PSU 的兼容性再继续。还有一个常见做法是运行opatch prereq CheckSystemSpace -phBaseDir /u01/psu/36575425/database专门验证磁盘空间是否足够。我在实际支持中遇到过df显示空间充足但 inode 耗尽导致 apply 失败的情况所以这个检查也不应该省略。3.3 执行 opatch apply中途这三个节点最值得盯冲突检查通过后正式进入 apply 阶段。我习惯用 silent 模式把日志交给文件系统去记录同时避免交互确认造成的人工等待。cd $ORACLE_HOME/OPatch ./opatch apply -silent -phBaseDir /u01/psu/36575425/database echo apply exit code: $?-silent参数让 opatch 以非交互方式运行。命令执行完毕后立即检查退出码0 表示成功非 0 需要立刻去看日志。opatch 的日志默认写在$ORACLE_HOME/cfgtoollogs/opatch目录下文件名格式类似opatch_2024-07-17_09-30-00.log里面会记录 apply 的每个阶段。需要盯的第一个节点是 apply 前期的文件解压和备份阶段。opatch 会先把被覆盖文件的原始版本备份到$ORACLE_HOME/.opatch或临时目录这一步磁盘 I/O 压力较大不要因为看起来卡住就中断进程。第二个节点是 relink。Oracle 11.2.0.4 的 PSU 在 apply 过程中会自动重新链接所有可执行文件日志里会出现大量的make输出。如果 relink 阶段失败日志末尾通常会带上具体的链接错误信息比如缺少某个系统库或编译器。这时候数据库还不能启动需要修复系统环境后重新执行 apply。第三个节点是 apply 完成的确认信息。silent 模式下最后的输出会显示类似OPatch succeeded的说明同时退出码为 0。如果退出码为 0 但日志里有 WARNING也要引起注意特别是关于relink或backup的警告我先解决掉再往下走。3.4 启动数据库与 SQL 脚本catbundle 才是补丁真正落地的环节二进制补丁应用完成后PSU 只完成了文件层面的更新。Oracle 数据字典里还有很多内容需要同步这一步通过catbundle.sql完成漏掉这个环节等于补丁白打。sqlplus / as sysdba EOF startup; EOF cd $ORACLE_HOME/rdbms/admin sqlplus / as sysdba EOF ?/rdbms/admin/catbundle.sql psu apply EOFcatbundle.sql psu apply是 11.2.0.4 里应用 PSU 字典更新的标准写法它会把补丁对应的 SQL 变更写入数据字典并更新registry$history表。执行这个脚本时实例必须处于 open 状态所以我先执行startup。执行时间通常从几分钟到半小时不等取决于数据库大小和系统负载。日志会输出到$ORACLE_HOME/cfgtoollogs/catbundle目录下文件名类似catbundle_PSU_ORCL.log执行结束后我要检查其中是否有ORA-开头的错误。这里有个容易翻车的细节catbundle.sql需要在$ORACLE_HOME/rdbms/admin目录下通过?/rdbms/admin/...的路径调用不要直接写相对路径。我之前在一个测试库上从/tmp路径直接执行脚本找不到依赖文件报了一堆ORA-00942最后重新从正确目录跑才通过。4. 补丁安装避坑与排查五个典型翻车现场补丁安装说难不难说简单也不简单。这一章整理我在实际维护和生产支持中遇到的五类高频问题全部按「现象 → 原因 → 解决」的方式记录每条都是花过时间换来的经验。4.1 现象一OPatch 报「版本低于最低要求」现象执行opatch apply后立刻退出日志里提示 OPatch 版本过低要求至少某个具体版本号当前版本不满足。有人换用-silent也一样失败看起来像玄学。原因11.2.0.4 的 PSU 对 OPatch 有硬性版本要求。很多老环境自安装后从没升级过 OPatch版本停留在几年前自然不满足新补丁的校验逻辑。opatch 的版本检查和数据库版本没有直接关系只和 OPatch 工具自身有关。解决用补丁包自带的opatch子目录或单独下载的 p6880880 更新 OPatch。步骤是先备份现有$ORACLE_HOME/OPatch目录再覆盖更新最后重新执行opatch version确认。此后每次 apply 前我都先看版本不再等报错。4.2 现象二冲突检查提示「已有补丁需要移除」现象opatch prereq CheckConflictAgainstOHWithDetail输出大量 Conflict 信息明确指出某几个补丁与 p36575425 冲突拒绝继续 apply。原因环境中曾经手动安装过一些单补丁而这些修复已经被新的 PSU 包含。opatch 不允许同时存在两个作用域重叠的补丁所以必须把旧补丁先去掉。解决逐个执行opatch rollback -id 旧补丁号待所有冲突项清理完毕后重新做冲突检查直到输出干净为止。如果旧补丁已经进入数据库字典回滚时也要同步跑对应字典脚本否则可能出现二进制版本和字典版本不一致的隐患。4.3 现象三apply 到 relink 阶段失败数据库起不来现象opatch apply 在 relink 阶段长时间停留随后日志中出现make错误指向某个共享库无法链接。此时尝试启动数据库报出缺少库文件或程序包的错误。原因最常见的是系统缺少编译器或相关依赖库另一种情况是$ORACLE_HOME所在文件系统空间耗尽导致临时链接产物写不进去。解决先看日志里make失败的具体库名用系统包管理工具补齐依赖再清理$ORACLE_HOME下的临时文件释放空间最后重新执行相同的 apply 命令。opatch 会从上次中断位置继续前提是没有任何手动干预破坏了现场。4.4 现象四补丁后 invalid objects 大量增加现象数据库启动正常业务也能连上但跑批时频繁报内部错误。查询dba_objects发现大量对象处于INVALID状态。原因最常见的原因是跳过或中断了catbundle.sql psu apply这一步。二进制补丁和字典版本不匹配时许多内置包处于无效状态导致运行时报错。解决重新执行catbundle.sql psu apply执行完成后用utlrp.sql重编译失效对象。建议补丁流程里把字典脚本和重编译当成一个整体不要分开验证。我在某次维护中就是因为图省事只打了 apply结果第二天被业务电话叫醒。4.5 现象五RAC 多节点只装了一半版本不一致现象RAC 环境下只对其中一个节点执行了 opatch apply另一个节点版本还停在旧基线。集群正常启动但服务集中在已打补丁的节点上时表现异常或者crsctl stat res显示资源状态不一致。原因11.2.0.4 的 PSU 没有跨节点自动同步机制每个节点都必须独立执行同样的 apply 流程。解决在所有节点上重复执行完整的 apply 和字典脚本流程注意 RAC 环境下建议逐个节点处理避免全部节点同时停机。处理完后用opatch lsinventory对照所有节点的输出确保补丁号完全一致。5. 验证与回滚补丁装完不等于结束很多人打完补丁看到 opatch 显示成功就以为交付了其实后面的验证和回滚预案才是真正考验经验的地方。补丁安装的完成标准不是 apply 退出码为 0而是数据库、字典、业务三个层面都被验证过。5.1 三层验证补丁清单、注册表历史、对象状态第一层验证是补丁清单层面。执行opatch lsinventory -detail确认 p36575425 已经出现在已应用补丁列表里并且显示为APPLIED状态。$ORACLE_HOME/OPatch/opatch lsinventory -detail | grep -A 20 Patch List这一层最容易通过也最容易让人误判。补丁清单只能证明二进制文件已经更新不能证明字典脚本已经生效所以必须继续往下走。第二层验证是注册表历史。查询registry$history看是否多了一条本次 PSU 的记录。sqlplus -s / as sysdba EOF set pagesize 0 linesize 200 feedback off select action_time, action, version, comments from sys.registry\$history; EOF这里有个细节registry$history只有在catbundle.sql psu apply成功执行后才会插入新的记录。所以这条查询不仅是验证手段也是判断字典脚本是否落地的直接依据。注意 SQL 里$符号需要用\$转义否则 shell 会尝试把它当变量展开。第三层验证是对象状态统计。补丁应用后内置对象可能会因为版本变化失效正常流程应该用utlrp.sql重新编译然后确认失效数量收敛到可接受范围。select count(*) from dba_objects where status INVALID;如果数量不为 0先执行?/rdbms/admin/utlrp.sql完成后重新查询。不要拿阈值拍脑袋判断对于一个正常的 11.2.0.4 数据库全量重编译之后 INVALID 对象数量应该非常接近补丁前的水平。5.2 功能冒烟测试验证哪些能力回到正常水平验证不是跑几条 SQL 就够。我一般会按下面的表做一轮冒烟测试覆盖数据库核心能力和业务入口。验证项操作方式期望结果实例启停正常 shutdown/startup无报错监听自动注册业务账号连接用应用账号登录并执行典型事务事务提交成功无告警日志内部包调用运行常用存储过程无ORA-04063或ORA-06508网络监听lsnrctl status服务注册正常端口监听正常跨节点一致性RAC 上每个节点执行 lsinventory补丁状态完全一致冒烟测试不建议只测数据库层面。基于模拟项目X的真实经验有一次补丁后所有数据库检查都通过但应用层调用某个内置函数时出现性能退化排查下来是绑定变量执行计划变化导致。所以验证环节要覆盖真实业务 SQL不能只看系统健康度。5.3 回滚的边界别把回滚当后悔药如果补丁安装不顺利很多人第一反应是 opatch rollback。这个思路在部分场景可行但要清楚 11.2.0.4 的回滚边界。$ORACLE_HOME/OPatch/opatch rollback -id 36575425 -phBaseDir /u01/psu/36575425/database-id参数指定要回滚的补丁号-phBaseDir是指向补丁包数据库目录的路径。注意如果字典脚本已经执行成功单纯 binary rollback 会让二进制回退到旧版本但数据字典还停留在新版本这个不一致状态比不打补丁更危险。遇到这种情况我最有效的后悔药是恢复补丁前的数据库环境用 RMAN 备份恢复控制文件和系统表空间再重新打一个正确的补丁。这也是为什么第 3 章里我强调备份优先级最高的其实是数据库文件而不是 Oracle Home。对于那些已经跑过完整流程但业务效果不理想的场景备库切换往往比回滚更靠谱我建议在补丁方案里把切换演练也纳入计划。6. 一个实战技巧把 PSU 验收做成可重复的状态快照每次打补丁都要人工记基线、记版本、记失效对象数既慢又容易漏。我后来把整个验证过程收敛成一个状态快照脚本补丁前后各跑一次用 diff 判断是否干净。这里分享它的核心思路。#!/bin/bash # PSU 补丁前后状态快照脚本 ORACLE_SIDORCL ORACLE_HOME/u01/app/product/11.2.0/dbhome_1 SNAPSHOT_DIR/tmp/psu_snapshot mkdir -p $SNAPSHOT_DIR export ORACLE_SID ORACLE_HOME export PATH$ORACLE_HOME/bin:$ORACLE_HOME/OPatch:$PATH # 1. 抓取补丁清单 $ORACLE_HOME/OPatch/opatch lsinventory $SNAPSHOT_DIR/lsinv_$(date %Y%m%d).txt # 2. 抓取补丁注册历史和失效对象数 sqlplus -s / as sysdba EOF set pagesize 0 linesize 200 feedback off spool $SNAPSHOT_DIR/registry_$(date %Y%m%d).txt select action_time, action, version, comments from sys.registry\$history; spool off EOF sqlplus -s / as sysdba EOF set pagesize 0 feedback off select invalid_objects || count(*) from dba_objects where status INVALID; EOF脚本里SNAPSHOT_DIR可以根据实际情况改路径核心是把补丁前后的输出放到同一目录下用日期区分。第一个抓取项是补丁清单第二个是字典注册记录第三个是失效对象计数。补丁后跑一次然后逐个文件对比就能发现异常。有一次我在某生产机上跑完快照后发现 registry 没有新增记录补丁清单却显示 APPLIED一下就定位到字典脚本被意外跳过了。这种黑匣子问题在人工流程里通常要排查很久脚本化之后一分钟就能出结论。从那以后我每次打补丁都强制走一遍状态快照脚本补丁前后各抓一次确认二进制、字典、对象状态三份数据完全对齐才敢交付。这个习惯帮我挡住了好几次因为操作遗漏导致的隐性故障也希望帮到你。本文还有配套的精品资源点击获取