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

文章详情

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

Oracle数据库补丁安装实战:从补丁包命名到验证回滚完整指南

Oracle数据库补丁安装实战:从补丁包命名到验证回滚完整指南 简介这是面向 Oracle 数据库管理员与运维工程师的补丁集更新包对应编号 20760997适用于 11.2.0.3 版本 Linux x86-64 平台。补丁内容为 11.2.0.3.15 数据库 PSU并集成 2015 年 7 月关键补丁更新CPUJUL2015主要用于修复已知安全漏洞、性能问题与稳定性缺陷。压缩包约 100.73MB主要文件类型为实际补丁程序及 PatchSearch.xml 等配置信息后者通常记录补丁适用性、依赖关系与安装说明便于安装前核对。已有 290 人学习/下载该资源。通过下载并正确应用此 PSU管理员可及时加固 Oracle 11.2.0.3 数据库、降低外部攻击风险同时获得官方在安全更新窗口期内发布的重要修复结合补丁集自带的搜索与校验信息也能更规范地完成补丁评估、备份、应用与验证流程提升日常运维效率。1. 一个补丁文件名就是一张安装说明书半夜接到电话说测试库要打补丁发来一个文件名p20760997_112030_Linux-x86-64.zip。干过几年 Oracle 运维的都知道这个命名本身就是一张说明书p 开头代表 Patch20760997 是补丁号112030 是 11.2.0.3.0 的版本缩写Linux-x86-64 是平台。读懂它你就知道该往哪个环境丢、需要什么前置条件、大概要停多久库。这篇文章就是围绕这类补丁包把从接收文件到安装验证、再到回滚的完整路径讲清楚。适合正在维护 Oracle 11g 单机或 RAC 的 DBA、运维工程师也适合第一次独立打补丁、心里没底的人照着走。重点是每一步该执行什么命令、什么参数能改、报错后看哪里、哪些坑是用时间换来的经验。2. 破解补丁文件名从 p20760997_112030_Linux-x86-64.zip 读出关键信息2.1 四个字段的拆解补丁号、版本、平台与压缩格式文件名p20760997_112030_Linux-x86-64.zip按_分隔成三块但实际信息量是四层pOracle 补丁包的标准前缀Patch 的首字母没有实际业务含义但看到它就能确认这是官方补丁包而不是别的工具包。20760997补丁唯一编号。这个编号在 Oracle 支持站点里可以检索到对应的补丁说明READMEREADME 里写清楚了修复的 Bug 列表、依赖条件、OPatch 最低版本要求、安装步骤。拿到任何补丁包第一件事就是去查这个编号的 README而不是直接解压。112030版本号拆开读是 11.2.0.3.0。其中 11g 是主版本2 是发行版0.3 是补丁集级别最后的 0 是特定平台子版本。看到 112030 就知道这个补丁只能用于 11.2.0.3不能装到 11.2.0.4 上更不能装到 12c 上——版本不匹配时 opatch 会直接拒绝。Linux-x86-64目标平台。Linux 是操作系统家族x86-64 是 64 位指令集。如果是 Solaris 就是Solaris64AIX 就是AIX64。平台错了装不上硬装只会报Prerequisite check failed。压缩格式是 zipLinux 上用unzip解压。有些补丁包是 tar.gz 格式p前缀加.tar.gz后缀也很常见。不同格式只是打包方式不同安装逻辑完全一致。2.2 补丁家族PSU、SPU、CPU、Bundle Patch 怎么选同一个补丁号背后的补丁类型决定了安装策略。Oracle 11.2.0.3 时代最常见的几类PSUPatch Set Update季度性累积补丁包含安全修复和重要 bug 修复。这是绝大多数生产环境默认选择。20760997 这类编号很多就属于数据库 PSU 或其子补丁。PSU 是累积的装新 PSU 会覆盖旧 PSU 的内容。SPUSecurity Patch Update只包含安全修复不含普通 bug 修复。如果企业安全合规要求严格但不想动功能性代码选 SPU。CPUCritical Patch Update早期叫法现在基本被 PSU/SPU 取代但老文档里还常见。Bundle Patch针对特定平台如 Windows、Solaris或特定组件如 RAC、Exadata的捆绑补丁包按平台而非季度发布。选型原则就一句话单机环境优先 PSURAC 环境注意所有节点保持同一补丁级别Exadata 走专用的 Bundle Patch 路线。不要自己混搭——比如先装了 11.2.0.3.10 的 PSU又去装 11.2.0.3.8 的 SPUopatch 会报冲突。2.3 安装前必查三项OPatch 版本、Inventory、空间补丁能不能装上在真正 apply 之前就能判断。我一般会在目标服务器上先跑三条命令# 检查 OPatch 工具版本补丁 README 里会写最低要求 $ORACLE_HOME/OPatch/opatch version # 检查 opatch 能否正常读取 Inventory $ORACLE_HOME/OPatch/opatch lsinventory # 检查 ORACLE_HOME 所在文件系统的剩余空间建议至少 5GB 以上 df -h $ORACLE_HOME逻辑说明opatch version打印的是 OPatch 工具自身版本补丁 README 里明确写了该补丁需要的最低 OPatch 版本低于要求时安装会在前置检查阶段直接失败报错类似OPatch version ... is older than ...。opatch lsinventory能列出 ORACLE_HOME 里已安装的补丁清单如果这条路本身报错说明 Inventory 损坏或环境变量有问题后续所有补丁操作都会失败。df -h是检查空间很多人忽略这一步结果 apply 到一半磁盘写满Oracle 软件目录损坏只能重装这是最惨痛的翻车。空间不用卡死在 5GB主要看补丁大小和$ORACLE_HOME/.patch_storage目录的占用——opatch 会把被替换的旧文件保存在这里用于回滚空间需求大约是补丁包体积的两倍。另外确认一下当前补丁级别opatch lsinventory -bugs_fixed | grep -i 20760997如果已经打过这个补丁重复安装毫无意义。3. 安装链路从校验到 SQL 应用完整跑一遍3.1 下载校验与解压别跳过校验直接 unzip补丁包从传输通道到你手上中间可能经过多层转发。zip 文件头损坏或字节缺失时unzip 可能能解出一部分文件但 opatch 执行到一半才发现文件不完整那时候已经被写入 ORACLE_HOME 的文件就很难清理了。所以解压前先做完整性校验# 先核对文件大小再计算 MD5 ls -l p20760997_112030_Linux-x86-64.zip md5sum p20760997_112030_Linux-x86-64.zip # 确认无误后解压解压到独立目录不要解压到 ORACLE_HOME 里 mkdir -p /u01/app/oracle/patch_2024 unzip p20760997_112030_Linux-x86-64.zip -d /u01/app/oracle/patch_2024逻辑说明ls -l看的是文件字节数在 Oracle 支持站点下载页面会标注补丁包大小两处不一致就说明文件不完整。md5sum生成校验值与官方公布的 MD5 对比这是最可靠的完整性验证。unzip的-d参数指定解压目标目录。解压不能直接解到$ORACLE_HOME因为补丁目录里除了安装文件还有 README 和自定义脚本混入 ORACLE_HOME 会造成环境混乱。解压后先读一下补丁目录里的 README。这不是走形式——README 里包含三个关键信息该补丁依赖哪些前置补丁、OPatch 最低版本、是否需要执行 SQL 脚本。跳过 README 直接 apply 的人后面大概率要回来补课。3.2 停库、关监听跑 opatch applyopatch apply 要求目标环境处于静态状态。数据库不关、监听还开着补丁文件可以被替换但运行中的进程持有旧文件句柄SQL 应用阶段可能出现版本不一致的报错。标准顺序是# 1. 以 oracle 用户执行确认环境变量 env | grep ORACLE_HOME # 2. 关闭数据库实例 sqlplus / as sysdba SQL shutdown immediate; SQL exit # 3. 关闭监听 lsnrctl stop # 4. 进入补丁解压目录执行安装 cd /u01/app/oracle/patch_2024/20760997 $ORACLE_HOME/OPatch/opatch apply逻辑说明env | grep ORACLE_HOME确认当前 shell 的 Oracle 环境指向正确的路径。很多人用 su 切用户后环境变量是乱的opatch 会找错 ORACLE_HOME 或者干脆报Environment variable ORACLE_HOME is not set。shutdown immediate是标准停库方式不能直接 kill 进程否则有实例恢复的风险。lsnrctl stop停监听是因为监听进程会加载 Oracle 库文件不关闭的话补丁替换的动态库文件可能被监听进程占用Unix 系统下文件被占用时替换不会报错但下次监听启动时行为就不可预期了。opatch apply是整套流程的核心。执行过程中会出现交互提示比如确认是否继续——设置好全局应答可以避免无人值守时卡住# 无人值守方式 $ORACLE_HOME/OPatch/opatch apply -silent参数说明-silent模式不交互所有确认都用默认值。适合夜间自动执行或在脚本里调用。但注意-silent模式下如果前置检查没过opatch 会直接退出并返回非零退出码不会给你选择忽略并继续的机会。单机手动打补丁时我反而推荐不带-silent亲眼看到每一步输出更安心。3.3 关键的一步补丁安装完成不等于补丁生效opatch apply 结束后会输出OPatch succeeded很多新手到这里就以为大功告成。实际上 Oracle 数据库补丁的生效方式分两类一类是文件级替换已经随 apply 完成另一类是 SQL 级变更需要连接数据库执行脚本。后者才是让补丁真正对数据库实例生效的那一步。以数据库 PSU 为例常见的后续脚本是执行catcpu.sql这个脚本的具体名称在 README 里。标准操作是先把数据库启动到 upgrade 模式# 启动数据库到 upgrade 模式 sqlplus / as sysdba SQL startup upgrade; SQL $ORACLE_HOME/rdbms/admin/catcpu.sql SQL shutdown immediate; SQL startup逻辑说明startup upgrade模式是专门给升级和补丁脚本用的这个模式下部分功能被禁用避免脚本运行过程中与正常事务发生死锁。catcpu.sql是 CPU/PSU 补丁配套的数据字典更新脚本内容通常包含对数据字典视图、存储过程定义、默认权限的更新。执行时间取决于数据库大小和脚本内容从几分钟到半小时不等期间不能打断否则数据字典处于半更新状态后续启动可能报ORA-04063之类错误。执行完脚本后shutdown immediate再startup恢复正常模式。这里有个判断技巧如果补丁 README 里没有提到 SQL 脚本就不需要做这一步。文件级补丁比如仅替换某个二进制工具装完就能用。判断标准始终以 README 为准别凭经验操作。3.4 安装后的验证权限、版本、错误日志三步走补丁装完、库也重启了怎么确认真的生效三条命令足够# 1. 确认补丁在 Inventory 里 $ORACLE_HOME/OPatch/opatch lsinventory | grep 20760997 # 2. 对比数据库内注册的补丁信息 sqlplus / as sysdba SQL select * from dba_registry_sqlpatch; # 3. 检查最近告警日志有没有新增错误 tail -200 $ORACLE_HOME/diag/rdbms/*/trace/alert_*.log | grep -i error逻辑说明opatch lsinventory查的是文件系统层面的补丁登记信息看到补丁号就说明文件替换成功。dba_registry_sqlpatch查的是数据字典里的 SQL 补丁记录看到对应记录才说明 SQL 脚本应用成功。两者缺一不可——文件替换成功但 SQL 脚本没跑或跑失败被忽略lsinventory 有记录而 dba_registry_sqlpatch 没有这种情况必须补跑 SQL 脚本否则很多 bug 修复不会真正生效。tail检查告警日志是个好习惯有些补丁装完没问题但数据库运行几天后才会在特定场景下报错告警日志是第一个记录异常的地方。装完补丁后观察两天比什么都不看强得多。4. 避坑指南这 5 个翻车现场每个都是真实代价4.1 现象opatch apply 报OPatch version is older than required原因补丁 README 里对 OPatch 工具版本有硬性要求环境里的 OPatch 版本低于最低要求时前置检查直接拒绝执行。很多人的 ORACLE_HOME 是几年前的初始安装版本OPatch 一直没升级过。解决先到补丁对应的版本说明里找到所需 OPatch 最低版本。下载对应的 OPatch 升级包opatch 的升级是独立 zip不是这个补丁包按其中的说明解压并替换$ORACLE_HOME/OPatch目录。替换前备份原目录mv $ORACLE_HOME/OPatch $ORACLE_HOME/OPatch_bak_$(date %Y%m%d) unzip p6880880_112000_Linux-x86-64.zip -d $ORACLE_HOME这里的p6880880是 OPatch 工具自身的常见补丁包号以实际下载为准解压后$ORACLE_HOME/OPatch/opatch version确认版本已更新再重新执行补丁安装。4.2 现象apply 过程中卡在某个百分比不动或报ORA-29701原因数据库实例或监听没有完全关闭。shutdown immediate执行后有时 background 进程没有完全退出比如会话未断开导致 shutdown 挂起或者集群环境RAC下其它节点的实例还在运行。opatch 检查到 ORACLE_HOME 里的库文件被进程占用就会卡住或超时报错。解决先ps -ef | grep ora_ | grep -v grep查看是否有残留进程。单机环境下确认监听进程和数据库后台进程全部消失。如果有ora_pmon_xxx进程存在说明数据库没关干净回到 sqlplus 里执行shutdown abort再startup restrict后重新shutdown immediate。RAC 环境下需要确认所有节点的实例都关闭或者使用-all_nodes参数对集群统一操作只关一个节点的做法是错的。4.3 现象putty 窗口一关opatch apply 进程就死了ORACLE_HOME 部分文件被替换原因用 ssh 终端直接跑 opatch网络断开或窗口关闭导致进程收到 SIGHUP 信号终止。补丁写到一半中断ORACLE_HOME 里的文件处于新旧混杂状态。解决所有耗时操作都放到nohup或screen/tmux里执行nohup $ORACLE_HOME/OPatch/opatch apply -silent /tmp/opatch_apply.log 21 参数说明nohup让进程忽略 SIGHUP 信号 /tmp/opatch_apply.log 21把标准输出和错误输出都写到日志文件放后台。之后随时用tail -f /tmp/opatch_apply.log查看进度。这里有个血泪经验如果已经中断了一半不要直接重新 apply先尝试opatch rollback恢复到原状态如果 rollback 也失败把$ORACLE_HOME/.patch_storage里的备份手动恢复实在不行只能从备份恢复 ORACLE_HOME所以操作前做文件系统快照或备份是值得的。4.4 现象SQL 脚本执行时报ORA-04063: view has errors或ORA-06502数值溢出原因SQL 脚本如catcpu.sql执行环境不对。常见有两种一是数据库没在 upgrade 模式脚本会修改数据字典视图普通模式下系统表处于非一致状态二是补丁要求在cdb/pdb架构下分别执行在 11.2.0.3 上通常是单库环境如果目标库是从 12c 降级或迁移来的结构差异会导致脚本报错。解决确认当前模式SQL select status from v$instance; -- 应该显示 UPGRADE如果状态不是 UPGRADEshutdown immediate后执行startup upgrade重新跑脚本。如果是多租户环境需要在每个 PDB 里执行脚本常见做法是用alter pluggable database all open upgrade打开所有 PDB 后在 PDB 容器里分别执行。12c 的 PSU 还会提供一个catcon.pl工具脚本专门用于在 CDB/PDB 环境下统一执行 SQL 补丁脚本比手动在多个 PDB 里切来切去可靠得多。4.5 现象回滚时报opatch rollback cannot proceed或者回滚后数据库打不开了原因回滚时机不对。PSU 这类补丁在安装时如果已经执行了 SQL 脚本回滚时通常需要先执行对应的回滚 SQL 脚本README 里会有说明比如catcpu_rollback.sql不能只做文件级回滚。还有一个常见情况补丁安装后数据库又执行过其它 DDL建表、加字段等数据字典结构已经偏离补丁安装时的基线回滚脚本会因找不到预期对象而失败。解决回滚前先判断两个条件——补丁是否包含 SQL 变更、是否在安装后做过额外 DDL。两个条件都满足时顺序必须是先执行 SQL 回滚脚本同样在 upgrade 模式下再执行opatch rollback -id 20760997。回滚完成后重新启动数据库并查dba_registry_sqlpatch确认 SQL 补丁记录已被移除。这个场景的经验之谈回滚是最后手段而不是第一选择。大部分问题可以通过重新执行补丁或修复配置解决回滚动作本身会引入新的变量——回滚失败比安装失败更难收拾。5. 补丁生效的双重确认文件层、SQL 层一个都不能少补丁打完后每天巡检时顺手查一下这两处确认补丁状态没有漂移# 文件层补丁列表是否还在 $ORACLE_HOME/OPatch/opatch lsinventory -bugs_fixed | grep 20760997-- SQL 层数据字典里补丁记录是否正常STATUS 应为 SUCCESS col ACTION_TIME for a30 col ACTION for a10 col STATUS for a10 col VERSION for a10 col BUNDLE_SERIES for a15 select ACTION_TIME, ACTION, STATUS, VERSION, BUNDLE_SERIES from dba_registry_sqlpatch order by ACTION_TIME;BUNDLE_SERIES列如果是 PSU 编号又看到ACTIONAPPLY、STATUSSUCCESS说明补丁在数据库层面完全生效。只看 opatch lsinventory 不看 dba_registry_sqlpatch 的巡检是半个巡检。还有一种更细的验证方式根据补丁号在 README 里找到它修复的某个具体 bug模拟触发场景观察行为是否与修复描述一致。这个做法虽然耗时但最踏实。比如某个补丁修复了特定 SQL 语句返回错误结果的问题就在测试库上把那类 SQL 跑一遍对比修复前后的执行计划和结果集。我在模拟项目X上验证过两个补丁都是通过这种定向验证发现 README 描述的修复点与真实行为存在偏差这种差别只有跑过才知道。另外给自己留个习惯每次打补丁把补丁号、日期、前置 OPatch 版本、是否需要 SQL 脚本、回滚路径、验证结果记录成一个清单存在服务器本地。半年后回看这个清单比任何文档都有用。有一次某公司让我统计一套老环境的补丁基线我全靠这些零散记录把补丁历史拼了出来省了大量翻查时间。真到了必须回滚的那天这个清单就是后悔药。打补丁这件事没有玄学每一步都有明确的前置条件和验证标准。按文件校验、环境预检、停库装补丁、SQL 脚本应用、双重验证这套链路走就不会翻车。希望帮到你。本文还有配套的精品资源点击获取
返回列表