news 2026/10/14 7:27:20

Oracle 11.2.0.4 PSU补丁实战:从应用到回滚全流程解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Oracle 11.2.0.4 PSU补丁实战:从应用到回滚全流程解析

简介:面向Oracle数据库11.2.0.4版本的周期补丁集更新PSU(编号p33477185,2022年1月发布)专为Linux x86-64平台设计,属于官方安全与性能维护更新,主要用于修复安全漏洞、消除已知问题并提升数据库运行稳定性,适合负责生产环境维护的DBA和运维人员下载使用。压缩包大小约436.52MB,共3658个文件,以so共享库、o目标文件和a静态库等二进制组件为主,辅以sql/plb数据库脚本、xml元数据及jar/class等Java相关文件;这些不同类型的文件分别承担补丁落地、数据字典更新和安装校验等职责,既便于人工检查,也便于自动化工具调用,可支撑离线部署与回滚验证。该资源已有859人浏览/学习,在同类Oracle补丁资料中具有一定参考价值。下载后能够获得清晰的补丁文件目录结构,便于快速定位核心组件并核对适用条件,为之后使用OPatch完成数据库升级和长期稳定运行提供直接素材。

1. 为什么 2022 年还要盯着 11.2.0.4 的 PSU 补丁

凌晨两点被安全扫描告警叫醒,报告里躺着两个 CVSS 9.0 以上的 Oracle 数据库漏洞,而你的生产库还在 11.2.0.4,这就是 DBA 手里那把悬着的剑。11.2.0.4 是 Oracle 数据库生命周期里服役最长的版本之一,官方扩展支持虽然已经走完,但 2022 年 1 月仍然放出了 p33477185 这个 PSU 补丁包(DB-PSU-11.2.0.4.220118),修复了包括 TNS 监听和 SQL 引擎在内的一批高危安全问题。这个补丁包解决的核心问题很简单:不升级大版本,也能堵住安全漏洞、拿到关键 bug 修复。适合所有还在维护 11.2.0.4 生产环境的 DBA——尤其是那些因为业务兼容性暂时动不了升级、但又不能放任漏洞裸奔的团队。本文按我实际打补丁的顺序,把这套流程、参数和坑位全部拆开讲。

2. PSU 的定位与补丁前置条件:先搞懂再动手

2.1 PSU 与 CPU、RU 的区别:为什么生产库首选用 PSU

Oracle 的补丁体系里,PSU(Patch Set Update)和 CPU(Critical Patch Update)经常被混着叫,实际上两者是包含关系。CPU 是每年四个季度发布的安全补丁集合,PSU 则是在 CPU 基础上叠加了重要的非安全修复。换句话说,打了一个 PSU,相当于当季 CPU 加一批稳定性修复一起进去了。11.2.0.4 的 PSU 编号规则里,220118 代表 2022 年 1 月 18 日发布,p33477185 就是这个具体补丁号。

选择 PSU 而不是单独的 CPU,是因为生产库打补丁本身有停机成本和风险成本,与其分两次停,不如一次把安全补丁和关键 bug 修复全带上。RAC 环境里,所有节点必须打同一个 PSU 版本,不能出现某个节点 220118、另一个节点 211019(上一个 PSU)这种混搭,否则节点间字典版本不一致,重做日志传输和实例恢复时会直接报 ORA-00600。这个版本兼容要求写在补丁的 README 里,但很多人等到打完补丁起库才看到报错。

补丁包里的核心内容分为两部分:一是 opatch 工具层面需要更新的二进制文件,二是需要手动执行的 SQL 脚本。二进制部分通过 opatch apply 完成,SQL 部分需要进入 sqlplus 执行 catbundle.sql 里对应 PSU 的脚本。少执行任一步骤,补丁状态都是不完整的,这一点在验证阶段很容易踩到。

2.2 打补丁前的三个硬性检查:opatch 版本、ORACLE_HOME 空间、冲突检测

