简介本资源是专为Windows平台Oracle 12c数据库环境定制的OPatch补丁管理工具集面向DBA、运维工程师及数据库开发人员用于安全、高效地应用Oracle官方补丁如PSU、BP、One-Off等解决补丁部署失败、OPatch版本不兼容、JVM识别异常等典型问题。压缩包共454个文件涵盖132个核心jar库支撑OPatch Java运行时、111个Windows动态链接库适配本地系统调用、21个可执行脚本如opatch.bat、datapatch.bat、opatch_jvm_discovery.bat等关键入口、41份Markdown格式说明文档含FAQ、操作指南与配置示例以及properties、xml、sh、pl等配套配置与跨平台支持文件整体体积102.88MB结构完整、开箱即用。目前已有998人学习下载提供即装即用的OPatch 12.2.x主流版本及配套工具链如opatchauto、operr、opatch_wls、datapatch并内置字体配置fontconfig.bfc、证书信任库cacerts、黑名单策略blacklist及安全策略文件显著降低Windows下Oracle补丁管理门槛。1. Oracle 12c Windows 补丁升级不是“点下一步”就能过的事OPatch 版本错配、PATH 混乱、补丁冲突——这三个坑让 70% 的 DBA 在凌晨两点还在查日志你手头有一台跑着 Oracle Database 12c比如 12.1.0.2 或 12.2.0.1的 Windows Server刚收到安全通告说必须打 January 2024 Critical Patch UpdateCPU或者业务方突然要求修复某个已知的 ORA-00600 内部错误。你信心满满地去 Oracle Support 下载了 p36123456_121020_MSWIN-x64.zip补丁包和 p6880880_121010_MSWIN-x64.zipOPatch 最新版双击 setup.exe别急——Windows 下 Oracle 补丁失败率远高于 Linux根本原因不是权限不够而是 OPatch 这个“补丁调度器”本身在 Windows 上就是个黑匣子它极度依赖环境变量顺序、JDK 版本兼容性、Oracle Home 路径中的空格与大小写甚至 PowerShell 执行策略都会让它静默退出。我见过太多人卡在opatch lsinventory报 “OPatch failed with error code 254”翻遍日志只看到一行java.lang.NoClassDefFoundError最后发现是 JDK 17 装早了而 12.1.0.2 只认 JDK 1.7–1.8。这不是玄学是 Windows Oracle 12c OPatch 三者版本组合的硬约束。本文专为在 Windows 环境下真实执行过至少 3 次完整补丁周期的 DBA 和运维工程师而写不讲原理图只列命令、标路径、写参数、给回滚后悔药。如果你正准备给生产库打补丁或刚被一个OPatch failed with error code 73搞得头皮发麻请从第 2 章开始逐行执行别跳。2. 准备工作确认 Oracle 12c 版本、下载匹配的 OPatch、校验 JDK 兼容性Oracle 官方对 OPatch 有严格版本绑定策略不是最新版 OPatch 就一定最好而是必须用 Oracle Support 文档明确标注支持你当前 Oracle Home 版本的那个 OPatch 小版本。例如12.1.0.2.0 基础版本Base Release官方只认证 OPatch 12.1.0.1.x 系列而 12.2.0.1.0 则要求最低 OPatch 12.2.0.1.20。用高版本 OPatch 强行管理低版本 Oracle Home极大概率触发Prerequisite check CheckActiveFilesAndExecutables failed—— 因为新 OPatch 会扫描更多进程锁文件而老 Oracle 的 Windows 服务没按新规范注册句柄。2.1 查准你的 Oracle 12c 精确版本号含 PSU/CPU 编号很多 DBA 只记SELECT * FROM v$version;输出的12.1.0.2.0但这远远不够。你需要的是完整的 Oracle Home Build ID它决定了你能打哪些补丁、该用哪个 OPatch# 以管理员身份打开 CMD不是 PowerShell后续步骤需 CMD 兼容性 C:\ set ORACLE_HOMED:\app\oracle\product\12.1.0\dbhome_1 C:\ %ORACLE_HOME%\OPatch\opatch version OPatch Version: 12.1.0.1.10 OPatch succeeded. C:\ %ORACLE_HOME%\OPatch\opatch lsinventory -detail | findstr Patch description # 如果 OPatch 不存在或报错先跳到 2.2 节安装 OPatch提示opatch lsinventory -detail输出中Oracle Home行下方紧跟着的Oracle Home Name和Oracle Home Location必须与你实际路径一致Patch description行会列出已安装的 PSU如 Database Patch Set Update : 12.1.0.2.190416这个日期码190416就是你当前的补丁集版本后续下载补丁时必须匹配。2.2 下载并部署正确版本的 OPatchWindows 专用 ZIP 包Oracle 不提供 Windows 下的 OPatch 安装程序.exe只提供 ZIP 包且必须解压到%ORACLE_HOME%\OPatch目录下覆盖原有文件。切勿解压到其他位置再复制因为 OPatch 内部硬编码了相对路径逻辑。访问 My Oracle Support (MOS) → 搜索 Note ID224346.1OPatch Download and Setup)根据你的 Oracle 版本选择对应 OPatchOracle 12.1.0.2 → 下载p6880880_121010_MSWIN-x64.zipOPatch 12.1.0.1.252023年10月发布Oracle 12.2.0.1 → 下载p6880880_122010_MSWIN-x64.zipOPatch 12.2.0.1.302024年1月发布下载后执行以下操作关键用 CMD禁用杀毒软件实时扫描# 1. 停止所有 Oracle 服务必须否则 OPatch 会因文件占用失败 C:\ net stop OracleServiceORCL C:\ net stop OracleOraDB12c_home1TNSListener # 2. 备份原 OPatch后悔药第一步 C:\ xcopy %ORACLE_HOME%\OPatch %ORACLE_HOME%\OPatch_backup_%date:~-4,4%%date:~-10,2%%date:~-7,2% /E /I /Y # 3. 解压新 OPatch ZIP 到 %ORACLE_HOME% 根目录注意是解压到 D:\app\oracle\product\12.1.0\dbhome_1不是其子目录 # 使用 7-Zip 命令行推荐比 Windows 自带解压更稳定 C:\ C:\Program Files\7-Zip\7z.exe x p6880880_121010_MSWIN-x64.zip -o%ORACLE_HOME% -y # 4. 验证解压结果必须看到 OPatch.bat、opatch.pl、jlib/ 目录 C:\ dir %ORACLE_HOME%\OPatch | findstr OPatch.bat opatch.pl jlib OPatch.bat 12/01/2023 02:15 AM 1,248 opatch.pl 12/01/2023 02:15 AM 12,345 jlib\ 12/01/2023 02:15 AM DIR参数说明-o指定解压目标根目录-y自动确认覆盖jlib/是 OPatch 运行必需的 Java 类库目录若缺失则opatch version必报错。此步骤失败最常见的原因是杀毒软件拦截 ZIP 解压行为临时禁用即可。2.3 核查并锁定 JDK 版本Windows 下最易被忽略的致命项Oracle 12c Windows 版本对 JDK 有硬性要求12.1.0.2仅支持 JDK 1.7u80 或 JDK 1.8u144官方文档 MOS Note 1965979.1 明确列出12.2.0.1支持 JDK 1.8u144 至 JDK 1.8u291不支持 JDK 9而 Windows 默认可能已安装 JDK 17如通过 Chocolatey 或手动安装此时 OPatch 启动时会调用系统 PATH 中第一个java.exe导致java.lang.UnsupportedClassVersionError。# 1. 查看当前 PATH 中 java.exe 位置 C:\ where java C:\Program Files\Java\jdk-17.0.1\bin\java.exe C:\Program Files\Java\jre1.8.0_291\bin\java.exe # 2. 强制 OPatch 使用指定 JDK推荐方式设置 OPATCH_JAVA_HOME C:\ set OPATCH_JAVA_HOMEC:\Program Files\Java\jre1.8.0_291 C:\ set PATH%OPATCH_JAVA_HOME%\bin;%PATH% # 3. 验证 OPatch 实际调用的 JDK C:\ %ORACLE_HOME%\OPatch\opatch version OPatch Version: 12.1.0.1.25 OPatch succeeded. C:\ %ORACLE_HOME%\OPatch\opatch version -jdk Java version: 1.8.0_291 Java vendor: Oracle Corporation注意OPATCH_JAVA_HOME环境变量优先级高于系统 PATH是 OPatch 官方推荐的 JDK 指定方式。不要修改系统全局 JAVA_HOME以免影响其他 Java 应用。若opatch version -jdk输出的版本仍不对检查set OPATCH_JAVA_HOME命令是否在同一个 CMD 窗口中执行CMD 不继承父窗口环境变量。3. 执行补丁安装解压补丁包、预检、应用、验证四步闭环补丁安装不是“把 ZIP 解压进去就完事”。OPatch 在 Windows 下会启动多个 Java 进程扫描 DLL、检查服务状态、生成 rollback 脚本每一步都可能因路径权限、防病毒软件、用户上下文而中断。本节按标准生产流程拆解每步附失败信号与即时诊断法。3.1 解压补丁包到独立临时目录严禁直接解压到 ORACLE_HOMEOracle 补丁 ZIP如p36123456_121020_MSWIN-x64.zip解压后是一个包含etc/,files/,custom/的结构化目录。必须解压到与%ORACLE_HOME%无父子关系的路径例如D:\patch_temp\36123456。原因OPatch 在 apply 阶段会递归扫描当前目录所有子目录若补丁包解压在%ORACLE_HOME%\patch下它会误将自身当作待打补丁的一部分触发Duplicate patch id detected错误。# 创建干净临时目录路径不含空格、中文、特殊字符 C:\ mkdir D:\patch_temp\36123456 # 解压补丁 ZIP同样用 7-Zip 避免 Windows 解压损坏 C:\ C:\Program Files\7-Zip\7z.exe x p36123456_121020_MSWIN-x64.zip -oD:\patch_temp\36123456 -y # 验证补丁元数据关键检查 README.html 和 patch.xml C:\ type D:\patch_temp\36123456\README.html | findstr 12.1.0.2 # 应输出类似h2Oracle Database 12.1.0.2.0/h2 C:\ type D:\patch_temp\36123456\patch.xml | findstr oracle_home_version # 应输出oracle_home_version12.1.0.2.0/oracle_home_version逻辑说明README.html是人工可读的补丁说明patch.xml是 OPatch 解析的机器配置文件。二者oracle_home_version字段必须与你opatch lsinventory输出的版本完全一致包括小数点后位数否则opatch prereq会直接拒绝。3.2 运行预检prereq用-oh显式指定 Oracle Home避免路径歧义Windows 下cd到补丁目录再运行opatch apply是高危操作因为 OPatch 会尝试从当前路径向上查找ORACLE_HOME极易误判。必须始终用-oh参数显式传入绝对路径且路径末尾不能有反斜杠\OPatch 会将其解析为转义符# 进入补丁目录非必须但便于后续命令 C:\ cd /d D:\patch_temp\36123456 # 执行预检不修改任何文件只做合规性扫描 C:\ %ORACLE_HOME%\OPatch\opatch prereq CheckConflictAgainstOHWithDetail -ph . -oh D:\app\oracle\product\12.1.0\dbhome_1 # 预期成功输出最后一行应为 Prereq check passed. ... Prereq check passed.参数说明-ph .表示当前目录即补丁解压根目录-oh后跟双引号包裹的 Oracle Home 绝对路径CheckConflictAgainstOHWithDetail是最严格的冲突检查会报告所有已安装补丁与当前补丁的兼容性。若失败输出中会明确指出冲突补丁号如Patch 29834712 conflicts with patch 28790647此时需查阅 MOS Note 对应补丁的互斥矩阵决定是否先回滚旧补丁。3.3 正式应用补丁apply启用详细日志、监控进程、捕获退出码opatch apply是核心动作必须在管理员 CMD 中执行并重定向日志以便追溯# 关键添加 -silent静默模式和 -ocmrf跳过 OCM 配置提示避免交互卡住 C:\ %ORACLE_HOME%\OPatch\opatch apply -oh D:\app\oracle\product\12.1.0\dbhome_1 -silent -ocmrf D:\patch_temp\36123456\apply_log.txt 21 # 实时监控 OPatch 启动的 Java 进程防止假死 C:\ tasklist /fi imagename eq java.exe | findstr OPatch # 应看到类似java.exe 1234 Console 1 45,678 K # 检查 OPatch 退出码必须为 0 C:\ echo %ERRORLEVEL% 0逻辑说明-silent禁用所有用户输入提示Windows GUI 弹窗在此模式下会被抑制-ocmrf指向一个空的ocm.rsp文件可提前创建echo D:\patch_temp\ocm.rsp跳过 Oracle Configuration Manager 配置步骤21将标准错误合并到日志确保所有报错不丢失。若%ERRORLEVEL%非 0立即打开apply_log.txt搜索SEVERE或FATAL关键字。3.4 补丁后验证lsinventory sqlplus 双校验确认补丁真正生效补丁应用成功 ≠ 补丁生效。必须验证两层OPatch 层lsinventory能列出新补丁 ID数据库层SQL*Plus 中能查询到补丁记录且相关 Bug 已修复# 1. OPatch 层验证新补丁应出现在列表顶部 C:\ %ORACLE_HOME%\OPatch\opatch lsinventory -detail | findstr 36123456 Patch 36123456 : applied on Wed May 15 10:23:45 CST 2024 Unique Patch ID: 28473216 # 2. 数据库层验证需启动数据库并连接 C:\ net start OracleServiceORCL C:\ sqlplus / as sysdba SQL SELECT ACTION, VERSION, COMMENTS FROM DBA_REGISTRY_HISTORY WHERE ACTIONAPPLY AND BUNDLE_SERIESPSU ORDER BY ACTION_TIME DESC; ACTION VERSION COMMENTS ------ -------- ---------------------------------------- APPLY 12.1.0.2.0 Patch 36123456: DATABASE PATCH SET UPDATE 12.1.0.2.240116 # 3. 验证具体 Bug 修复以常见 ORA-00600 [kghfrh:ds] 为例 SQL SELECT * FROM V$VERSION WHERE BANNER LIKE %Oracle Database%; # 输出应包含 12.1.0.2.0 且无已知崩溃 Bug注意DBA_REGISTRY_HISTORY视图记录的是 Oracle 自身的补丁应用历史比lsinventory更权威。若此处无记录说明补丁未真正注册到数据字典需检查apply_log.txt中是否有Failed to update registry字样。4. 避坑指南Windows 下 OPatch 最常踩的 5 个深坑及血泪解法这些不是理论假设而是我在某高校 Oracle 实验室、某金融公司核心账务系统、某制造企业 MES 数据库上累计 17 次补丁失败后总结的“保命清单”。每一条都对应一个真实报错、一个定位命令、一个三步解决法。4.1 现象OPatch failed with error code 73日志中出现Unable to create a process for command: cmd /c copy ...原因Windows 权限模型限制。OPatch 在 apply 阶段需要以 SYSTEM 权限复制 DLL 文件但当前 CMD 窗口是以普通管理员用户如 Administrator启动UAC 虚拟化导致文件写入被重定向到C:\Users\Administrator\AppData\Local\VirtualStore而非真实ORACLE_HOME目录。解决以真正的 Administrator 账户不是加入 Administrators 组的普通账户登录 Windows右键“命令提示符” → “以管理员身份运行”在弹出的 UAC 确认框中点击“是”执行whoami /groups | findstr S-1-5-32-544确认输出中包含BUILTIN\Administrators且Group Attributes为Enabled group, Enabled by default, Enabled group提示whoami /groups是 Windows 原生命令无需额外工具。若输出中BUILTIN\Administrators的Group Attributes包含Deny说明该账户被策略禁用需联系域管理员。4.2 现象opatch lsinventory报OPatch failed with error code 254日志中java.lang.NoClassDefFoundError: oracle/opatch/OPatch原因OPatch 的jlib/opatch.jar文件损坏或OPATCH_JAVA_HOME指向的 JDK 中缺少tools.jarJRE 默认不包含必须用 JDK。解决检查jlib/目录完整性dir %ORACLE_HOME%\OPatch\jlib | findstr opatch.jar确认OPATCH_JAVA_HOME指向的是 JDK 路径含lib\tools.jar而非 JREC:\ dir %OPATCH_JAVA_HOME%\lib\tools.jar # 应输出文件信息若报“找不到文件”则换用 JDK 路径若tools.jar存在但报错依旧强制指定 classpathC:\ set CLASSPATH%OPATCH_JAVA_HOME%\lib\tools.jar;%ORACLE_HOME%\OPatch\jlib\opatch.jar C:\ %ORACLE_HOME%\OPatch\opatch version4.3 现象补丁应用后数据库无法启动告警日志中出现ORA-00445: background process PMON did not start after 120 seconds原因补丁中更新的orabase.dll或oraclient12.dll与 Windows 系统 DLL 冲突常见于打了 CPU 补丁后又手动替换了 Oracle Client。解决立即回滚补丁见第5章检查ORACLE_HOME\bin\下 DLL 时间戳C:\ dir %ORACLE_HOME%\bin\orabase.dll %ORACLE_HOME%\bin\oraclient12.dll /T:C # 对比补丁前备份时间如 OPatch_backup_20240515 目录中同名文件从备份中恢复原始 DLLC:\ copy D:\app\oracle\product\12.1.0\dbhome_1\OPatch_backup_20240515\bin\orabase.dll %ORACLE_HOME%\bin\ /Y4.4 现象opatch apply卡在Validating patches...超过 10 分钟tasklist显示多个java.exe进程内存持续增长原因Windows 防病毒软件如 Windows Defender、Symantec Endpoint实时扫描 OPatch 解压的files/目录导致 Java 进程被挂起。解决临时禁用实时防护Windows Security → Virus threat protection → Manage settings → Turn off real-time protection将%ORACLE_HOME%和D:\patch_temp\添加到防病毒软件排除列表重启 CMD重新执行opatch apply注意禁用防护后务必在补丁完成后立即恢复这是生产环境铁律。4.5 现象补丁应用成功但sqlplus / as sysdba连接时报ORA-12560: TNS:protocol adapter error原因OPatch 修改了listener.ora或tnsnames.ora中的路径将ORACLE_HOME写成了短路径如D:\app\oracle\product\12.1~1.0\dbhome_1而 Windows 服务注册表中监听器服务指向的是长路径。解决检查监听器服务注册表项C:\ reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\OracleOraDB12c_home1TNSListener /v ImagePath # 输出应为D:\app\oracle\product\12.1.0\dbhome_1\BIN\tnslsnr.exe -inherit若注册表中路径为短路径含~1手动修正C:\ reg add HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\OracleOraDB12c_home1TNSListener /v ImagePath /t REG_SZ /d \D:\app\oracle\product\12.1.0\dbhome_1\BIN\tnslsnr.exe\ -inherit /f重启监听器net stop OracleOraDB12c_home1TNSListener net start OracleOraDB12c_home1TNSListener5. 补丁回滚当opatch apply失败或应用后异常如何安全撤退补丁不是单行命令而是一套原子操作。OPatch 在apply前会自动生成rollback脚本但 Windows 下这个脚本极易因路径问题失效。回滚必须分三阶段停止服务 → 手动清理残留 → 执行 OPatch rollback → 验证还原。任何跳步都可能导致 Oracle Home 损坏。5.1 确认回滚前提检查 rollback 目录是否存在且完整OPatch 在apply开始时会将原始文件备份到%ORACLE_HOME%\cfgtoollogs\opatch\rollback\下以补丁 ID 命名的子目录。若此目录不存在说明apply未走到备份阶段只能靠人工备份恢复。# 检查 rollback 目录以补丁 ID 36123456 为例 C:\ dir %ORACLE_HOME%\cfgtoollogs\opatch\rollback\36123456 /A:D # 应输出类似 # 05/15/2024 10:23 AM DIR 36123456 # 进入目录检查关键备份文件 C:\ dir %ORACLE_HOME%\cfgtoollogs\opatch\rollback\36123456 | findstr backup.*\.zip # 应看到 backup_36123456.zip包含所有被替换的 DLL、JAR、XML 文件逻辑说明backup_36123456.zip是 OPatch 自动生成的二进制快照比人工xcopy更可靠因为它记录了文件权限、时间戳、NTFS 流等元数据。若此 ZIP 不存在说明apply在备份前就失败了需使用第2章备份的OPatch_backup_YYYYMMDD目录恢复 OPatch 自身再考虑重试或降级。5.2 手动清理残留进程与锁文件Windows 特有步骤Windows 不像 Linux 有lsof但 Oracle 进程会持有文件锁。若rollback前不清理OPatch 会报Unable to delete file: ... because it is being used by another process。# 1. 强制结束所有 Oracle 相关进程谨慎仅用于回滚场景 C:\ taskkill /f /im oracle.exe /im tnslsnr.exe /im oradim.exe # 2. 删除 OPatch 创建的临时锁文件位于 ORACLE_HOME 根目录 C:\ del /f /q %ORACLE_HOME%\oraInst.loc C:\ del /f /q %ORACLE_HOME%\inventory\locks\*.* # 3. 清空 Windows 临时目录中的 OPatch 缓存 C:\ del /f /q %TEMP%\OraInstall* C:\ del /f /q %WINDIR%\Temp\OraInstall*注意taskkill /f是强制终止仅在数据库已不可用时使用。生产环境建议先net stop失败后再用taskkill。删除oraInst.loc是为了重置 OPatch 的本地库存位置避免路径混淆。5.3 执行 OPatch rollback必须指定 -id 和 -ohrollback命令不接受当前目录作为补丁源必须用-id明确指定补丁编号并再次用-oh指向 Oracle Home# 进入 OPatch 目录确保使用正确的 OPatch 版本 C:\ cd /d %ORACLE_HOME%\OPatch # 执行回滚-id 后跟数字不加 p 前缀 C:\ opatch rollback -id 36123456 -oh D:\app\oracle\product\12.1.0\dbhome_1 -silent D:\patch_temp\36123456\rollback_log.txt 21 # 检查退出码 C:\ echo %ERRORLEVEL% 0参数说明-id 36123456中的36123456是补丁编号不是 ZIP 文件名-silent同样避免交互日志重定向确保可追溯。若%ERRORLEVEL%非 0打开rollback_log.txt搜索RollbackSession关键字确认回滚会话是否启动。5.4 验证回滚结果lsinventory 清除记录 数据库启动测试回滚成功后lsinventory中不应再出现该补丁且数据库必须能正常启动# 1. 检查 OPatch 库存补丁 ID 应消失 C:\ %ORACLE_HOME%\OPatch\opatch lsinventory | findstr 36123456 # 无任何输出表示已清除 # 2. 启动数据库服务 C:\ net start OracleServiceORCL # 3. 连接 SQL*Plus 验证重点检查 V$INSTANCE 和告警日志 C:\ sqlplus / as sysdba SQL SELECT INSTANCE_NAME, STATUS, DATABASE_STATUS FROM V$INSTANCE; # 应输出ORCL OPEN ACTIVE SQL HOST type %ORACLE_HOME%\diag\rdbms\orcl\ORCL\trace\alert_ORCL.log | findstr Errors ORA- # 应无 ORA- 错误输出提示V$INSTANCE的STATUS必须为OPENDATABASE_STATUS为ACTIVE这是数据库真正可用的黄金指标。若alert_ORCL.log中仍有ORA-错误说明回滚未完全修复需检查rollback_log.txt中Restoring file的文件列表手动从backup_36123456.zip中提取并覆盖。6. 验证补丁是否真正生效用一个真实 Bug 场景跑通全流程光看lsinventory有记录、DBA_REGISTRY_HISTORY有条目不等于补丁起效。我习惯用一个已知的、可复现的 Oracle Bug 作为“验收测试用例”。以 Oracle 12.1.0.2 中著名的ORA-00600: internal error code, arguments: [kghfrh:ds]为例——该 Bug 在特定大表 Join 场景下触发导致 PMON 进程崩溃。补丁 36123456 正是修复此问题的 CPU。下面带你走一遍从构造测试场景到验证修复的完整闭环。6.1 构造可复现的测试 SQL模拟真实业务压力该 Bug 触发条件是两个大表各 100 万行以上进行 Hash Join且 Join 列存在大量 NULL 值。我们用DBMS_RANDOM快速生成测试数据-- 1. 创建测试表在 TEST 表空间避免影响生产对象 SQL CREATE TABLE t1 AS SELECT ROWNUM id, DBMS_RANDOM.STRING(U, 20) name, NULL dept_id FROM DUAL CONNECT BY LEVEL 1000000; SQL CREATE TABLE t2 AS SELECT ROWNUM id, DBMS_RANDOM.STRING(U, 20) name, NULL dept_id FROM DUAL CONNECT BY LEVEL 1000000; -- 2. 收集统计信息触发优化器选择 Hash Join SQL EXEC DBMS_STATS.GATHER_TABLE_STATS(SYS, T1); SQL EXEC DBMS_STATS.GATHER_TABLE_STATS(SYS, T2); -- 3. 执行触发 Bug 的 SQL注意此语句在未打补丁的 12.1.0.2 上 100% 崩溃 SQL SELECT /* USE_HASH(t1,t2) */ COUNT(*) FROM t1, t2 WHERE t1.dept_id t2.dept_id;注意/* USE_HASH(t1,t2) */提示强制使用 Hash Joint1.dept_id t2.dept_id中两边均为 NULL正是触发kghfrh:ds的经典条件。执行此语句后若数据库未崩溃而是返回COUNT(*) 0说明补丁已生效。6.2 监控数据库稳定性连续运行 1 小时无 PMON crashBug 修复不是“一次有效”而是“持续稳定”。我通常会让测试 SQL 在后台循环执行同时监控 PMON 进程存活状态# 创建监控脚本 monitor_pmon.bat echo off :loop echo [%date% %time%] Checking PMON... tasklist /fi imagename eq oracle.exe | findstr PMON if errorlevel 1 ( echo [ALERT] PMON process disappeared at %date% %time% D:\patch_temp\monitor_alert.log exit /b 1 ) timeout /t 60 nul goto loop# 启动监控另开一个 CMD 窗口 C:\ monitor_pmon.bat # 同时在 SQL*Plus 中循环执行测试 SQL SQL BEGIN 2 FOR i IN 1..60 LOOP -- 执行 60 次每次间隔 60 秒共 1 小时 3 EXECUTE IMMEDIATE SELECT /* USE_HASH(t1,t2) */ COUNT(*) FROM t1, t2 WHERE t1.dept_id t2.dept_id; 4 DBMS_LOCK.SLEEP(60); 5 END LOOP; 6 END; 7 /逻辑说明tasklist本文还有配套的精品资源点击获取