DBUA预检失败主因是辅助实例缺失归档或控制文件备份,需确保RMAN成功还原控制文件且归档覆盖其SCN后全部变更;预检实际执行utlu19i.sql,须OPEN RESTRICTED;路径不一致或NLS/PLSQL未显式校验将导致漏检。
用 RMAN RESTORE 到辅助实例前,必须确认控制文件和归档能完整重建
dbua 预检失败常不是因为升级包问题,而是辅助实例压根没拿到足够恢复所需的归档和控制文件备份。rman restore controlfile 必须成功,且 list archivelog all 在目标库备份集中要能查到从控制文件 scn 到当前时间的全部归档——缺任意一段,recover database 就会卡住,dbua 直接跳过预检或报 ora-19909: datafile belongs to an orphan incarnation。
实操建议:
- 在源库执行
LIST BACKUP OF ARCHIVELOG ALL,记下最早和最晚的COMPLETION TIME;再比对RESTORE CONTROLFILE得到的控制文件CHECKPOINT_CHANGE#,确保所有归档覆盖该 SCN 之后的变更 - 如果使用 FRA,确认
DB_RECOVERY_FILE_DEST_SIZE在辅助实例中设得足够大(至少是源库已用空间的 1.5 倍),否则RESTORE ARCHIVELOG途中可能静默失败 - 别依赖自动删除策略:RMAN
CONFIGURE ARCHIVELOG DELETION POLICY TO APPLIED ON STANDBY在辅助实例无效,归档必须显式RESTORE过来
DBUA 预检实际调用的是 utlu19i.sql(或对应版本脚本),但只在 OPEN RESTRICTED 状态下运行
很多人以为 DBUA 预检是黑盒扫描,其实它底层就是跑 Oracle 自带的升级前检查脚本 utlu19i.sql(19c)或 utlu122i.sql(12.2)。但它不会在 MOUNT 状态执行,也不会在 OPEN READ WRITE 下执行——必须先 ALTER DATABASE OPEN RESTRICTED,否则脚本里大量 SELECT 会因对象未就绪报错,比如 ORA-01219: database not open 或 ORA-00942: table or view does not exist。
实操建议:
- RESTORE + RECOVER 完成后,立刻执行
ALTER DATABASE OPEN RESETLOGS,再立刻ALTER DATABASE OPEN RESTRICTED;中间不能有 DML 或 job 启动 - 手动验证:以
/ AS SYSDBA连入,运行@?/rdbms/admin/utlu19i.sql,观察输出末尾是否有Oracle Database 19c Post-Upgrade Status Tool和Component Status表格——这是 DBUA 实际依赖的输出结构 - 如果看到
ERROR at line 1: ORA-00942,大概率是catuppst.sql没被 DBUA 自动触发,此时需手动运行(但仅限预检阶段,勿在真实升级中提前执行)
RMAN DUPLICATE 不适用:DBUA 预检要求数据文件物理路径与源库一致或可映射
用 DUPLICATE TARGET DATABASE TO ... 创建辅助实例看似省事,但 DBUA 预检时会校验 V$DATAFILE 中的路径是否能在新环境中访问。若源库路径是 /u01/oradata/prod/users01.dbf,而 DUPLICATE 映射成了 /u02/oradata/test/users01.dbf,DBUA 会跳过空间评估、字符集兼容性等关键项,直接报 Pre-upgrade checks failed: Datafile path mismatch(非标准错误码,但日志里明确写 path mismatch)。
实操建议:
- RESTORE 时用
SET NEWNAME+SWITCH DATABASE TO COPY,而非 DUPLICATE;目标路径尽量与源库相同(哪怕只是符号链接),例如ln -s /backup/prod /u01/oradata/prod - 如果实在无法复刻路径,必须在 RESTORE 后、OPEN 前,用
ALTER DATABASE RENAME FILE逐个修正V$DATAFILE记录,并确认DBA_DATA_FILES中的FILE_NAME字段已更新 - 检查
V$TABLESPACE的BLOCK_SIZE是否与目标版本兼容(如源库 8K 表空间在 19c 中仍支持,但 16K 可能触发警告),这个值在 DUPLICATE 时不会变,但 DBUA 会读取并判断
预检通过 ≠ 升级一定成功,最关键的漏检点是隐式 NLS 参数和 PL/SQL 编译状态
DBUA 预检能发现 WRONG_CHARSET 或 INVALID_OBJECTS,但不会检查 NLS_LENGTH_SEMANTICS=CHAR 这种隐式设置是否导致升级后 VARCHAR2 列实际长度超限;也不会重新编译所有 INVALID 的 PL/SQL,而只是记录数量——这意味着预检报告写着 “0 invalid objects”,但 SELECT * FROM ALL_OBJECTS WHERE STATUS = 'INVALID' 在 OPEN RESTRICTED 下仍可能返回结果,因为编译器尚未触发。
所以真正要盯住的只有两件事:一是源库 NLS_DATABASE_PARAMETERS 里所有 NLS_* 值,在辅助实例中是否被 SPFILE 显式继承(尤其 NLS_NCHAR_CONV_EXCP=TRUE 缺失会导致升级中途报错);二是手动跑一遍 UTLIRP.SQL + UTLIPKG.SQL,否则 DBUA 的 “PL/SQL valid” 结论只是静态扫描,不反映真实可执行状态。

