最先要确认的不是别的,是 opatch 工具本身的版本。p33477185 这个补丁对 opatch 有最低版本要求,官方 README 里写得很清楚,但我见过太多人跳过这一步,直接 opatch apply 然后报 OPatch version mismatch。这也算是最常见的打补丁翻车现场。升级 opatch 本身不复杂,解压覆盖到 ORACLE_HOME 下的 OPatch 目录即可,但要注意备份旧版本。

![提示] 升级 opatch 前先用cp -rp $ORACLE_HOME/OPatch $ORACLE_HOME/OPatch_bak留个后路,某些老插件和 opatch 版本绑定,回退时还能用。

ORACLE_HOME 的空间检查也容易被忽略。一个 PSU 补丁包解压后大约有几百 MB,apply 过程中 Oracle 会在 ORACLE_HOME 下的 .patch_storage 目录里备份被替换的二进制文件,这个备份目录通常会占到补丁包体积的 1.5 到 2 倍。如果 ORACLE_HOME 所在文件系统剩余空间不足,apply 会进行到一半报空间不足,然后留下一个半成品补丁状态,RAC 节点间的补丁状态直接不一致,比不打补丁更麻烦。

冲突检测按以下命令走一遍,合并补丁集的情况尤其需要这一步:

$ORACLE_HOME/OPatch/opatch prereq CheckConflictAgainstOHWithDetail -phBaseDir /u01/psu_p33477185/33477185

逻辑说明:这行命令检查待安装补丁与当前 ORACLE_HOME 里已安装补丁之间是否有文件覆盖冲突。-phBaseDir指向解压后的补丁目录,如果输出里有 ERROR 开头的冲突项,说明之前装过某些一次性补丁(one-off patch)和这个 PSU 修改了同一个文件。解决办法是先卸载冲突的 one-off patch 或者联系官方确认冲突方案,硬打的话会出现运行时行为不确定的问题,比如 oraagent 崩溃或者监听异常退出。参数-phBaseDir的路径要写补丁号那一层目录,不是外层解压目录。

做完这三个检查,才算具备了打补丁的前置条件。接下来进入操作流程。

3. 打补丁前的准备事项:备份、停机窗口与关闭顺序

3.1 备份策略:备份什么、备份到哪里、多久能恢复

打补丁这件事,备份有两层含义,第一层是数据库本身的备份,第二层是 ORACLE_HOME 二进制和集群软件的快照。数据库层面,RMAN 全备加归档是一道底线,但补丁操作原则上不碰数据文件,所以更关键的是第二层——ORACLE_HOME 的二进制回退能力。

常见做法是用 tar 把整个 ORACLE_HOME 打一份压缩包,放到补丁包之外的文件系统上。注意别放在 ORACLE_HOME 本身的目录里,否则回退的时候目录结构会互相污染。标准命令:

tar -czpf /u01/backup/oracle_home_$(date +%Y%m%d).tar.gz -C /u01/app oracle/product/11.2.0/dbhome_1

参数说明:-c创建归档,-z用 gzip 压缩,-p保留权限属性,-f指定归档文件名。-C切换工作目录到/u01/app,这样解压时能直接还原出相对的路径结构。保险起见的做法是把$ORACLE_HOME下的dbs目录单独再复制一份,因为密码文件和 spfile 都在那里,有些公司会把口令文件建在别处,tar 之前先find $ORACLE_HOME -name "*.ora"看一眼配置文件的实际分布。

集群环境里还要把 GI 的 home 目录一并备份,因为 PSU 打到 RAC 环境时,OPatch 工具会同时更新 DB home 和 GI home 下的部分二进制,即使你的补丁只针对数据库。不备 GI home 的后果是:一切正常还好,一旦需要回退,两个 home 的版本错位会导致crsctl stat res -t显示 INSTANCE 状态 FOREVER ONLINE 但实际连接全部失败。

3.2 关闭顺序有讲究:实例、监听、ASM、CRS 依次停

