Oracle 11.2 Linux x86-64 下 OPatch 工具替换与补丁管理指南
工试云启 考证服务中心整理

简介p6880880_112000_Linux-x86-64是甲骨文公司发布的补丁安装工具包专门用于11g数据库在Linux 64位平台上的临时补丁维护。补丁包内置版本为11.2.0.3.15属于官方唯一支持的临时补丁安装方式既能完成一次性补丁的应用也会同步更新中央库存与产品库存使补丁记录准确可查使用时要求数据库主机的图形化安装工具OUI版本为11.2系列。压缩包共含877个文件除了补丁安装主程序与诊断脚本外还包含大量类库文件、配置信息、动态链接库、数据库脚本及执行脚本并预置了运行时所需的时区数据和数字证书整体体积约93.8兆压缩包内各类文件分工明确便于快速定位所需模块。目前已有352人学习下载适合负责11g环境运维的数据库管理员在补丁升级前核对或替换工具版本也适合初学者通过文件清单理解补丁安装的组成结构对库存登记机制也能建立直观印象。解压后即可作为补丁安装程序目录使用在官方流程中自动完成库存登记减少人工编辑带来的配置风险。1. p6880880_112000_Linux-x86-64这不是数据库补丁而是给 Oracle 换 OPatch 工具的压缩包p6880880_112000_Linux-x86-64.zip 这个名字容易让刚入行的 DBA 误以为是 Oracle 11.2 的某个月度补丁拿到手就想去 opatch apply结果被报错打懵。实际上 p6880880 是 Oracle 的 OPatch 工具升级包112000 表示针对 11.2.0.x 这条产品线Linux-x86-64 说明只能在 x86-64 架构的 Linux 服务器上用。它的作用是替换$ORACLE_HOME/OPatch整套补丁执行工具后续装 PSU、CPU 或单补丁时OPatch 版本不够会直接卡住。这篇笔记写给在 Linux x86-64 上维护 Oracle 11.2 的 DBA 和运维把「下载完不知道怎么办」带到「敢在生产库上安全替换并验证」。2. 动手前先搞清三件事OPatch 是干什么的为什么 11.2 的 p6880880 不能乱飞到 19c2.1 OPatch 是补丁的搬运工不是补丁本身一个完整的 Oracle 补丁安装动作最少牵扯三样东西补丁包、OPatch 工具、OUI Inventory。补丁包是数据库产品代码的增量文件OPatch 负责把改动落到$ORACLE_HOME的二进制目录里同时更新 inventory 里的记录。p6880880 这个包不带任何数据库代码它装完后发生变化的只是$ORACLE_HOME/OPatch/opatch这个工具本身以及它依赖的 jlib、docs 目录。你可以把 OPatch 理解成补丁发布体系里的执行层补丁包只描述差异工具负责把差异写到正确位置上。它要做的事包括检查正在运行的数据库进程、备份被替换的二进制、把新文件拷贝进去最后把 patch id 写入 inventory。这套动作里任何一步出错OPatch 都会把状态写进$ORACLE_HOME/cfgtoollogs/opatch/opatch.log所以排错第一步永远不是重新 apply而是先看日志再定位原因。如果把它当成普通补丁去 apply你会发现它既没有补丁号对应的说明也不会产生 inventory 里的补丁记录它属于工具链升级不是业务逻辑升级。理解这一层后面大部分报错都能对号入座不会在补丁列表里翻来翻去找 p6880880 的影子。2.2 112000 限定了产品线Linux-x86-64 限定了平台文件名拆开看每段都有明确限制。112000 是编码后的版本号展开就是 11.2.0.0.0所以它在 11.2.0.3、11.2.0.4 这类 11.2 老库上都能用它只认大版本不认某个特殊补丁号。Linux-x86-64 则是平台标识说明这个包只服务 x86_64 Linux和 Solaris、AIX、HP-UX、macOS甚至 Linux on aarch64 都不通用。文件名片段含义p6880880OPatch 工具对应的补丁号不是数据库 bug 补丁112000目标产品线是 11.2.0.x其他大版本不要混用Linux-x86-64平台限定换平台必须重新下载对应包同叫 p6880880不同大版本下载下来的压缩包内部脚本和 jar 版本不完全一致。我见过有人拿 12c 的工具包去补 11.2 老库结果 opatch 启动直接报 Java 类找不到这类问题不属于环境玄学就是版本错配。想跨平台或者跨大版本使用下标前先仔细看文件名尾巴不要只认 p6880880 这个数字。下载文件还要看完整名称。Oracle 补丁下载页会把同 patch 号不同平台列在一起文件名末尾的 AIX、Solaris 容易被粗心的人忽略。Linux 运维里最典型的翻车就是下回来一个平台不符的包解压后 opatch 脚本能看一执行就报语法错或者启动不了最后只能回到下载页重新选。2.3 替换前必须先确认的 Inventory 和 ORACLE_HOMEOPatch 是强环境依赖的 Java 工具它要先用/etc/oraInst.loc里的 inventory_loc 找到 Oracle Universal Inventory再结合ORACLE_HOME判断该给哪个数据库目录做操作。很多新 DBA 换完 OPatch 后照样报 Cannot get OUI inventory问题通常出在这两个前置条件上而不是新工具坏了。替换前我会按顺序跑下面几行命令每条输出都要核对而不是一把梭whoami echo $ORACLE_HOME ls -ld $ORACLE_HOME/OPatch cat /etc/oraInst.loc $ORACLE_HOME/OPatch/opatch version命令本身都很短但要核对的内容不少whoami返回 oracle 而不是 root。root 执行 OPatch 时权限模型容易乱写入 inventory 的文件属主会变成 root后续 oracle 用户直接无法操作。echo $ORACLE_HOME不能为空。为空说明当前会话还没切环境后面即使找到 opatch 也拿不到目标库。ls -ld $ORACLE_HOME/OPatch看属主和权限。11.2 老库上通常属主是 oracle组是 oinstall目录权限是 775。cat /etc/oraInst.loc输出的两个键inventory_loc 是 inventory 物理路径inst_group 是 OUI 的组名两个都要存在且与当前环境匹配。最后opatch version能正常打印版本号才说明现有工具链和环境是通的可以放心替换。如果最后一行 opatch version 都报错不要继续往下走。把输出贴出来逐行读多半是 java 路径或者 inventory 指向的问题。另外同一台机器上多套 ORACLE_HOME 时绝不能靠ORACLE_SID来定位环境OPatch 只看 ORACLE_HOME不关心你连的是哪个实例。谁替哪套库打补丁就先把哪套 ORACLE_HOME export 到当前会话。3. 替换 OPatch 的标准步骤备份、解压、权限、PATH一条条来3.1 先解到临时目录并测试压缩包完整性拿到文件后我从来不会直接 unzip 到$ORACLE_HOME。第一次可能权限不够第二次可能覆盖到一半第三次发现老版本已经没了。稳妥做法是先进/tmp做完整性检查再解到独立 staging 目录。cd /tmp ls -lh p6880880_112000_Linux-x86-64.zip unzip -t p6880880_112000_Linux-x86-64.zip mkdir -p /tmp/opatch_stage unzip -o p6880880_112000_Linux-x86-64.zip -d /tmp/opatch_stage find /tmp/opatch_stage -maxdepth 2 -type f | head -20unzip -t只测试 zip 的 CRC 完整性不落盘-d指定解压目录-o是为了重复执行时不交互。解出来的顶层一般是OPatch目录里面有 opatch 脚本、jlib、docs 等。如果这台 Linux 是最小化安装没有 unzip可以改用python3 -m zipfile -e p6880880_112000_Linux-x86-64.zip /tmp/opatch_stage效果一样。提示不要用 root 解压到 oracle 的目录后面属主修复很容易漏也不要把 staging 建在$ORACLE_HOME里那样会把不属于数据库的目录混进安装根目录巡检脚本扫到会误报。3.2 老 OPatch 改名备份新 OPatch 整体拷贝替换前必须给老工具留后路。我习惯用 mv 先把老目录挪走而不是 rm回滚时只需要把备份目录改回来。备份名带上日期避免一个月后不知道里面是什么。TS$(date %Y%m%d) mv $ORACLE_HOME/OPatch $ORACLE_HOME/OPatch.bak.$TS cp -r /tmp/opatch_stage/OPatch $ORACLE_HOME/OPatch ls -l $ORACLE_HOME/OPatch/opatchmv 在同一文件系统内只是元数据改名速度快而且不会因为目标目录已有内容而报错cp -r 把 staging 里的整套目录复制进 dbhome。复制完成后先看的不是版本号而是 opatch 脚本在不在、有没有执行权限。cp 一旦中断新目录会只写一半这时候不要凑合直接删掉新目录把备份目录 mv 回来重来一遍。用 oracle 用户执行 cp属主一般就是 oracle:oinstall如果多用户共用这台主机建议继续做下一步别省略。备份目录保留在同一盘里不要丢到/tmp重启后/tmp被清空回滚后悔药就没了。3.3 校准属主与执行权限别用 777OPatch 挂在$ORACLE_HOME下权限模型要跟数据库二进制保持一致否则 OUI 在 inventory 校验时会认为目录不可信。常见做法是属主 oracle、组 oinstall目录 775普通文件 664只有 opatch 主脚本额外加执行位。chown -R oracle:oinstall $ORACLE_HOME/OPatch find $ORACLE_HOME/OPatch -type d -exec chmod 775 {} \; find $ORACLE_HOME/OPatch -type f -exec chmod 664 {} \; chmod 755 $ORACLE_HOME/OPatch/opatchfind -exec是为了不依赖手工逐个修改目录和文件分开处理这样不会把 jar 变成可执行文件。chmod 755 只给 opatch 主脚本不要对 jlib 下的 jar 加执行位。如果 oinstall 组名和你机器上不一致以/etc/oraInst.loc里inst_group显示的值为准不要照抄这套例子里的组名。改了属主之后不要顺手把整个$ORACLE_HOME再做一次 chown那会把意外改过的其他目录一并覆盖。收窄到 OPatch 这一个目录就够了。3.4 设置 PATH 和 JAVA再用 opatch version 验证OPatch 是 Java 程序它默认会去$ORACLE_HOME/jdk/bin下找 java。11.2 环境里这个目录通常存在如果机器上装了别的 JDK就要显式把 JAVA 相关变量导出避免调用到不兼容版本。export ORACLE_HOME/u01/app/oracle/product/11.2.0/dbhome_1 export PATH$ORACLE_HOME/OPatch:$PATH export JAVA_HOME$ORACLE_HOME/jdk export PATH$JAVA_HOME/bin:$PATH opatch version把 OPatch 放在 PATH 最前面是为了保证在操作台输入 opatch 时调用的就是新工具不是系统里残留的旧版本。opatch version 的输出形如 OPatch Version: 11.2.0.3.x这个数字只需要比你要打的补丁 README 里要求的高并不是越高越好。如果这条命令带出 Java 相关异常先跑$ORACLE_HOME/jdk/bin/java -version再看JAVA_HOME是否指错老库当年只装了 jre 时把这个变量指到$ORACLE_HOME/jre也能凑合跑通。4. 装完 OPatch 只是开始用 lsinventory、冲突预检和空跑把补丁链路验通4.1 opatch version 之后先看 lsinventory替换完成后有人直接拿正式补丁去 apply跑到一半才报错。正确的顺序是先做一次 inventory 探活让 OPatch 把整个环境扫描一遍。lsinventory 负责读取 inventory 并列出已安装补丁这步能暴露大部分目录、权限和 inventory 损坏问题。$ORACLE_HOME/OPatch/opatch lsinventory -oh $ORACLE_HOME-oh显式指定 ORACLE_HOME避免脚本里环境变量在 subshell 中被吞掉。输出先显示 Oracle Home、Inventory 位置然后是已安装的 top-level patches如果之前打过 PSU再打一个同目录的 CPU冲突点会在这里先冒出来。只要这条命令不报错就说明新 OPatch 能正确对接当前 inventory一旦这里出现 Cannot get OUI inventory不要继续回到 2.3 重新核对/etc/oraInst.loc和ORACLE_HOME。同时要看日志末尾有没有 missing patches 或者 pending transaction 字样。有 pending 说明上一次补丁没打完必须先清掉残留事务否则这次 apply 会接着出错。lsinventory 不是例行公事它是环境健康度的一次快照。4.2 拿目标 PSU/CPU 做冲突预检OPatch 升级完成不等于任何补丁都能直接打。目标补丁包的 README 通常会要求先跑 prereq最常见的检查项是CheckConflictAgainstOHWithDetail用于确认目标补丁和当前已装补丁有没有文件冲突。这个动作不修改 inventory失败也不伤现有环境属于低成本高回报的好习惯。$ORACLE_HOME/OPatch/opatch prereq CheckConflictAgainstOHWithDetail \ -oh $ORACLE_HOME \ -ph /u01/patch/psu_20250401/12345678-ph指向的是解压后的补丁目录不是压缩包也不是补丁号本身。常见误用是把补丁号直接写在-ph后面OPatch 会报 not a valid patch location。正确做法一般是补丁目录以补丁号作为最里层目录名外层是补丁集合目录。输出里有 No conflict 或者检查通过就可以继续往下如果有 conflict说明目标补丁与 inventory 里的已装补丁相互覆盖需要先处理旧补丁或改成合并补丁集。很多运维跳过的这一步恰恰能在 apply 之前发现八成失败场景。Linux 运维故障案例里那些打到一半才回滚的现场大多数早就在 prereq 里给过提醒只是没人跑。4.3 用空跑验证正式应用链路prereq 只做静态检查正式 apply 还会执行文件替换、备份、inventory 更新。要提前验证这套动作可以在 apply 或 napply 后面加-dryRun。这个开关会走完整流程但不会真实写入文件和 inventory是补丁发布前最扎实的后悔药。cd $ORACLE_HOME/OPatch ./opatch napply -oh $ORACLE_HOME -ph /u01/patch/psu_20250401/12345678 -dryRunnapply 适合一次处理一个或一批补丁-dryRun让它预测完就停住。老版本 OPatch 对开关名有差异执行前先跑opatch apply -help看输出里有没有 DryRun 字样。空跑日志在$ORACLE_HOME/cfgtoollogs/opatch/opatch.log先定位 Invoking prereq 之后的段落前面的环境信息只是背景。dryRun 成功后日志里会出现完整 apply plan包括要替换的文件数量拿这个数量去和 README 核验章节对一下对得上再正式打。对生产库我还会在 dryRun 后顺手跑一次lsnrctl status确认监听没被扫描动作弄脏。这一步看起来多余实际能拦住那些准备阶段乱重启服务的操作。4.4 不要把 p6880880 当数据库补丁直接 apply和上面相反的误用也常见有人把 p6880880 下载好放到某个目录执行 opatch apply期望打出新 OPatch。这在逻辑上就不通。p6880880 的安装方式是替换$ORACLE_HOME/OPatch也就是刚才的 mv/cp 流程它不经过 apply也不会出现在 lsinventory 的补丁列表里。它的产物只体现在 opatch version 输出中。判断工具升级成功与否只看版本号不看补丁记录。顺手给团队文档里记一句替换后的 OPatch 版本要同步写进变更表下次排障看到版本号和记录不一致就会优先怀疑环境串了。5. OPatch 避坑指南5 个让运维翻车的现场与排查5.1 现象opatch 报错 Cannot get OUI inventory现象替换后运行opatch version正常但一跑opatch lsinventory就报无法定位 inventory。原因多数是ORACLE_HOME没有 export或者/etc/oraInst.loc里的 inventory_loc 指向了别的数据库安装目录。解决先echo $ORACLE_HOME再cat /etc/oraInst.loc确认 inventory_loc 和当前 ORACLE_HOME 属于同一套环境。多套库共用一台机器时最容易把两个配置串起来。5.2 现象PSU 安装报 OPatch version 低于要求现象补丁 README 写需要 OPatch 11.2.0.3.x你也替换了 p6880880但 apply 时仍报版本不够。原因通常是 shell 的 PATH 还指向系统目录里的旧 opatch或者替换后没有重新登录环境变量没有拉走。解决export PATH$ORACLE_HOME/OPatch:$PATH再跑opatch version和which opatch确认输入的命令来自$ORACLE_HOME/OPatch不是/usr/bin下的残留。5.3 现象解压时报 disk full 或空间不足现象unzip 到一半报 No space left on device明明/tmp看起来还有空间。原因是/tmp和$ORACLE_HOME可能是不同文件系统zip 解压一份、cp -r 又一份实际占用了两倍磁盘。解决先df -h /tmp和df -h $ORACLE_HOME把 staging 建在空间大的一侧解压完成后确认OPatch目录完整再删掉 zip 和 staging避免一个月后磁盘悄悄变满。5.4 现象opatch 起不来报 Java 类找不到现象替换后执行 opatch输出一串 class not found 或 NoClassDefFoundError。原因多半是$ORACLE_HOME/jdk/bin/java丢失或者环境变量里挂了一个高版本 JDK和 OPatch 自带的 jlib 不兼容。解决先$ORACLE_HOME/jdk/bin/java -version能用就把JAVA_HOME显式指到这个目录再用绝对路径$ORACLE_HOME/OPatch/opatch version测试。不要同时让多个 Java 版本混在 PATH 里opatch 会优先抓到第一个。5.5 现象回滚时发现老 OPatch 备份被删现象新 OPatch 有问题想回到旧版发现备份目录没了或者备份放在/tmp已被重启清理。原因是替换时用了 rm或者备份位置选错。解决替换前用mv $ORACLE_HOME/OPatch $ORACLE_HOME/OPatch.bak.$TS保留同盘副本回滚时mv $ORACLE_HOME/OPatch.bak.$TS $ORACLE_HOME/OPatch就能恢复。老工具替换这类操作备份最容易忽略但也是回滚成本最低的一环。6. 进阶把 OPatch 版本检查写进 Linux 巡检脚本给补丁发布前留一手每次发补丁前我习惯先跑一个固定脚本把 OPatch 版本、inventory 状态、权限一次看完而不是手工敲命令。脚本很朴素胜在能避免临场漏项#!/usr/bin/env bash export ORACLE_HOME/u01/app/oracle/product/11.2.0/dbhome_1 OP$ORACLE_HOME/OPatch/opatch if [ ! -x $OP ]; then echo [FAIL] OPatch 不存在或无执行权限 exit 1 fi $OP version $OP lsinventory -oh $ORACLE_HOME /tmp/opatch_inv_$(date %F).log 21 tail -20 /tmp/opatch_inv_$(date %F).log脚本先判断 opatch 可执行再打版本最后把 inventory 输出留到日志文件我还会顺手 grep 日志里有没有 pending transaction 和 missing patches 之类标志确认没有残留未完成事务。这个脚本可以直接丢进 cron 做周巡检补丁发布前再手动跑一次。以前我因为偷懒跳过 OPatch 版本检查生产补丁窗口被白费过一次从那以后每次发布都先跑这套检查。希望帮到你。本文还有配套的精品资源点击获取