多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

Oracle 11g OPatch补丁工具p6880880替换与数据库补丁应用实战

Oracle 11g OPatch补丁工具p6880880替换与数据库补丁应用实战 简介面向Oracle 11g数据库环境运维人员p6880880_112000_Linux-x86-64.zip是官方OPatch 11.2.0.3.15补丁安装工具专用于在OUI 11.2.*的Oracle主目录中安装一次性临时补丁支持Linux x86-64平台。作为Oracle唯一受支持的临时补丁安装方式该工具会同步更新中央与产品清单中的补丁记录。压缩包共877个文件约93.8MB核心由jar主程序、properties配置、so动态链接库与sh自动化脚本组成另含大量Java运行时所需的时区数据文件及说明文档目录结构清晰。目前已有352人学习/下载适合需要升级或维护Oracle补丁体系的数据库管理员参考。解压后可直接替换或升级旧版OPatch需提前备份旧版本内置README明确了OPatch对临时补丁的安装机制与适用范围便于快速核查当前Oracle Home的OUI版本降低打补丁时的操作风险也可作为团队内部统一OPatch版本的标准化交付物。1. p6880880 是什么Oracle 11g 补丁工具包在 Linux x86-64 上的定位p6880880_112000_Linux-x86-64 这个名字第一次出现时多数人会误以为它是一个数据库补丁。实际上它是 Oracle 11g 在 Linux x86-64 平台上的 OPatch 工具补丁包作用是把环境里的 OPatch 本体升级到能支持新补丁格式的版本。我接手旧库时第一步做的事往往不是 apply 数据库补丁而是先替换这套工具否则后续动作全部卡在版本检查上。OPatch 长期不更新属于典型的隐性负债等真打补丁那天才暴露。这篇笔记围绕这套包讲清楚它解决什么问题、怎么装、怎么用来打 11g 补丁以及我踩过的几个坑。2. 安装替换 OPatch从解压 zip 到 opatch version 通过的手工流程2.1 为什么 11g 的补丁工具需要单独“打补丁”Oracle 11g 安装完成后$ORACLE_HOME/OPatch 目录下会存在一个随数据库安装附带的基础版本工具。这个工具负责解析补丁包、备份被覆盖文件、读写补丁清单相当于整套补丁体系里的管家。随着时间推移新发布的补丁包对管家自身的能力要求会逐步提高最典型的就是补丁描述文件的格式升级。旧版 OPatch 解析不了新的 patch.xml 或 bundle.xml会在 prereq 预检阶段直接返回类似“OPatch version is older than required for this patch set”的提示数据库补丁根本没机会进入 apply 流程。另一个容易被忽视的原因是 inventory 读写格式的变化。OPatch 需要通过一组动态库去读取本机的 oraInventory这套清单文件记录了数据库装过哪些组件、打过哪些补丁。新补丁的清单格式如果加入了新的字段或版本号规则旧工具就会在读取阶段报错或者读出一个错误的结果。所以升级 OPatch 不是可做可不做的优化项而是“不升级就打不动新补丁”的硬依赖。文件名里的 112000 表示这套工具适配 11.2.x 系列Linux-x86-64 是平台限定下载时这三个信息要对应上。因为它是工具本身的升级包安装方式与普通数据库补丁不同不需要执行 apply而是解压后整体替换 $ORACLE_HOME/OPatch 目录。替换完成后还要确认工具能正常读取 inventory才算真正安装成功。很多人只做了文件替换忽略后续验证结果到 apply 阶段才被环境变量或 inventory 问题卡住。2.2 解压与替换备份、授权、环境变量一条龙安装 p6880880 的第一步是把它放到一个干净的临时目录比如 /u01/software然后校验完整性再解压。不要直接解压到 $ORACLE_HOME/OPatch 里因为 zip 包第一层目录本身就是 OPatch直接解压会产生目录嵌套后面替换时容易留下半套混合版本。我习惯于先独立解压到临时目录确认内容完整后再针对 ORACLE_HOME 做替换。# 1. 使用 oracle 用户登录校验并解压 mkdir -p /u01/software/opatch_pkg cd /u01/software/opatch_pkg md5sum p6880880_112000_Linux-x86-64.zip unzip -q p6880880_112000_Linux-x86-64.zip ls -l OPatch/opatch逻辑说明md5sum 用于校验下载包是否完整比对结果不是官方给的值就不要继续避免解压出一套半残工具。unzip -q 是静默解压解压后第一层出现的 OPatch 目录里必须有 opatch 可执行脚本如果这个文件缺失通常说明 zip 包在网络传输中损坏或者包本身对应平台不对。检查这一步花不了一分钟但能省掉后续排查的时间。接下来是替换环节。替换 OPatch 工具本身不需要停机它只在命令行被调用不会像数据库共享库那样被进程长期占用。但替换动作要保守生产环境里必须留后悔药。我一般不会直接 rm 旧目录而是先把它改名成带日期的备份目录等确认新工具能正常运行之后再考虑清理。# 2. 备份旧工具目录再替换新工具 mv $ORACLE_HOME/OPatch $ORACLE_HOME/OPatch.bak.$(date %Y%m%d) cp -r /u01/software/opatch_pkg/OPatch $ORACLE_HOME/OPatch chown -R oracle:oinstall $ORACLE_HOME/OPatch chmod -R 755 $ORACLE_HOME/OPatch # 3. 验证替换后的工具版本 $ORACLE_HOME/OPatch/opatch version逻辑说明mv 改名只动目录项速度快而且不会触发跨分区的数据复制cp -r 才把新工具真正放进 ORACLE_HOME。chown 和 chmod 这两条命令是为了防止前面用 root 解压导致文件属主错乱这在 Linux 系统管理里是常见问题尤其多人共用的服务器上很容易出现。opatch version 的输出里除了显示 OPatch 版本号还会附带识别出的 Oracle Home 路径看到那段路径与当前环境一致说明工具已经认对了位置。参数说明命令里的 $ORACLE_HOME 必须已经生效。如果 echo $ORACLE_HOME 输出为空说明当前用户的环境变量没有加载先去检查 .bash_profile。我习惯把一套 Oracle 环境变量固化在系统用户的配置文件里而不是每次手动 export。PATH 里要带上 $ORACLE_HOME/OPatch这样后续直接敲 opatch 即可执行命令更短也更符合多数文档里的写法。环境变量这块可以顺带做个自查# 4. 检查当前用户、ORACLE_HOME、ORACLE_SID 是否就位 id echo ORACLE_HOME$ORACLE_HOME echo ORACLE_SID$ORACLE_SID which opatch逻辑说明id 确认当前用户是 oracle避免用错了身份去操作后续命令。ORACLE_HOME 与 ORACLE_SID 的值为空时后面所有步骤都会出问题这里提前暴露比到 apply 阶段再报错要好。which opatch 能确认命令搜索路径里已经包含了 OPatch 工具目录。参数说明如果你在几台机器之间切换建议在每台机器的环境配置文件里显式写好各自的路径不要复制同一套配置到所有机器。11g 环境常见的 ORACLE_HOME 路径形如 /u01/app/oracle/product/11.2.0/dbhome_1注意一台机器可能同时存在多个 ORACLE_HOME尤其在装了 RAC 或同时跑多个版本的环境里必须确认当前补丁操作针对的是哪一个库。2.3 验证安装inventory 与 opatch lsinventory 的解读文件替换只是工具层面的到位OPatch 能不能正常工作取决于它能否读取本机的补丁清单。Oracle 的补丁清单分为两部分中央清单目录通常位于 $ORACLE_BASE/../oraInventory 或者 /u01/app/oraInventory而每个 ORACLE_HOME 下还有自己的 inventory/ContentsXML 目录。opatch 启动时先定位 oraInventory再读取组件与补丁记录。如果这两部分有任何不一致lsinventory 命令就会直接失败。# 5. 验证工具能否读到补丁清单 $ORACLE_HOME/OPatch/opatch lsinventory # 6. 保存基线输出供打补丁后做 diff $ORACLE_HOME/OPatch/opatch lsinventory /u01/software/opatch_before_$(date %Y%m%d).log逻辑说明lsinventory 输出里重点看三行内容Oracle Home 路径必须与当前环境一致OPatch version 必须与刚才 opatch version 输出一致Installed Top-level Products 区域会列出已安装的组件版本比如 Oracle Database 11.2.0.4.0。三行都正常说明工具已经接管了本机的补丁清单。第 6 条命令把这份清单存成基线文件后续打完补丁再跑一次同样命令做 diff能直观看到新增了哪些补丁、更新了哪些组件。参数说明lsinventory 不带任何参数时默认列出全部信息在输出量大的环境里可以用 lsinventory -detail 或 -bugs_fixed 来做定向查询可控性更好。保存基线时文件名里带日期避免以后的变更覆盖历史记录这是我的长期习惯。3. 用 OPatch 打补丁apply、冲突检查与回滚命令实战3.1 打补丁前三个必查项prereq、版本、磁盘拿到一个正式的数据库补丁包之后在 apply 之前有三个项目我每次都强制走一遍缺一个都不动手。第一是确认当前 OPatch 版本满足补丁说明里的最低要求第二是把补丁包自带的 prereq 预检跑通第三是确认 ORACLE_HOME 所在分区有足够的剩余空间。这三个问题最容易把 apply 过程卡在中途一旦失败inventory 状态会变得非常别扭恢复起来比第一次打补丁麻烦得多。# 7. 检查补丁冲突与前置条件只读不修改 cd $ORACLE_HOME/OPatch ./opatch prereq CheckConflictAmongPatches -ph /u01/software/patch/12345678 ./opatch prereq CheckApplicable -ph /u01/software/patch/12345678 # 8. 查看 ORACLE_HOME 所在分区剩余空间 df -h $ORACLE_HOME逻辑说明prereq 的两个子命令都是只读检查不会对系统做任何修改。CheckConflictAmongPatches 检查新补丁与已应用补丁之间有没有文件或代码层面的重叠冲突CheckApplicable 检查这个补丁是否能应用到当前版本的数据库上。两条命令都返回成功或 No conflict 才是安全的前置状态。df -h 用来确认剩余空间我一般要求至少 2GB 以上有些大补丁会在 backout 目录里保留大量被替换文件的副本空间不足会在 apply 中后期才暴露此时收尾很费劲。参数说明-ph 后面跟的是补丁解压后的完整路径不是 zip 文件路径。补丁包同样要先解压到独立目录目录名通常就是补丁号本身。示例里的 12345678 只是演示编号实际要以你下载到的补丁号为准。要注意平台对应Linux x86-64 的机器上不要混入其他平台的补丁包解压时系统不会报错但 prereq 阶段会失败。3.2 apply 与 rollback 的完整命令序列prereq 通过后进入正式应用阶段。Oracle 11g 的 in-place 补丁要求数据库实例处于关闭状态这是硬性条件。如果库还在运行补丁脚本替换共享库时会遇到文件占用轻则补丁失败重则留下一个文件版本不一致的半套环境。我一般先停监听再停实例顺序不要反。停监听是为了避免新连接在打补丁过程中被创建实例 shutdown 则保证所有后台进程退干净。# 9. 补丁窗口内关闭监听与实例 lsnrctl stop sqlplus / as sysdba EOF shutdown immediate; exit; EOF # 10. 应用数据库补丁 cd $ORACLE_HOME/OPatch ./opatch apply /u01/software/patch/12345678 -silent逻辑说明shutdown immediate 会回滚未提交事务并断开活动连接是生产环境最常用的关闭方式比 abort 温和得多。apply 命令把补丁内容写入 ORACLE_HOME并同步更新补丁清单。silent 模式跳过交互式确认按默认值执行适合变更窗口内脚本化运行。命令执行结束后要看到结尾处明确的 “OPatch succeeded” 字样这一条才算成功。参数说明apply 后面可以直接跟补丁解压目录也可以先 cd 到目录里再执行效果相同。silent 模式在 Linux x86-64 平台上是标准动作它会把日志写到 $ORACLE_HOME/cfgtoollogs/opatch 下文件名带时间戳。如果补丁说明里要求特殊参数比如 -skip_subset 或者 -rollback_reboot严格按照补丁配套的说明来加不要从网上照搬一套参数。打补丁不是不能后悔回滚路径同样走 OPatch。回滚时工具会读取打补丁时留下的备份文件把被覆盖的旧版本恢复回去。# 11. 需要回滚时按补丁号执行 cd $ORACLE_HOME/OPatch ./opatch rollback -id 12345678逻辑说明rollback 依赖打补丁时自动生成的 backout 文件这些文件通常存放在 ORACLE_HOME 的临时目录或 OPatch 自带的 backup 路径下。因此打补丁后不要轻易清理这类目录一旦删掉回滚就失去了依据。rollback 同样要求数据库处于关闭状态操作逻辑与 apply 一致。参数说明-id 后面是补丁号不是任意字符串。如果一个 bundle 补丁包含多个子补丁回滚时可能要先回滚子补丁再回滚主补丁顺序错误会导致依赖检测无法通过。拿不准时先跑 lsinventory 看清单顺序再做回滚动作。3.3 从 lsinventory 与数据字典确认补丁生效apply 成功不代表补丁一定生效了。OPatch 的 succeeded 只表示文件替换和清单更新完成数据库内部注册记录的更新是另一回事。这里我习惯做两层验证工具层看 lsinventory 与补丁修复的 bug 列表数据库层查数据字典里的补丁历史。两层都确认过变更才算闭环。# 12. 检查已应用补丁与修复清单 opatch lsinventory opatch lsinventory -bugs_fixed | grep 12345678 # 13. 数据库内部确认补丁历史 sqlplus / as sysdba EOF select TO_CHAR(action_time, YYYY-MM-DD HH24:MI) action_time, action, version, comments from dba_registry_history order by action_time; EOF逻辑说明lsinventory 输出中的已应用补丁列表能看到该补丁编号-bugs_fixed 则会列出这个补丁所修复的 bug 项。数据字典查询看的是 dba_registry_history这是一张记录数据库补丁动作的审计表包含动作时间、动作类型、版本号和说明信息。如果表里出现了对应时间与补丁说明的记录说明补丁已经进入数据库内核的注册信息不只是文件层面的替换。参数说明11.2 环境里 dba_registry_history 是可靠的验证来源12c 及以上还可以查 dba_registry_sqlpatch但 11g 上没有这个视图不要去搜一个不存在的对象。查询结果按 action_time 排序能看出补丁的先后顺序这也可以用于确认回滚顺序是否正确。4. 避坑清单OPatch 翻车现场与排查顺序这一章我把自己实际遇到的翻车场景按现象、原因、解决整理成下面的清单基本覆盖了 p6880880 替换和 11g 补丁应用中最容易踩中的五类问题。4.1 权限错乱解压后 opatch 报 Permission denied现象用 root 用户解压完 p6880880 后切回 oracle 用户执行 opatch version直接提示 Permission denied或者脚本执行到一半报无法创建临时文件。原因zip 包被 root 解压文件属主全部是 rootoracle 用户没有执行和写入权限。这个问题在 Linux 系统管理里很常见文件在但不代表当前用户能用。解决统一修正属主和权限再重新验证。执行 chown -R oracle:oinstall $ORACLE_HOME/OPatch 之后再用 chmod -R 755 补一遍执行权限。这里提醒一下chmod 755 会去掉组和其他用户的写权限OPatch 运行过程中需要写临时文件和 backout 文件属主要确认 oracle 用户自己能写否则后续 apply 还会报权限问题。4.2 inventory 报错无法加载补丁清单现象替换工具后执行 opatch lsinventory输出中直接出现 “Unable to load the inventory” 或 “OUI inventory is not initialized properly”整个命令在启动阶段就中断。原因oraInventory 目录损坏、位置被移动或者工具版本与 inventory 格式不匹配。有些环境里 ORACLE_HOME/inventory/ContentsXML/oui-patch.xml 文件被手工改过或误删也会触发这个报错。解决先检查 oraInventory 目录是否存在并且属主正确。然后打开 oui-patch.xml确认里面记录的本机补丁条目与当前系统一致。如果目录还在但内容乱掉可以考虑重建中央清单但重建属于变更较大的操作务必先备份原目录。日常运维里更要留意的是不要在机器上随意移动或删除 /u01/app/oraInventory 这类路径。4.3 补丁不适用版本与平台都对不上现象apply 执行到 prereq 阶段直接失败提示补丁不可应用检查补丁对应版本时才发现 11.2.0.1 的环境用了要求 11.2.0.4 的补丁包。原因数据库小版本与补丁要求不匹配。11g 的补丁通常按小版本区分比如 11.2.0.4 的补丁不能直接打在 11.2.0.1 上。解决先确认当前数据库版本。常用的做法是登录数据库执行 select version from v$instance或者查看补丁包内的 etc/config 文件文件里明确写清了适用于哪些基版本。如果不匹配需要先把数据库升级到补丁要求的基版本再重新走 apply 流程。平台文件也要顺带核对Linux x86-64 的包不能用在其他架构上。4.4 动态库被占用apply 中途失败现象apply 执行到替换动态库阶段日志中出现类似 “libclntsh.so.11.1: cannot open shared object file” 的错误命令中断。原因数据库实例或监听没有完全关闭后台进程仍然持有 ORACLE_HOME 下动态库文件的句柄。补丁需要覆盖这些文件时系统层面无法完成替换。解决停止一切占用 ORACLE_HOME 下文件的进程。先 lsnrctl status 确认监听已停再用 ps -ef | grep ora_ 查看实例进程是否全部退出。如果确认还有残留进程检查是哪个后台进程再决定处理方式不要盲目 kill 系统核心进程。环境干净后先执行一次 rollback 清理残留状态再重新 apply。4.5 回滚顺序混乱二次补丁后回滚出错现象打完一个补丁后又应用了另一个有依赖关系的补丁后续发现第一个补丁有问题想单独回滚rollback 时报依赖冲突无法执行。原因补丁之间存在先后依赖单独回滚位于依赖链底部的补丁上层补丁的完整性会被破坏OPatch 检测到这种关系后拒绝执行。解决先从 lsinventory 里查看所有已应用补丁的应用时间按“后打先回”的顺序逐条回滚。每次 rollback 前重新跑一遍 prereq 检查确认当前清单状态允许这次回滚。回滚到目标补丁之前的状态后再按原计划处理问题而不是强行跳过依赖关系。5. 验证补丁真生效三个不靠看的硬核检查法5.1 基线 diff让补丁前后的变化一目了然替换 OPatch 并打完数据库补丁后最直观的验证手段是把新清单和旧基线做一次 diff。这个动作我已经养成习惯每次在 /u01/software 下保存一份带日期的基线文件打补丁后重新生成一份清单做对比。# 14. 对比补丁前后清单变化 cd /u01/software opatch lsinventory opatch_after_$(date %Y%m%d).log diff opatch_before_$(date %Y%m%d).log opatch_after_$(date %Y%m%d).log逻辑说明diff 输出中会明确显示新增的补丁编号和组件版本变化几秒钟就能看出这次补丁到底改动了什么。如果 diff 结果为空说明补丁没有真正进入清单需要回到 apply 阶段排查。这个方法比肉眼翻日志快得多也避免了遗漏次要补丁。5.2 数据字典与回归验证从应用层看结果清单对比通过后我还会进数据库查一次 dba_registry_history确认补丁记录已经写入内部注册信息。这一步的意义在于有些文件层面的补齐并不代表数据库内核已经感知两套记录都存在变更才完整。如果有条件再针对补丁涵盖的问题场景做一轮针对性回归比如补丁修复的是某类 SQL 执行计划问题就找出对应的 SQL 场景跑一遍看行为是否有变化。这种回归验证用不了多少时间但能把验证从“工具说成功”推进到“应用说正常”。从那以后我每次在 11g 上动补丁都会把工具替换、prereq 预检、基线 diff 三步强制走一遍确认工具版本正确且清单可读才开始 apply不再凭输出末尾的 succeeded 字样判断一切正常。希望帮到你。本文还有配套的精品资源点击获取
返回列表