单机环境相对简单,RAC 环境的人员必须统一关闭顺序。正确顺序是先停业务、再停监听、最后停实例。ASM 实例在所有数据库实例关闭后才能停。很多人图省事,直接srvctl stop database -d orcl,这没问题,但后续 opatch apply 要求 ORACLE_HOME 下没有任何进程占用二进制文件,监听进程在 Linux 上会以 oracle 用户跑着,不先停监听,apply 时可能报无法替换libntcp11.so之类的文件锁错误。

标准关闭步骤,每个节点都执行:

sqlplus / as sysasm SQL> shutdown immediate; SQL> exit
srvctl stop listener -n node1 srvctl stop instance -d orcl -n node1 srvctl status database -d orcl

逻辑说明:上面是先停监听再停实例的顺序,srvctl stop instance指定-n节点参数可以只停当前节点。srvctl status database用来确认目标节点上的实例已经 OFFLINE。ASM 实例在最后一个实例关闭后会自动停止,也可以通过srvctl stop asm -n node1显式停掉。对单机环境这道命令替换成lsnrctl stop,然后sqlplus / as sysdba里执行shutdown immediate和shutdown abort的取舍:能 immediate 就别 abort,abort 会触发实例恢复,把这个时间留到补丁验证阶段更合适。

3.3 补丁包上传与解压过程中的文件属主问题

补丁包是用 oracle 用户下载并解压的,这一步看似简单,但在大批量服务器上经常出问题。用 root 解压是最高频错误之一——解压出来的文件属主变成 root,后续 opatch apply 以 oracle 用户运行时,对补丁目录没有写权限,直接报Permission denied。规范做法是上传到/u01/psu目录后,先切换用户再解压:

su - oracle mkdir -p /u01/psu_p33477185 cd /u01/psu_p33477185 unzip -q p33477185_112040_Linux-x86-64.zip

参数说明:-q静默解压,不输出每个文件的过程列表,但解压失败时看不到具体文件,所以第一次解压建议去掉-q,确认 zip 包完整没有 CRC 错误。解压完成后用ls -ld检查目录属主,必须是oracle:dba或oracle:oinstall。如果是 root 属主,chown -R oracle:dba /u01/psu_p33477185一次性修正。同理,补丁文件所属的文件系统挂载选项也别带noexec,OPatch 的脚本需要在这个目录下执行二进制;某些安全基线会把 /u01 挂成 noexec,opatch apply 时直接报无法执行/u01/psu_p33477185/OPatch/opatch。

4. 执行打补丁操作:opatch apply 到 SQL 脚本执行全流程

4.1 opatch apply 的参数选择与执行过程监听

所有前置条件就绪后,进入核心步骤。在补丁目录下执行 opatch apply,注意整个操作必须以 oracle 用户执行,不能用 root。以下是单节点环境的完整命令:

cd /u01/psu_p33477185/33477185 $ORACLE_HOME/OPatch/opatch apply

逻辑说明:命令不加额外参数时,opatch 会自动读取当前目录下的etc/config/opatch配置来决定 apply 方式。执行过程中它会自动检查 Inventory(补丁清单),做依赖分析和冲突检测,然后开始拷贝文件替换二进制。整个过程分阶段输出,看到Patch ... successfully applied才代表 apply 阶段成功。这里不建议加-silent参数,第一次打补丁最好盯着交互式输出的每一步,尤其是滚动到文件替换阶段时,如果出现Copy of file ... failed可以立刻 Ctrl+C 中断。

补丁 apply 过程中需要关注的几个输出关键字:

  • Verifying the patch...这一步做补丁文件校验,失败时说明补丁包下载不完整或解压过程丢文件
  • Backing up files...正在创建回滚所需的备份文件
  • Updating files...实际替换二进制文件
  • OPatch succeeded最终成功标志

![注意] apply 过程中会短暂占用 ORACLE_HOME 下的库文件,此时如果数据库实例没有被完全关闭,会出现Error in invoking target 'install'或直接提示某个.so文件被占用,只需要把残留的 oracle 进程ps -ef | grep ora_清理干净后重新执行 apply。

