☰
Oracle 11.2.0.4 PSU补丁应用全流程:OPatch与datapatch实战
2026/10/12 7:49:57 网站建设 项目流程

简介:本资源为Oracle官方补丁包p26635834,面向Linux x86-64平台上的Oracle数据库及中间件运维人员,用于修复产品安全漏洞、性能缺陷并提升系统稳定性。压缩包共103个文件,约40.49MB,以class、sql、xml、jar等类型为主,其中sql脚本承担数据库层面的修复与调整,xml文件提供补丁元数据供OPatch识别,jar与class则对应Java组件的更新逻辑,另含少量txt说明与证书文件,整体结构符合Oracle补丁的标准组织方式。该补丁包内含PatchSearch.xml元数据与补丁二进制内容,可配合OPatch工具完成兼容性校验、补丁应用与安装结果核查,帮助读者在受控环境中完成一次规范的补丁部署与验证。目前已有265人学习下载,适合需要跟进Oracle安全更新、维护企业级数据库合规运行的中高级DBA参考。

1. 从 p26635834_112040 这个补丁号说起:它到底解决什么问题

如果你在 Linux x86-64 环境里维护过 Oracle 数据库,大概率见过这种命名:p26635834_112040_Linux-x86-64.zip。第一眼看像随机字符串,其实每个字段都有含义——26635834是补丁编号(Patch Number),112040对应数据库版本 11.2.0.4,Linux-x86-64是目标平台。这不是一个普通压缩包,而是 Oracle 官方补丁集在 My Oracle Support 上的标准交付形态。

它解决的核心问题是:11.2.0.4 这个长期支持版本在生命周期内会累积大量 bug 修复和安全补丁,逐个打单点补丁(one-off patch)容易产生冲突,而 PSU(Patch Set Update)或 CPU(Critical Patch Update)把一批经过回归测试的修复打包在一起,用 OPatch 工具一次性应用。对运维来说,这意味着更少的停机窗口、更可控的依赖关系。

适合谁用?正在跑 11.2.0.4 的 DBA、需要给测试环境补齐补丁基线的实施工程师、以及在做数据库迁移前要统一补丁版本的技术负责人。如果你用的是 12c 以上版本,补丁编号规则和 OPatch 版本要求都不同,这份资源不适用。

2. 解压前先搞清目录结构:OPatch 与补丁元数据怎么读

拿到 zip 包别急着 unzip 到任意目录。Oracle 补丁对解压路径有隐含要求,路径里带空格或中文,OPatch 在解析patch_location时可能报OPatch failed with error code 73。我一般会在/u01/patch下建一个纯英文短路径,把包放进去再解压。

2.1 解压后的标准目录长什么样

# 创建补丁工作目录,避免路径含空格或中文 mkdir -p /u01/patch/26635834 cd /u01/patch/26635834 # 解压,注意 unzip 默认不覆盖已存在文件,加 -o 可强制覆盖 unzip -o p26635834_112040_Linux-x86-64.zip # 查看解压结果 ls -la

解压后通常得到两层结构:顶层是补丁号目录26635834,里面包含README.html、etc/config/inventory.xml、files/子目录。README.html是必读的,它写明了前置补丁要求(prerequisite patches)、是否需要opatch prereq检查、以及是否涉及datapatch步骤。etc/config/inventory.xml记录了补丁包含的组件和版本,OPatch 靠它判断当前 ORACLE_HOME 是否匹配。

提示:不要跳过 README.html。我见过有人直接opatch apply,结果因为缺少前置补丁导致中途失败,回滚又花了半小时。

2.2 用 opatch lsinventory 确认当前基线

在打补丁之前,必须先确认当前 ORACLE_HOME 的补丁状态。这一步是后面所有操作的前提。

# 切换到 oracle 用户,确保环境变量指向目标 ORACLE_HOME su - oracle echo $ORACLE_HOME echo $PATH | grep -o '[^:]*OPatch[^:]*' # 查看当前已安装补丁列表 $ORACLE_HOME/OPatch/opatch lsinventory -detail

lsinventory输出里重点看三块:Oracle Home 路径、已安装的 Interim Patch 列表、以及 OPatch 自身版本。如果 OPatch 版本低于补丁 README 里要求的最低版本,需要先升级 OPatch。常见做法是从补丁包自带的OPatch目录替换,或者从官方单独下载对应版本。

参数说明:-detail会列出每个补丁影响的组件和文件,不加则只显示补丁号汇总。排查冲突时用-detail更直观。

