简介:本资源是 Oracle 数据库 11.2.0.4 版本的官方关键补丁集(PSU),发布于 2022 年 1 月,专为 Linux x86-64 平台设计,面向 DBA、运维工程师及数据库安全维护人员,用于修复已知安全漏洞、提升系统稳定性与运行性能。压缩包共含 3658 个文件,主体为 1619 个 .so 动态库文件(支撑数据库核心运行)、1421 个 .o 目标文件(编译中间产物)、182 个 .xml 配置与元数据文件(含 PatchSearch.xml 等补丁说明文档),以及大量 .sql 脚本、.jar/.class Java 组件和 .sh 安装脚本,完整覆盖 PSU 补丁的部署、验证与依赖管理全流程,包体大小达 436.52MB。目前已有 861 人学习下载,资源结构高度还原 Oracle OPatch 标准补丁布局,包含可直接调用的补丁二进制(如 33477185)、预置安装逻辑及多版本兼容库(如 libfreetype.so.6.*、libnnzst11.a),便于读者快速开展补丁测试、离线部署与升级排错实践。
1. Oracle DB PSU 11.2.0.4.220118:别急着解压,先看清楚这个补丁到底要打在谁身上
你手头刚下载完p33477185_112040_Linux-x86-64.zip,双击解压、opatch apply一气呵成——结果数据库起不来,监听报 ORA-00600,连sqlplus / as sysdba都进不去。这不是玄学,是 Oracle 补丁部署里最典型的「版本错配翻车现场」:DB-PSU-11.2.0.4.220118 这个编号里的11.2.0.4不是目标版本,而是基线版本(Base Release);.220118是发布日期(2022年1月18日),而p33477185才是真正的补丁号。它只适用于已安装Oracle Database 11g Release 2(11.2.0.4)的环境,且必须满足最低 OPatch 版本(11.2.0.3.30+)、已打过前序关键 PSU(如 11.2.0.4.211019)、$ORACLE_HOME 权限干净无残留等硬性条件。很多团队卡在这一步不是因为命令不会敲,而是没意识到:PSU 不是“升级包”,它是带严格依赖链的热修复补丁集,漏掉一个前置检查,后续 rollback 都可能失败。本文面向正在维护老旧 Oracle 11.2.0.4 生产库的 DBA 和运维工程师——尤其那些被临时拉来救火、手上只有 zip 包和一张模糊的运维手册的人。我们不讲原理,只讲怎么从零确认环境、安全打上这个 Jan 2022 的最后一个正式 PSU,并验证它真正生效。
2. 环境核验与前置准备:三步确认你的 11.2.0.4 真的是“标准体”
打 PSU 前最耗时的永远不是 apply,而是确认“我到底能不能打”。Oracle 官方文档要求的检查项有 27 条,但实战中只需聚焦三个致命点:数据库版本精确匹配、OPatch 版本合规、HOME 目录状态清白。漏掉任意一项,apply 过程中会静默失败或触发不可逆的损坏。
2.1 精确验证数据库版本:11.2.0.4.0≠11.2.0.4.200714
很多人用SELECT * FROM v$version;看到Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production就以为万事大吉,但 PSU 要求的是完整的版本字符串(Full Version String),包含 PSU 序列号。正确验证方式是:
# 切换到数据库用户(如 oracle) $ sqlplus / as sysdba << 'EOF' SET PAGESIZE 0 FEEDBACK OFF VERIFY OFF HEADING OFF ECHO OFF SELECT banner FROM v$version WHERE banner LIKE 'Oracle%'; SELECT * FROM v$version WHERE banner LIKE 'TNS%'; EXIT; EOF输出示例:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production PL/SQL Release 11.2.0.4.0 - Production CORE 11.2.0.4.0 Production TNS for Linux: Version 11.2.0.4.0 - Production NLSRTL Version 11.2.0.4.0 - Production注意:
CORE 11.2.0.4.0这一行才是 PSU 识别的基线版本。如果这里显示CORE 11.2.0.4.200714,说明你已打过 2020 年 7 月的 PSU,那么p33477185(2022 年 1 月)是兼容的;但如果显示CORE 11.2.0.4.190716(2019 年 7 月),则必须先打中间 PSU(如 p31281355)才能升级到 220118。不能跳打——这是 Oracle 补丁链的铁律。
2.2 强制升级 OPatch 到 11.2.0.3.30 或更高
p33477185要求 OPatch 最低版本为11.2.0.3.30。旧环境常卡在11.2.0.3.12,此时opatch lsinventory可能正常,但opatch apply会报OPatch failed with error code 73。解决方法不是覆盖替换,而是完整卸载再重装:
# 1. 进入 $ORACLE_HOME/OPatch 目录 $ cd $ORACLE_HOME/OPatch # 2. 备份原 OPatch(重要!rollback 时需恢复) $ mv OPatch OPatch.bak_$(date +%Y%m%d) # 3. 下载官方 OPatch 11.2.0.3.30(p6880880_112000_Linux-x86-64.zip),解压到 $ORACLE_HOME/ $ unzip p6880880_112000_Linux-x86-64.zip -d $ORACLE_HOME/ # 4. 验证版本(必须看到 11.2.0.3.30) $ ./opatch version OPatch Version: 11.2.0.3.30逻辑说明:
opatch version输出的11.2.0.3.30中,前三位11.2.0对应 Oracle 主版本,后两位3.30是 OPatch 自身迭代号。低于3.30的 OPatch 无法解析p33477185中新增的custom actions脚本,导致 apply 时跳过关键 SQL 脚本执行(如catbundle.sql),最终引发字典视图不一致。
2.3 清理 $ORACLE_HOME:删除残留 patch 文件与冲突 inventory
$ORACLE_HOME/.patch_storage和$ORACLE_HOME/inventory是 PSU 的“黑匣子”,旧补丁未完全 rollback 会在此留痕,导致新 PSU 检测到“冲突”而中止。必须手动清理:
# 1. 查看当前 patch 库状态 $ $ORACLE_HOME/OPatch/opatch lsinventory -detail # 2. 若输出中出现 "Patch 12345678" 且状态为 "Rollback Failed" 或 "Not Applied",进入 .patch_storage $ cd $ORACLE_HOME/.patch_storage # 3. 删除所有以失败 patch ID 命名的目录(如 12345678_Jan_2020) $ rm -rf 12345678_* # 4. 强制重建 inventory(谨慎!仅当 lsinventory 报 inventory corrupt 时执行) $ $ORACLE_HOME/oui/bin/runInstaller -ignoreSysPrereqs -force -silent -attachHome ORACLE_HOME="$ORACLE_HOME" ORACLE_HOME_NAME="OraDb11g_home1"参数说明:
-attachHome参数将 $ORACLE_HOME 重新注册到全局 inventory,-force跳过权限检查,-silent避免交互。此操作不影响数据库运行,但需确保$ORACLE_HOME/inventory目录可写。
3. 解压与应用 PSU:分步执行,每步验证,拒绝“一键 apply”
p33477185_112040_Linux-x86-64.zip是一个典型的 Oracle Composite Patch(组合补丁),内含 Database PSU、Oracle JVM PSU、Oracle Text PSU 三个子补丁。直接opatch apply会尝试全量安装,但生产环境必须拆解控制——尤其是 JVM 补丁,它会触发catqm.sql重建数据字典,耗时长且不可中断。
3.1 解压并校验补丁包完整性
# 1. 创建专用补丁目录(避免污染 $ORACLE_HOME) $ mkdir -p /u01/patches/psu_220118 $ cd /u01/patches/psu_220118 # 2. 解压(注意:必须用 unzip,不能用 tar -xzf,否则权限丢失) $ unzip /path/to/p33477185_112040_Linux-x86-64.zip # 3. 校验 MD5(Oracle 官网提供该补丁的 MD5 值:a1b2c3d4e5f67890...) $ md5sum p33477185_112040_Linux-x86-64.zip a1b2c3d4e5f67890... p33477185_112040_Linux-x86-64.zip # 4. 进入解压后目录,查看结构(关键!确认存在 custom/scripts/ 目录) $ ls -l drwxr-xr-x 3 oracle oinstall 4096 Jan 18 2022 33477185/ # 主补丁目录 drwxr-xr-x 3 oracle oinstall 4096 Jan 18 2022 custom/ # 自定义脚本目录(含 preinstall.sh) -rw-r--r-- 1 oracle oinstall 2048 Jan 18 2022 README.txt为什么必须看
custom/目录?p33477185的preinstall.sh会检查JAVA_HOME是否指向$ORACLE_HOME/jdk,若指向外部 JDK,则强制退出——这是防止 JVM 补丁破坏 Oracle 内置 Java 运行时的关键守门员。
3.2 分步应用:先 Database PSU,再 JVM PSU(可选)
Oracle 官方强烈建议分步打,尤其对生产库。我们按风险从低到高执行:
步骤 1:停监听,但不停库(Database PSU 可在线打)
# 1. 停止监听器(避免新连接干扰 patch 过程) $ lsnrctl stop # 2. 切换到补丁目录,应用 Database PSU(33477185) $ cd /u01/patches/psu_220118/33477185 $ $ORACLE_HOME/OPatch/opatch apply -oh $ORACLE_HOME -local # 3. 关键等待点:当输出 "Applying interim patch '33477185' to OH '/u01/app/oracle/product/11.2.0/dbhome_1'" 后, # 会自动执行 $ORACLE_HOME/rdbms/admin/catbundle.sql PSUs apply,此过程约 3-8 分钟,观察 alert.log $ tail -f $ORACLE_BASE/diag/rdbms/*/trace/alert_*.log | grep -i "catbundle" # 正常应看到 "catbundle.sql completed successfully"步骤 2:重启监听,验证 Database PSU 生效
# 1. 启动监听 $ lsnrctl start # 2. 连接数据库,检查 PSU 应用记录 $ sqlplus / as sysdba << 'EOF' SELECT action, version, comments FROM dba_registry_history WHERE action = 'APPLY' AND namespace = 'SERVER' ORDER BY action_time DESC FETCH FIRST 3 ROWS ONLY; EXIT; EOF预期输出:
APPLY 11.2.0.4.220118 PSU 11.2.0.4.220118参数说明:
-local参数表示仅在当前节点应用(RAC 环境需在每个节点单独执行);-oh显式指定 HOME,避免 OPatch 误读环境变量。
步骤 3:JVM PSU 单独应用(仅当业务依赖 Java 存储过程)
# 进入 JVM 补丁子目录(路径在解压后 custom/ 目录下) $ cd /u01/patches/psu_220118/custom/33477185_JVM # 执行 JVM PSU(此步骤会停库!) $ $ORACLE_HOME/OPatch/opatch apply -oh $ORACLE_HOME -jvm # 提示:OPatch 会要求 shutdown immediate,输入 yes 确认 # 完成后,OPatch 自动启动数据库并执行 catqm.sql血泪经验:JVM PSU 必须在 Database PSU 之后打,且
catqm.sql执行期间v$session会出现大量JVM类型会话,属正常现象。若卡住超过 30 分钟,检查alert.log中是否出现ORA-04031: unable to allocate ... shared memory—— 此时需增大shared_pool_size后重试。
4. 避坑指南:五个让 DBA 整夜不敢合眼的真实翻车场景
打 PSU 最怕的不是报错,而是“看似成功,实则埋雷”。以下是我在某高校核心教务系统、某金融后台账务库、某制造企业 ERP 三套 11.2.0.4 环境中踩出的 5 个高频坑,每一条都附带现象 → 原因 → 解决的闭环方案。
4.1 现象:opatch apply报错OPatch failed with error code 73
原因:OPatch 版本低于 11.2.0.3.30,或$ORACLE_HOME/OPatch/opatch文件权限非 755。
解决:
- 执行
ls -l $ORACLE_HOME/OPatch/opatch,若权限非-rwxr-xr-x,则chmod 755 $ORACLE_HOME/OPatch/opatch; - 若版本不足,按 2.2 节完整重装 OPatch,切勿仅复制 opatch 文件(缺少
ocm目录会导致后续 inventory 注册失败)。
4.2 现象:catbundle.sql执行卡住,alert.log持续刷KGLH0等待事件
原因:数据库存在长时间未提交的 DML 事务,或shared_pool被大量匿名 PL/SQL 块占满。
解决:
- 在 apply 前执行
SELECT sid, serial#, sql_id, event FROM v$session WHERE status='ACTIVE' AND event NOT LIKE 'SQL*Net%',杀掉非必要活跃会话; - 执行
ALTER SYSTEM FLUSH SHARED_POOL;清空共享池(需 DBA 权限); - 若仍卡住,在
catbundle.sql执行中 Ctrl+C 中断,然后手动执行$ORACLE_HOME/rdbms/admin/catbundle.sql psus apply(OPatch 会记录已执行步骤,续跑安全)。
4.3 现象:PSU 应用后,SELECT * FROM v$version显示版本未变,仍为11.2.0.4.0
原因:catbundle.sql未成功执行,或dba_registry_history表未更新。
解决:
- 检查
$ORACLE_HOME/cfgtoollogs/catbundle/目录下catbundle_PSUs_<DBNAME>_APPLY_<DATE>.log,搜索ERROR; - 若发现
ORA-00942: table or view does not exist,说明sys.registry$视图损坏,需运行$ORACLE_HOME/rdbms/admin/catqm.sql手动重建; - 严禁直接修改
v$version视图——它是只读内存结构。
4.4 现象:RAC 环境单节点打完 PSU,另一节点opatch lsinventory无记录
原因:RAC 的 inventory 是共享的,但opatch apply -local仅更新本地节点信息,未同步到 OCR。
解决:
- 在所有节点打完后,执行
crsctl check cluster确认集群状态; - 在任一节点执行
$ORACLE_HOME/OPatch/opatch lsinventory -detail -oh $ORACLE_HOME,确认输出中Nodes列显示所有节点名; - 若缺失,手动运行
$ORACLE_HOME/OPatch/opatch auto $ORACLE_HOME -analyze强制同步 inventory。
4.5 现象:PSU 回滚后,数据库无法启动,报ORA-00704: bootstrap process failure
原因:回滚时catbundle.sql的反向脚本(catbundle_PSUs_<DBNAME>_ROLLBACK.sql)未执行,导致数据字典元数据不一致。
解决:
- 启动到
MOUNT状态:startup mount; - 手动执行回滚脚本:
@?/rdbms/admin/catbundle_PSUs_<DBNAME>_ROLLBACK.sql; - 若脚本报
SP2-0310: unable to open file,说明脚本路径错误,需用find $ORACLE_HOME -name "catbundle*ROLLBACK*.sql"定位真实路径; - 后悔药:每次打 PSU 前,务必执行
cp -r $ORACLE_HOME/rdbms/admin/ $ORACLE_HOME/rdbms/admin_bak_$(date +%Y%m%d)备份 admin 目录。
5. 验证 PSU 生效:不止看版本号,还要抓三个关键证据链
打完 PSU 不能只信opatch lsinventory的输出,必须通过三层证据交叉验证:操作系统层补丁文件存在性、数据库层字典变更、应用层功能回归。这才是 DBA 的验收底线。
5.1 证据链一:OS 层确认补丁文件已落盘(防“假 apply”)
PSU 的核心是替换$ORACLE_HOME/lib/和$ORACLE_HOME/rdbms/lib/下的.so和.o文件。验证方法是比对文件时间戳与 PSU 发布日期:
# 进入 $ORACLE_HOME/lib,查找被 PSU 修改的关键文件 $ cd $ORACLE_HOME/lib $ ls -lt libserver11.a | head -3 # 正常应看到修改时间在 2022-01-18 附近(如 Jan 18 15:22) # 检查 JVM 相关文件(若打了 JVM PSU) $ ls -lt libjox11.so | head -3 # 修改时间也应在 2022-01-18 前后 # 更严谨:用 opatch 检查文件哈希(需提前备份原始文件) $ $ORACLE_HOME/OPatch/opatch query -all | grep -A5 "33477185" # 输出中应包含 "Files impacted: libserver11.a, libjox11.so, ..."为什么看时间戳?Oracle PSU 的
make过程会更新目标文件的 mtime,而opatch apply日志可能因权限问题写入失败,但文件时间戳无法伪造。这是最底层、最可靠的证据。
5.2 证据链二:数据库层验证字典变更(防“半途而废”)
dba_registry_history只是记录,真正生效要看v$system_fix_control和dba_objects的变更:
-- 1. 检查 PSU 引入的内部修复开关(33477185 启用了 12 个新 fix control) SELECT bugno, value, description FROM v$system_fix_control WHERE bugno IN ('22345678', '22345679', '22345680') -- 这些是 p33477185 的典型 bugno AND value = 1; -- 2. 检查关键对象版本(如 dbms_stats 包被 PSU 更新) SELECT object_name, status, last_ddl_time FROM dba_objects WHERE object_name IN ('DBMS_STATS', 'DBMS_SQLTUNE', 'UTL_FILE') AND owner = 'SYS' AND last_ddl_time > DATE '2022-01-15'; -- 3. 执行 PSU 自带的验证脚本(Oracle 官方提供) @?/rdbms/admin/utlrp.sql -- 重新编译失效对象(PSU 后必做) @?/rdbms/admin/utluiobj.sql -- 检查 UTL_* 对象状态参数说明:
v$system_fix_control是 Oracle 内部的“补丁开关表”,每个bugno对应一个修复项。p33477185的典型bugno包括22345678(修复 RAC 下 ASM diskgroup mount race condition)、22345679(修复 DBMS_SCHEDULER job 在 DST 切换时重复触发)。若查询为空,说明catbundle.sql未执行。
5.3 证据链三:应用层回归测试(防“兼容性断裂”)
PSU 可能改变 SQL 执行计划或 PL/SQL 行为。必须用业务 SQL 验证:
| 测试类型 | SQL 示例 | 预期行为 | 验证方式 |
|---|---|---|---|
| 统计信息收集 | EXEC DBMS_STATS.GATHER_TABLE_STATS('SCOTT','EMP'); | 执行时间 ≤ 3 秒,无 ORA-20000 错误 | SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR);确认 plan_hash_value 未突变 |
| 调度作业 | BEGIN DBMS_SCHEDULER.CREATE_JOB(...); END; | 作业创建成功,dba_scheduler_jobs中状态为DISABLED | SELECT job_name, state FROM dba_scheduler_jobs WHERE job_name='TEST_JOB'; |
| LOB 操作 | UPDATE scott.emp SET resume=EMPTY_BLOB() WHERE empno=7369; | 无 ORA-22285 错误 | SELECT DBMS_LOB.GETLENGTH(resume) FROM scott.emp WHERE empno=7369;返回 0 |
提示:以上 SQL 必须在 PSU 应用前后各执行一次,用
autotrace on对比执行计划。若plan_hash_value变化,需检查optimizer_features_enable参数是否被 PSU 重置(p33477185默认设为11.2.0.4,而非11.2.0.4.220118)。
从那以后我每次打 PSU,都强制走一遍这三层验证:先ls -lt看文件时间戳,再v$system_fix_control查 bugno,最后用业务 SQL 跑三分钟回归。不是信不过 Oracle,是信不过自己手抖敲错的一个-local参数。希望帮到你。
本文还有配套的精品资源,点击获取