☰
Oracle 11.2.0.4 PSU补丁p36575425安装实战与避坑指南
2026/10/12 14:48:44 网站建设 项目流程

简介:面向 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 怎么选:稳定优先还是特性优先

PSU(Patch Set Update)和 DBBP(Database 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_SID=ORCL 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/database

CheckConflictAgainstOHWithDetail是 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 EOF

catbundle.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_SID=ORCL 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,一下就定位到字典脚本被意外跳过了。这种黑匣子问题在人工流程里通常要排查很久,脚本化之后一分钟就能出结论。

从那以后我每次打补丁都强制走一遍状态快照脚本,补丁前后各抓一次,确认二进制、字典、对象状态三份数据完全对齐才敢交付。这个习惯帮我挡住了好几次因为操作遗漏导致的隐性故障,也希望帮到你。

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询