2.3 冲突检查:opatch prereq 与 lspatches

# 检查补丁是否与当前环境冲突 $ORACLE_HOME/OPatch/opatch prereq CheckConflictAgainstOHWithDetail -phBaseDir /u01/patch/26635834/26635834 # 列出当前所有补丁号,便于比对 $ORACLE_HOME/OPatch/opatch lspatches

prereq子命令会扫描ORACLE_HOME里已存在的文件,判断补丁是否会覆盖不同版本的同名文件。如果输出Prereq "checkConflictAgainstOHWithDetail" passed,说明可以继续。如果报Conflict,需要根据提示决定是回滚旧补丁还是换用包含关系的新补丁集。

3. 正式 apply:从 OPatch 命令到 datapatch 的完整链路

补丁应用分两个层面:二进制文件替换(OPatch apply)和数据库字典更新(datapatch)。11.2.0.4 的 PSU 通常两者都需要,只做前者会导致数据库启动后组件版本不一致。

3.1 关闭实例与监听,确认无活动会话

# 在 oracle 用户下操作 sqlplus / as sysdba <<EOF shutdown immediate; exit; EOF # 停止监听 lsnrctl stop # 确认没有残留的 oracle 进程占用 ORACLE_HOME 下的文件 ps -ef | grep $ORACLE_HOME | grep -v grep

shutdown immediate会回滚未提交事务并断开所有会话。如果库很大,这一步可能耗时几分钟。生产环境建议提前通知应用方,或者用shutdown transactional等待当前事务完成。停监听是为了防止补丁过程中有新连接进来。

3.2 执行 opatch apply 并观察输出

cd /u01/patch/26635834/26635834 # 应用补丁,-silent 减少交互,-local 表示仅本地节点 $ORACLE_HOME/OPatch/opatch apply -silent -local # 如果补丁要求指定 OCM 响应文件,加 -ocmrf 参数 # $ORACLE_HOME/OPatch/opatch apply -silent -ocmrf /u01/patch/ocm.rsp

输出里会逐条打印ApplySession的进度。关键节点是Backing up和Copying files。OPatch 会自动备份被覆盖的文件到$ORACLE_HOME/.patch_storage下,回滚时靠这个目录。如果中途报Prerequisite check "CheckActiveFilesAndExecutables" failed,说明还有进程占用文件,回到 3.1 检查。

参数说明:-silent跳过确认提示,适合脚本化;-local在 RAC 环境下只打当前节点,不加则默认所有节点。单实例环境加不加都行,但显式写上更清晰。

3.3 datapatch:让数据库字典跟上补丁版本

# 启动实例到 mount 或 open 状态 sqlplus / as sysdba <<EOF startup; exit; EOF # 运行 datapatch,它会读取补丁里的 SQL 脚本并应用到数据库 cd $ORACLE_HOME/OPatch ./datapatch -verbose

datapatch会检查dba_registry_sqlpatch视图,对比当前数据库已应用的 SQL 补丁和 ORACLE_HOME 里的补丁文件。如果发现不一致,自动执行缺失的脚本。-verbose会打印每个组件的更新过程,排查失败时必加。

常见失败是datapatch报ORA-04021: timeout occurred while waiting to lock object,说明有会话持有字典对象锁。解决方法是确认无业务连接后重试,或者用datapatch -force强制(不推荐,除非确认无并发)。

3.4 验证补丁是否生效

# 再次查看补丁列表 $ORACLE_HOME/OPatch/opatch lspatches # 在数据库里查询 SQL 补丁记录 sqlplus / as sysdba <<EOF select patch_id, patch_uid, version, status, action_time from dba_registry_sqlpatch order by action_time; exit; EOF

lspatches应显示新补丁号,dba_registry_sqlpatch里status为SUCCESS。如果status是FAILED,需要看datapatch日志,通常在$ORACLE_HOME/cfgtoollogs/sqlpatch下。

4. 避坑与排查:补丁失败后先看这五个地方

补丁操作翻车大多不是命令写错,而是环境状态没对齐。下面五条是我踩过或见别人踩过的典型场景。

4.1 OPatch 版本过低导致 apply 直接退出

现象:执行opatch apply后立刻报OPatch version 11.2.0.3.x is lower than the minimum required version。原因:补丁 README 里指定了最低 OPatch 版本,旧版无法解析新补丁的inventory.xml结构。解决:从补丁包自带的OPatch目录替换$ORACLE_HOME/OPatch,替换前备份原目录。替换后opatch version确认。