4.2 RAC 环境的多节点安装顺序与方式

RAC 环境下的 apply 分为 push 和 non-push 两种方式。non-push 方式要求在第一个节点执行opatch apply生成本地补丁,然后通过opatch auto把补丁推到其他节点。但 11.2.0.4 的 PSU 推荐做法是每个节点分别执行 apply,原因在于跨节点的opatch auto依赖 GI home 的 OUI 版本,版本不匹配时报错概率极高。

多节点执行顺序:节点 1 先 apply,apply 完成后不开库,继续在节点 1 执行$ORACLE_HOME/rdbms/admin/catbundle.sql的 PSU 脚本(这一步在第 4.3 节单独拆开讲),全部 SQL 执行完成后,再在节点 2、节点 3 重复第 4.1 节的 apply。这样设计的好处是:SQL 脚本只需要执行一次,不需要每个节点都跑;但二进制部分每个节点都必须更新。假如你节点 2 的 opatch lsinventory 显示没有 33477185,整个集群的sys.dba_registry_sqlpatch查询出来仍然只有一个补丁记录,但实际的二进制版本已经出现两套,这也是后面最容易踩的坑。

4.3 执行 catbundle.sql 中的 PSU 脚本:让字典版本跟上二进制

opatch apply 完成之后,如果不执行 SQL 脚本,数据库仍然认为字典版本没有更新,很多新特性不会启用,后续打其他补丁也可能冲突。这一步需要进入 sqlplus 执行catbundle.sql。文件位于$ORACLE_HOME/rdbms/admin/catbundle.sql,执行方式如下:

sqlplus / as sysdba SQL> startup upgrade SQL> @$ORACLE_HOME/rdbms/admin/catbundle.sql PSU apply SQL> shutdown immediate SQL> startup

参数说明:startup upgrade必须显式指定,否则脚本里的一些 DDL 会因版本保护机制直接报 ORA-20000。catbundle.sql的第一个参数PSU表示执行的是 PSU 类型的捆绑脚本,apply表示应用而非回滚。脚本执行时间通常在 10 到 30 分钟之间,取决于系统负载和数据库大小。执行结束后,Oracle 会向registry$sqlpatch写入一条补丁记录,这条记录才是验证补丁是否真正生效的金标准。

脚本执行过程中如果看到ORA-04021或者ORA-04020这类锁等待错误,多半是startup upgrade前还有残留会话没断开,用ps -ef | grep LOCAL=NO查一下是否还有外部连接,全部 kill 干净再重跑脚本。脚本本身支持重复执行,不需要担心跑到一半失败会污染字典,这点设计得比较友好。

5. 打补丁后必现排查:三个现场问题定位与处理

5.1 现象一:opatch lsinventory 显示补丁存在,但字典版本没变

打完补丁后用opatch lsinventory看到 33477185 在列表里,但查询sys.dba_registry_sqlpatch发现 ACTION 是APPLY的记录根本没有。这种状态叫二进制已更新、字典未更新,等于一半补丁生效一半没生效。

原因基本可以锁定在第 4.3 节的 SQL 脚本没有被执行,或执行时参数写错——比如把apply写成了rollback。另一个常见场景是执行了catbundle.sql但用了@catbundle.sql oracle(执行 ORACLE 脚本参数传错)导致脚本找不到对应 bundle,报SP2-0310: unable to open file后终止。

解决:重新执行@$ORACLE_HOME/rdbms/admin/catbundle.sql PSU apply,注意数据库必须处于startup upgrade状态。如果之前已经执行过但报错中断,再次执行前先查registry$history里有没有残留的部分执行记录,有的话要联系支持确认是否需要从catbundle脚本的特定段继续,不要盲目重跑全部。

select * from sys.registry$sqlpatch; select * from dba_registry_sqlpatch;

这两条查询能直接确认字典层的补丁记录状态,ACTION 字段显示APPLY且 STATUS 为SUCCESS才算是完整生效。

