资讯动态

Oracle 11.2.0.1补丁安装:OPatch、补丁排序与回滚

发布时间:2026/10/27 19:54:34 来源:尧图企业网站定制
简介这份DOC文档面向需要为Oracle 11.2.0.1数据库安装补丁的DBA、运维人员及数据库学习者聚焦补丁实施前的环境确认与备份提醒、OPatch工具使用、数字补丁按序应用和安装后验证等关键环节帮助读者建立清晰、可对照的补丁管理流程。压缩包内仅含1个doc文件大小约942KB以文字说明为主线将命令示例、成功标志判断、维护记录建议以及异常情况下的查看与回滚思路集中在一份文档中便于离线查阅和现场参考。文档内容紧凑适合按补丁实施阶段查阅对补丁编号差异、安装后服务状态确认等细节也有交代也可作为数据库维护记录和交接资料的补充。已有131人学习。读者可从中获得补丁安装的整体路径、常见问题的排查方向与操作注意事项尤其适合刚接触Oracle补丁管理、需要快速上手并降低误操作风险的技术人员参考。1. 11.2.0.1 打补丁这件事先分清 OPatch、补丁号和关库顺序有人把给数据库打补丁想成“解压、双击、重启”三步真到 Oracle 11.2.0.1 这种老库上就会知道出问题的地方从来不在opatch apply那一下而在前面的 OPatch 版本、补丁编号顺序和实例有没有关干净。这份文档记录的是 Windows 平台上给 11.2.0.1 打补丁的完整路径把 OPatch 解压到ORACLE_HOME、set 环境变量、进补丁目录执行opatch apply、多个补丁按编号从小到大逐个打、最后重启服务器让服务自启。它解决的是老版本数据库长期不更新、已知缺陷堆着没人敢动的问题。适合手上还挂着 11.2.0.1 的 DBA、要按变更窗口做加固的运维也适合第一次独立打补丁、想照着走完一遍的人。补丁本身不复杂复杂的是边界条件下面按动手顺序拆开讲。2. 动手前把底子铺好OPatch 版本核对、备份清单与关库确认补丁打不打得进去七成取决于这一步。我见过太多人上来就opatch apply报了一屏错再回头补环境最后连原来的 OPatch 都被覆盖坏了。这一章把三个前置条件逐一落实OPatch 放对位置、该备的东西备齐、实例确实停干净。2.1 OPatch 为什么必须解压到 ORACLE_HOME 下OPatch 本体是一组 Java 类和批处理脚本它启动后第一件事是读环境变量ORACLE_HOME然后去%ORACLE_HOME%\.patch_storage和 central inventoryinventory.xml里核对这个 Home 注册了哪些补丁、当前装了哪些组件。你把 OPatch 解压到 D 盘某个临时目录再跑它照样能启动但找不到 inventory 就会停下来典型提示是找不到 Oracle Home、或者 central inventory 里没有注册这个 Home。所以原文那句“解压的放 OPatch”实际含义是把补丁包里附带的 OPatch 目录内容覆盖到%ORACLE_HOME%\OPATCH下面。覆盖之前先把旧的OPATCH整个复制一份出来命名成OPATCH_bak_日期这一步几乎不占空间但后面 OPatch 自身出问题时是唯一的后悔药。覆盖完先别急着打补丁跑一次版本核对set ORACLE_HOMED:\oracle\product\11.2.0\dbhome_1 %ORACLE_HOME%\OPATCH\opatch version这条命令输出当前 OPatch 的版本号。拿它跟补丁目录里README.txt或README.html中“OPatch Version”一节要求的最低版本对比低于要求就必须先升 OPatch不能硬打。常见做法是补丁包里如果自带OPatch目录就直接用它没有的话去补丁交付渠道单独取对应版本的 OPatch 包。参数上没什么可调的opatch version只读不写随便跑。还有一点容易忽略Windows 上如果机器装过多个 Oracle Home比如同时有 11.2.0.1 和别的版本PATH里可能残留着另一个 Home 的OPATCH路径。执行前用where opatch确认一下命中的是不是当前这个 Home 下的可执行文件命错了后面所有操作都是白做。2.2 备份清单数据库、ORACLE_HOME、inventory 三份都要补丁失败可以回滚但回滚只回滚二进制文件不保证数据字典的变更能退干净。所以打之前该备的必须备我一般按下面三份来准备备份对象具体内容为什么必须备数据库本体数据文件、控制文件、spfile/pfile、在线归档日志补丁后如果出现无法启动或数据字典异常只能靠它恢复ORACLE_HOME整个dbhome_1目录打包重点OPATCH、rdbms\admin、bin、lib回滚失败或 OPatch 被覆盖坏时可直接换回整目录oraInventoryinventory.xml、ContentsXML目录Home 注册信息损坏后OPatch 会彻底不认这个 Home数据库侧用 RMAN 做一次全备最稳不想动 RMAN 的话至少做一次冷备关库之后把数据文件、控制文件、参数文件整体拷贝到另一块盘。ORACLE_HOME 和 inventory 直接用系统自带的压缩打包即可注意打包时不要包含正在写入的 trace 文件可以先关库再打包避免文件句柄占用。rem 关库之后执行示例路径按实际环境替换 mkdir D:\backup\before_patch_20240101 xcopy D:\oracle\product\11.2.0\dbhome_1 D:\backup\before_patch_20240101\dbhome_1 /E /I /H xcopy D:\oracle\product\11.2.0\oraInventory D:\backup\before_patch_20240101\oraInventory /E /I /H/E连空目录一起复制/I目标不存在时按目录处理/H把隐藏文件也带上。inventory 的实际位置不一定在ORACLE_BASE下Windows 上默认也可能落在系统盘的Program Files\Oracle\Inventory执行前先用opatch lsinventory -detail输出里的 “Central Inventory” 一行确认真实路径别照着模板抄。2.3 关库、停服务、确认没有残留进程补丁要替换的是bin目录下的可执行文件和lib下的动态库只要还有 oracle 进程占着这些文件opatch apply就会在最后阶段报文件被占用。顺序是先关实例、再停服务、最后查进程。-- 以 sysdba 身份登录后执行 shutdown immediate; -- 确认实例状态输出应为 STARTED 或空不能是 OPEN select status from v$instance;shutdown immediate会回滚未提交事务并断开所有会话比abort安全。如果卡住不退先查v$session里有没有长事务或阻塞会话别直接上shutdown abort那样下次启动要做实例恢复在变更窗口里白白多花时间。实例停掉之后停 Windows 服务服务名一般是OracleServiceSIDnet stop OracleServiceORCL rem 确认没有 oracle.exe 残留 tasklist | findstr /I oracle.exe监听服务OracleOraDb11g_home1TNSListener不必关它不占用补丁要替换的核心文件。tasklist那条如果还有输出说明有后台进程没退干净可以用orakill或任务管理器结束但结束前先确认不是别的实例的进程多实例机器上误杀会导致另一个库宕机。3. 单个补丁走一遍从 set ORACLE_HOME 到 opatch apply 的输出判读前置条件齐了单个补丁的流程其实就三四条命令。但命令短不代表没讲究set写错一个字符、补丁目录进错一层症状都会在几十秒之后才以一堆看不懂的日志形式冒出来。这一章把命令逐条拆开重点放在输出怎么读。3.1 set ORACLE_HOME 的几个隐形坑原文写的是set ORACLE_HOMED:\oracle\product\11.2.0\dbhome_1这条命令本身没错但有几个细节能让人卡半天。第一等号两边不能有空格。set ORACLE_HOME D:\...在 cmd 里会把变量名设成带空格的形式后面%ORACLE_HOME%展开就是空OPatch 立刻提示找不到 Home。第二值结尾不能带反斜杠。D:\oracle\product\11.2.0\dbhome_1\这种写法在某些 OPatch 版本上会拼出双反斜杠路径导致 inventory 匹配失败。第三set只在当前 cmd 窗口生效关掉窗口就没了。所以每个补丁目录都要重新开窗口、重新 set不能指望“上一个窗口设过了”。第四路径里不要有空格和中文。Oracle 装在D:\Program Files\...这种带空格的路径下OPatch 的批处理脚本拼参数时容易断在空格处中文路径则在日志编码上出乱码排查时很痛苦。一个稳妥的写法是把几条环境变量一起设好set ORACLE_HOMED:\oracle\product\11.2.0\dbhome_1 set ORACLE_SIDORCL set PATH%ORACLE_HOME%\OPATCH;%ORACLE_HOME%\bin;%PATH% echo %ORACLE_HOME%最后那条echo不是可有可无的它是当前窗口里唯一能立刻验证变量是否生效的手段。输出跟预期一致再往下走不一致就重开窗口重设别在错误的环境里试第二次。3.2 进补丁目录执行 opatch apply 并读懂输出环境变量确认无误后cd到解压出来的补丁目录。注意是进到补丁目录本身也就是能看到etc、files、README.txt这一层不是它的上一级。cd /d D:\patch\p1234567 %ORACLE_HOME%\OPATCH\opatch applycd /d的/d用于跨盘符切换从 C 盘切到 D 盘必须带否则目录根本没变。原文里写的是%ORACLE_HOME%\OPATCH\opatch apply等价写法给路径加引号是为了防止 Home 路径里有特殊字符时被截断。执行后会先跑一串前置检查再逐个文件应用。几个关键输出位置要盯出现Enter the full pathname of the local ORACLE_HOME这类交互提示说明环境变量没生效OPatch 退回到手动输入模式。这时候直接 CtrlC 退出回去重设变量不要在这里手敲路径容易带错。中间出现Prerequisite check相关行任何一项failed都要停下看日志不要指望后面的步骤能覆盖。最后一行是判定依据。原文说“看到 succeed 就可以了”实际输出常见形态是OPatch succeeded.或ApplySession failed两种前者才是成功。常用的附加参数不多但用得上参数作用使用场景-silent不交互全自动执行批量脚本里跑或确认无需人工确认时-report只检查不实际应用变更前预演看会不会冲突-no_sysmod不修改系统表空间相关对象特殊环境由 DBA 手工处理时日志位置固定通常在%ORACLE_HOME%\cfgtoollogs\opatch\下文件名带时间戳补丁目录里也会留一份。失败时第一件事不是重跑是打开最新的那份日志从后往前找第一个ERROR或SEVERE后面往往是连锁反应看第一个才有意义。3.3 apply 成功后的数据库侧收尾动作文件替换完不等于补丁生效。11.2.0.1 上的 PSU 类补丁在二进制层面应用完之后还需要在数据库里跑一遍数据字典更新脚本否则会出现版本视图对不上、部分系统包仍是旧版的情况。-- 启动到 open 状态后执行? 在 SQL*Plus 里代表 ORACLE_HOME ?/rdbms/admin/catbundle.sql psu apply -- 重新编译所有无效对象 ?/rdbms/admin/utlrp.sqlcatbundle.sql带psu apply参数表示按 PSU 方式应用跑完会在sys.registry$history里留一条记录。如果补丁说明里明确要求执行就一定要跑如果补丁只是 interim patchREADME 里没提这一步就跳过。跑之前确认库已经正常 open且compatible参数没有卡在更低版本上。utlrp.sql会编译所有INVALID状态的存储对象跑之前可以先查一下数量跑完再查一次做对比select count(*) from dba_objects where status INVALID;数量降下来才算编译到位仍然有大量无效对象时多半是依赖的外部对象缺失不是补丁本身的问题。4. 多补丁的排序与冲突为什么必须从数字小的往数字大的打单个补丁打得再顺多个补丁一起上就是另一回事。原文那句“数字补丁包从数字小的打到大的”背后是 Oracle 补丁的叠加机制顺序错了轻则冲突检查不过重则后一个补丁把前一个覆盖掉最后lsinventory里只认一个。4.1 补丁的叠加关系与排序依据Oracle 的 interim patch 之间有两种典型关系一种是一个补丁包含另一个补丁的修复内容superset另一种是两个补丁修改了同一个文件的不同位置可共存还有一种是两个补丁改了同一处代码互斥必须先打一个再打另一个的合并版本。补丁编号本身是递增分配的早期交付的编号小后期的编号大所以“从小到大”在多数情况下是对的但严格说决定顺序的是补丁 README 里的Patch Pre-requisites小节不是编号。我一般按这个顺序判断先读每个补丁的 README看有没有写明“需要先安装某个补丁”如果有就按 README 指定的依赖关系排README 没写依赖时再按编号从小到大排。两边冲突时以 README 为准因为编号顺序只是交付时间不保证依赖关系。多个补丁之间还有一种情况是后来出现了合并补丁把若干个小补丁打包成一个这种情况下不需要再单独打被合并的那些直接打合并版即可否则会报已经应用过。4.2 逐个 apply 的执行节奏节奏上有两条硬规矩每个补丁单独开窗口、单独 set、单独进目录不要在同一个窗口里连续cd到不同补丁目录以及中间不重启全部打完再统一重启。rem 补丁 1 set ORACLE_HOMED:\oracle\product\11.2.0\dbhome_1 cd /d D:\patch\p1000001 %ORACLE_HOME%\OPATCH\opatch apply rem 确认输出 OPatch succeeded 后另开窗口处理补丁 2 set ORACLE_HOMED:\oracle\product\11.2.0\dbhome_1 cd /d D:\patch\p1000002 %ORACLE_HOME%\OPATCH\opatch apply中间不重启的理由是每个补丁的 apply 过程都要读 inventory 的当前状态重启服务器不会改变 inventory 内容反而拉长变更窗口。全部打完之后统一重启让 Oracle 服务自启这时实例启动会一次性完成所有补丁要求的数据字典调整比起一个补丁重启一次要干净。每打完一个立刻做一次轻量验证%ORACLE_HOME%\OPATCH\opatch lsinventory | findstr /I patch确认新补丁编号出现在列表里再进下一个。这一步多花十秒能避免“打了三个补丁发现第一个没进去”的返工。4.3 冲突预检prereq 把问题提前暴露补丁之间有没有冲突不用等apply跑到一半才发现OPatch 自带前置检查命令可以在真正应用之前先跑一遍cd /d D:\patch\p1000002 %ORACLE_HOME%\OPATCH\opatch prereq CheckConflictAgainstOHWithDetail -ph ./-ph ./指向当前目录下的补丁定义文件CheckConflictAgainstOHWithDetail会把该补丁与当前 Home 里已装的补丁逐个比对输出哪些文件冲突、冲突的补丁编号是多少。除了这个还有两个常用的检查项检查项命令后缀检查内容空间检查CheckSystemSpace -ph ./目标盘剩余空间是否够补丁展开和备份活跃文件检查CheckActiveFilesAndExecutables -ph ./是否有进程占用即将被替换的文件冲突检查CheckConflictAgainstOHWithDetail -ph ./与已装补丁的文件级冲突CheckActiveFilesAndExecutables这一项在 Windows 上特别有用前面说的实例没关干净这个检查会直接点出哪个进程占着哪个 dll比等 apply 失败再去猜要快得多。真遇到冲突且 README 没有给出合并补丁时处理路径只有两条找交付方要一个把两者合并的补丁或者放弃其中一个。不要试图手工替换文件绕过那样 inventory 记录跟实际文件不一致后面所有补丁的状态判断都会失真。5. 避坑与排查apply 卡住、succeed 假象、库起不来的现场处理补丁流程本身只有几条命令真正耗时间的是出错之后的定位。下面这几条是我在实际环境里反复遇到的按“现象、原因、解决”写遇到时可以先按顺序对号入座。5.1 现象opatch 一启动就报版本不兼容执行opatch apply后立刻退出提示当前 OPatch 版本与补丁要求不符或者提示无法识别补丁格式。原因是%ORACLE_HOME%\OPATCH下的 OPatch 版本低于补丁 README 里要求的最低版本。补丁的打包格式会随 OPatch 版本演进老版本 OPatch 读不懂新补丁的patch_metadata。解决办法是先核对版本opatch version看当前值README 里找 “OPatch Version” 要求低于要求就整目录替换 OPatch。替换前把旧目录改名备份替换后重新跑opatch version确认生效。这里有个顺序问题必须先升 OPatch 再打补丁反过来做会把补丁目录里的元数据写成旧格式。5.2 现象前置检查失败提示文件被占用或实例在运行apply跑到 Prerequisite check 阶段停下报某个 dll 或 exe 正在被使用。原因是实例没关干净或者 Windows 服务还挂着。有时候shutdown immediate返回了但后台的oracle.exe还在做最后的清理几秒内没退完。解决办法是回到 2.3 节那套动作net stop OracleServiceSID、tasklist | findstr oracle.exe确认无残留再用prereq CheckActiveFilesAndExecutables -ph ./复核一遍。如果是有其他客户端工具比如某些图形化工具连着库也要一并断开光关实例不一定够。5.3 现象apply 显示成功重启后 lsinventory 里找不到补丁这个最坑。屏幕上明明打了OPatch succeeded.第二天查 inventory 却没这条记录。原因通常有两个一是打到了另一个 ORACLE_HOME机器上装了多个 HomePATH或ORACLE_HOME指错了二是 inventory 指针没更新Home 注册在别的 central inventory 里。解决办法是先看opatch lsinventory -detail输出头部的 “Oracle Home” 和 “Central Inventory” 两行确认路径是不是你以为的那个。指错了就回正确 Home 重打一遍inventory 指针错了用-invPtrLoc参数指定正确的oraInst.loc再执行。别嫌这一步麻烦路径错了所有的成功提示都是假的。5.4 现象补丁打完数据库起不来或报大量无效对象重启后实例启动失败告警日志里有 ORA-00600或者能起来但应用报对象无效。原因是二进制补丁应用了但数据字典脚本没跑。PSU 类补丁会修改系统表结构catbundle.sql不执行数据字典版本和二进制版本就对不上。解决办法是先把实例拉到 mount 或 open 状态视报错而定执行?/rdbms/admin/catbundle.sql psu apply再跑?/rdbms/admin/utlrp.sql编译无效对象最后用dba_registry查各组件状态是否VALID。如果catbundle.sql本身报错先看sys.registry$history里上一次的记录确认是不是重复执行导致的冲突。5.5 现象补丁目录路径带空格或中文apply 中途异常退出apply跑到一半退出日志里出现路径截断或者编码乱码。原因是 OPatch 的批处理脚本对路径里的空格和中文处理不完善参数拼接时断在空格处实际传给 Java 的路径只剩前半截。解决办法是把补丁包解压到纯英文、无空格、层级浅的路径下比如D:\patch\p1000001不要放在桌面或者“我的文档”这类路径里。已经解压到错误位置的话重新解压一份到新路径不要试图改名绕过patch_metadata里记录的路径也要一起对得上。6. 验证与回滚lsinventory 读数、rollback 边界和事后留档补丁打完验证这一步很多人只扫一眼有没有succeed就收工。真正能说明问题的是 inventory 里的记录和日志路径这两样东西决定了三个月后出问题时你能不能还原当时的现场。6.1 lsinventory 输出里哪些行必须看%ORACLE_HOME%\OPATCH\opatch lsinventory -detail D:\backup\lsinventory_after_patch.txt-detail会展开每个补丁的详细信息重定向到文件是为了留档。输出里有几行是必看的输出位置含义判断标准Oracle Home当前操作的 Home 路径必须与预期一致Central Inventoryinventory 实际位置与备份时的路径一致OPatch version当前 OPatch 版本不低于补丁要求Patches applied已应用补丁列表本次补丁编号在内Log file location该补丁的应用日志文件真实存在且非空最后一行最容易被忽略但它是最有用的。日志文件里记录了每个文件的替换动作和前置检查结果出问题时直接打开这个文件比翻整个cfgtoollogs目录快得多。6.2 rollback 的边界能退什么、不能退什么回滚命令本身很简单%ORACLE_HOME%\OPATCH\opatch rollback -id 1000001-id后面跟补丁编号必须在lsinventory里存在才能回滚。但有三个边界要提前清楚第一回滚是按补丁整体退不能只退其中一部分文件第二如果后面又打了依赖这个补丁的新补丁必须先退新的再退旧的顺序反了会报冲突第三回滚只还原二进制和部分配置补丁执行过的数据字典变更不会自动回退回滚后通常还要再跑一遍catbundle.sql和utlrp.sql把对象状态理顺。所以回滚不是万能方案真正保险的还是 2.2 节那三份备份。rollback 适合“补丁打错了编号”这种场景不适合“补丁把库搞坏了”。6.3 事后留档把现场封进一个文件夹我现在的习惯是每次变更结束把四样东西放进同一个以日期命名的文件夹打补丁前的lsinventory输出、打补丁后的lsinventory输出、每个补丁的应用日志、以及补丁包原始压缩文件。压缩包留着的原因很实际回滚或者重装时要靠它而交付渠道上的历史补丁不一定随时取得到。这套动作最初是被一次事故逼出来的当时给一套测试库连打三个补丁中间某个补丁的日志没留两周后应用报错排查时完全无法确认当时到底应用了哪些文件只能整库重建。从那以后我每次打补丁lsinventory -detail的输出都强制走一遍重定向文件名带上补丁编号和日期一个都不省。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