4.2 路径含空格或中文导致解析失败

现象:opatch apply报OPatch failed with error code 73或Invalid patch location。原因:OPatch 内部用 shell 拼接路径,空格被当作参数分隔符。解决:把补丁移到/u01/patch这类纯英文无空格路径下重新解压。不要用/home/oracle/我的补丁/这种路径。

4.3 前置补丁缺失导致中途回滚

现象:apply 进行到一半报Prerequisite patch 12345678 is not installed,然后自动回滚。原因:当前 ORACLE_HOME 缺少 README 里列出的前置补丁。解决:按 README 的Prerequisite Patches列表逐个补齐,或者直接选用包含前置补丁的更大补丁集。回滚后lspatches应恢复原状,确认无残留再重试。

4.4 datapatch 报 ORA-04021 锁超时

现象:datapatch -verbose输出ORA-04021: timeout occurred while waiting to lock object。原因:有会话持有SYS下的字典对象锁,常见于未断开的应用连接或后台 job。解决:shutdown immediate后以 restrict 模式启动,或者查v$locked_object定位会话并 kill。确认无并发后再跑datapatch。

4.5 回滚后 OPatch 状态不一致

现象:opatch rollback成功,但lspatches仍显示补丁号,或者dba_registry_sqlpatch里状态混乱。原因:回滚只还原了二进制文件,SQL 层面的回滚需要datapatch配合。解决:回滚二进制后,启动数据库跑datapatch -verbose,它会根据dba_registry_sqlpatch里的记录反向执行回滚脚本。如果状态仍不对,查$ORACLE_HOME/.patch_storage下的回滚日志。

5. 补丁基线管理:把一次性操作变成可重复流程

单次打补丁不难,难的是让团队里每个人、每个环境都打出一样的基线。我后来养成的习惯是:把补丁号、OPatch 版本、datapatch 结果三样东西记在一个patch_manifest.txt里,跟 ORACLE_HOME 一起归档。

5.1 用脚本固化检查与记录

#!/bin/bash # patch_baseline.sh - 记录当前 ORACLE_HOME 补丁基线 # 用法: ./patch_baseline.sh /u01/app/oracle/product/11.2.0/dbhome_1 OH=$1 OUT=/u01/patch/patch_manifest_$(date +%Y%m%d).txt { echo "=== ORACLE_HOME: $OH ===" echo "=== Date: $(date) ===" echo "" echo "--- OPatch Version ---" $OH/OPatch/opatch version echo "" echo "--- Installed Patches ---" $OH/OPatch/opatch lspatches echo "" echo "--- SQL Patch Registry ---" sqlplus -s / as sysdba <<EOF set pagesize 100 linesize 200 select patch_id, version, status, action_time from dba_registry_sqlpatch order by action_time; exit; EOF } > $OUT 2>&1 echo "Baseline written to $OUT"

这个脚本把 OPatch 版本、二进制补丁列表、SQL 补丁注册表三块信息一次性落盘。参数$1是 ORACLE_HOME 路径,输出文件名带日期,避免覆盖。sqlplus -s是静默模式,不打印 banner,适合脚本采集。

5.2 对比两个环境的基线差异

# 假设有两个环境的 manifest 文件 diff /u01/patch/patch_manifest_20250101.txt /u01/patch/patch_manifest_20250115.txt

如果输出里只有日期不同,说明两个环境补丁一致。如果有补丁号差异,diff会直接标出来。我一般会在变更前跑一次、变更后再跑一次,把两份 manifest 一起提交到变更记录里。这样下次有人问「这个环境到底打了哪些补丁」,直接看文件就行,不用再登机器查。

5.3 一个容易忽略的细节:OCM 响应文件

如果补丁要求-ocmrf参数,说明它需要 OCM(Oracle Configuration Manager)响应文件。这个文件通常由ocm.rsp提供,内容包含 OCM 的配置信息。没有的话可以在 apply 时加-ocmrf /dev/null跳过,但部分补丁会因此报 warning。常见做法是提前从官方文档生成一个通用ocm.rsp,放在/u01/patch下复用。

注意:ocm.rsp里可能包含环境相关的配置,不要跨环境直接拷贝,最好每个环境单独生成。

从那以后我每次打完补丁,都会强制走一遍patch_baseline.sh,把 manifest 跟变更单一起归档。这个习惯帮我省过至少两次「这个环境到底跟那个环境差哪个补丁」的扯皮。希望帮到你。

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

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

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

立即咨询