5.2 现象二:RAC 节点间补丁版本不一致,集群起库报 ORA-0112

RAC 环境起第二个实例时,告警日志直接报ORA-0112: media recovery required或者ORA-00600 [kectst1]。这在打完补丁的第一次启动期间尤其吓人,但实际上原因是节点 2 没有执行 opatch apply,只有节点 1 有了新版本的二进制。

原因:节点 1 和节点 2 的 ORACLE_HOME 里libserver11.a等核心文件版本不同,导致第二个实例启动时,实例间的字典检查和文件版本检查失败。在 11.2.0.4 这个版本上,PSU 的二进制差异不会自动跨节点同步,除非你用了共享 ORACLE_HOME——而这在高可用场景下几乎没人用。

解决:把第 4.1 节的 opatch apply 在节点 2 上重新执行一遍,然后重启该节点实例。别尝试只替换报错提示的那几个.so文件,那不是聪明的捷径,是一次性补丁另一处不被记录的永久隐患。完成后在两个节点分别执行opatch lsinventory -bugs_fixed | grep 33477185,确认输出一致。

5.3 现象三:TNS 监听启动失败,监听服务没有注册

补丁打完后lsnrctl start能起来,但lsnrctl status里看不到任何服务注册,客户端连接报ORA-12514: TNS listener does not currently know of service。其实监听进程本身没挂,是实例没有完成向监听的动态注册。

原因:补丁后首次启动实例时,LOCAL_LISTENER或者REMOTE_LISTENER参数里配的地址解析出现了延迟,常见于 DNS 解析慢或者/etc/hosts里主机名解析异常。PSU 本身不直接导致这个问题,但打补丁过程会重启监听和实例,把原本隐藏在运行期的问题暴露出来。

解决:先确认监听地址配置,执行lsnrctl services看是否已有服务;没有的话检查show parameter listener里LOCAL_LISTENER的值是否指向了正确的地址格式。11.2.0.4 上最常见的是LOCAL_LISTENER用了简写主机名但/etc/hosts里没有对应条目,改成完整的(ADDRESS=(PROTOCOL=TCP)(HOST=node1-vip)(PORT=1521))格式后,执行ALTER SYSTEM REGISTER手动触发注册,十秒内服务就会出现在监听状态里。

6. 补丁验证与回滚的实战技巧

6.1 用 opatch lsinventory 和 dba_registry_sqlpatch 双重确认

验证补丁生效这件事,理论上两条命令就够了。第一是系统层面的opatch lsinventory,第二是数据库字典层面的查询,两条必须同时满足才算真正完成。opatch lsinventory的完整命令带-bugs_fixed参数能列出这个补丁修复的具体 bug 号,便于对照安全公告里提到的 CVE 编号做审计留痕。

$ORACLE_HOME/OPatch/opatch lsinventory -bugs_fixed | grep -A 4 "33477185"
SQL> select patch_id, patch_uid, version, action, status from sys.registry$sqlpatch where patch_id = 33477185;

PATCH_UID是每次 apply 生成的唯一标识,回滚时opatch rollback需要用到-id参数,这个 UID 在哪查?$ORACLE_HOME/.patch_storage/33477185_<date>/etc/目录里有对应的元数据文件。RAC 环境验证时,每个节点都要跑一遍 opatch lsinventory,不要只在主节点查一次——这也是我吃过亏的地方,曾经只在节点 1 验证完就宣布升级成功,结果节点 2 的补丁根本没打上,第二天业务切换过去直接连不通。

6.2 补丁回滚的两种方式和回滚后的强制操作

11.2.0.4 的 PSU 回滚比 12c 以后的版本要稍微繁琐一点,核心原因是二进制和字典两部分都要回滚。二进制回滚用 opatch rollback:

cd /u01/psu_p33477185/33477185 $ORACLE_HOME/OPatch/opatch rollback -id 33477185

