datapatch必须在主库OPEN且监听启动后执行,备库仅做OPatch二进制升级、不得运行datapatch;主库执行后需立即归档切换以触发备库元数据同步。

datapatch 必须在主库启动后、备库同步前执行;补丁顺序错一步,备库就卡在 APPLYING 状态无法推进。
先打备库,但别急着跑 datapatch
备库不是“打完补丁就完事”,它只负责二进制层升级(OPatch apply),不运行 datapatch。常见错误是:备库升级完 OPatch、解压补丁、opatch apply 成功后,顺手就去 datapatch -verbose —— 这会失败,报 ORA-65107 或直接 hang 住。因为备库数据库处于 MOUNT 状态,且 Data Guard 同步链路未断开,datapatch 不允许在此时修改数据字典。
- 备库操作仅限:备份
$ORACLE_HOME→ 关库关监听 → 替换OPatch→ 解压补丁包 →opatch apply→ 检查opatch lsinv - 切记:备库上不要执行
datapatch,也不要在备库上startup数据库(除非已关闭 DG 同步) - 如果误执行了
datapatch导致备库挂起,需用alter database recover managed standby database cancel;中止应用,再重启 MOUNT 状态
主库注册补丁必须等监听和实例都起来
datapatch 不是“启动数据库就能跑”,它依赖两个前提:监听器必须 lsnrctl start 正常运行,且数据库必须是 OPEN 状态(不能只是 MOUNT)。很多人在主库 shutdown immediate 后,只 startup 就立刻跑 datapatch,结果报 DPERR-1002: Cannot connect to database —— 实际是监听没启,连接走的是 IPC,而 datapatch 默认走 TCP。
- 正确顺序:先
lsnrctl start→ 再sqlplus / as sysdba执行startup→ 确认select status from v$instance;返回OPEN→ 最后执行$ORACLE_HOME/OPatch/datapatch -verbose -
datapatch -prereq可提前验证,但它不检查监听状态,只校验补丁冲突和 SQL 脚本兼容性 - 若主库是 RAC,必须在所有节点都完成
opatch apply后,再逐个节点执行datapatch(不能只在一个节点跑)
备库自动同步补丁元数据的关键时机
主库 datapatch 成功后,补丁信息(如 DBA_REGISTRY_SQLPATCH 记录)会通过归档日志传到备库,但前提是:备库必须处于实时应用模式(RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE),且主库归档已切换(alter system archive log current;)。否则备库的 DBA_REGISTRY_SQLPATCH 会长时间停留在旧版本,看起来像“没同步”。
- 主库
datapatch完成后,立即执行一次alter system archive log current; - 在备库查:
select patch_id, action, status from dba_registry_sqlpatch order by action_time desc;,确认最新PATCH_ID的STATUS是APPLIED - 如果备库状态仍是
LOADING或ERROR,说明归档还没传过来,检查v$archive_dest_status和gaps视图
补丁回滚和无效对象编译容易被跳过
很多人以为 datapatch 成功就万事大吉,其实还有两件事必须手动做:一是 utlrp.sql 编译无效对象(尤其主库上有自定义 PL/SQL 或 Java 类时),二是保留回滚能力——opatch rollback 在 Data Guard 下不可逆,只能靠备份 $ORACLE_HOME 回退。
- 编译无效对象必须在主库
OPEN后、备库同步前执行:cd $ORACLE_HOME/rdbms/admin; sqlplus /nolog @utlrp.sql - 回滚补丁时,不能只在主库 rollback:必须先停主备所有实例 → 主库
opatch rollback→ 备库也执行相同opatch rollback(补丁 ID 要一致)→ 再分别datapatch -rollback - 最保险的做法:打补丁前用
tar -cvzf备份整个$ORACLE_HOME,而不是只备份OPatch目录
datapatch 的执行时机,比命令本身更关键;一个 archive log current 没触发,备库就永远看不到新补丁记录。


