参数说明:-id后面跟补丁号,opatch 会自动从.patch_storage目录里找到 apply 时的备份文件,把被替换过的二进制文件全部还原。注意,如果 ORACLE_HOME 里后来打过其他补丁,直接 rollback 这个 PSU 可能与其他补丁产生冲突,需要在 rollback 之前先卸载后装的补丁,顺序上要遵循后打先撤的原则。

二进制回滚完成后,数据库字典层面的变更不会自动撤销,需要再次进入 sqlplus 执行catbundle.sql的回滚参数:

sqlplus / as sysdba SQL> startup upgrade SQL> @$ORACLE_HOME/rdbms/admin/catbundle.sql PSU rollback SQL> shutdown immediate SQL> startup

这里有个容易被忽略的细节:catbundle.sql的 rollback 不是把所有 DDL 倒序重放,它是从registry$sqlpatch记录里删除对应的补丁记录,同时把被 PSU 修改过的数据字典视图重新编译回旧版本。如果漏掉这一步,数据库二进制回到旧版但字典还留着补丁痕迹,下次再 apply 这个 PSU 时会直接报补丁版本不匹配。

从那以后,我每次打补丁都强制走一遍完整的验证清单:opatch lsinventory 的输出截图、dba_registry_sqlpatch 的查询结果、监听状态的三项确认,全部保留到一个名为patch_checklist_<date>的 SQL 脚本里,下次排查问题时拿出来一比对就知道哪个环节漏了。这套流程不是最优美,但胜在每一步都有据可查,回滚也只是重复一遍流程而已。希望帮到你。

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

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

计算机网络复试高频考点:故障驱动型小题精讲

1. 项目概述&#xff1a;为什么一份“小题总结”值得花三天重写三遍“西电复试计算机网络 小题总结”——这八个字背后&#xff0c;不是一份简单的考前笔记&#xff0c;而是一套被某高校通信工程方向复试现场反复验证过的知识压缩-错误拦截-临场调用三重机制。我连续三年参与该…

作者头像 李华
网站建设 2026/10/14 7:26:50

具身智能的终点不是人形,实时音视频才是神经系统

2025年开年&#xff0c;人形机器人跳舞、跑步、做家务的视频刷遍全网&#xff0c;看着它们越来越像人的动作&#xff0c;很多朋友都在问同一个问题&#xff1a;人形机器人是不是具身智能的终点&#xff1f;我的回答可能和主流叙事不太一样&#xff1a;具身智能的终点从来不是“…

作者头像 李华
网站建设 2026/10/14 7:26:38

PS5远程串流全指南:从主机设置到网络优化,随时随地玩遍游戏

串流游戏这个东西&#xff0c;我前前后后折腾了小半年&#xff0c;踩过的坑能写满一页纸&#xff0c;但带来的便利也是实打实的。所谓“AnyPS5”&#xff0c;我自己的理解很简单&#xff1a;不管手里是手机、平板、轻薄本还是办公室的电脑&#xff0c;只要能装客户端、能联网&a…

作者头像 李华
网站建设 2026/10/14 7:26:30

Windows系统安装生存指南:硬件兼容、分区策略与驱动优化

1. 这不是重装系统教程&#xff0c;而是一份给真实用户的“系统安装生存指南”你是不是也经历过&#xff1a;硬盘突然变砖、蓝屏代码看都看不懂、重装完发现驱动全丢、连WiFi都连不上&#xff1f;我做过上百次Windows系统安装&#xff0c;从XP时代用光盘启动&#xff0c;到如今…

作者头像 李华
网站建设 2026/10/14 7:26:19

Python表单接口开发实战:分层设计与MCP工具化

1. 从表单到接口&#xff1a;为什么这套开发路径值得花时间啃表单系统在业务系统里属于那种“看起来简单、做起来全是坑”的模块。很多人第一次接触表单接口开发&#xff0c;觉得无非就是增删改查&#xff0c;几张表、几个字段、一套RESTful路由就完事了。但真正落到实际项目里…

作者头像 李华