RMAN不能直接跨版本还原11g备份到19c实例,必须先在11g环境完成升级准备(如preupgrade检查、清回收站、编译无效对象),再用RMAN备份底片配合19c实例的STARTUP UPGRADE及catuppst.sql等升级脚本完成迁移。
RMAN 不能直接跨版本还原 11g 备份到 19c 实例——必须先在 11g 环境中完成升级准备,再用 RMAN 恢复到已安装 19c 软件的目标库。这是最常被忽略的前提,硬要跳过会导致 ORA-01222、ORA-01130 或控制文件无法识别等错误。
为什么不能直接 restore 11g backupset 到 19c instance
oracle 的 rman 备份集(backupset)本身是版本兼容的,但还原(restore)和恢复(recover)过程依赖目标实例的内核能力。19c 的 oracle_home 启动的实例不理解 11g 的数据字典结构、scn 格式、甚至某些块头字段语义。所以你看到的“rman restore to 19c”实际分两步:先在 11g 上升级数据库至 19c 兼容状态(即升级数据字典),再用 19c 实例启动并 recover。
- 直接
startup nomount+restore spfile/controlfile到空 19c 实例会失败:控制文件版本校验通不过 - 即使强行绕过(如用
CREATE CONTROLFILE),后续restore database也会报ORA-19870: error while restoring backup piece - 官方明确要求:目标端必须是已安装 19c 软件、且已创建好空实例(或 NOMOUNT 状态)的环境,但该实例不能直接读取 11g 数据文件——必须先完成升级流程
正确路径:RMAN + 升级助手(DBUA)或手动 upgrade 模式
核心不是“用 RMAN 恢复”,而是“用 RMAN 提供物理备份底片,配合升级流程完成迁移”。典型做法是:
- 在源 11g 库上运行
preupgrade.jar,生成检查报告和修复脚本(如清回收站、编译无效对象) - 停业务,将库置为
READ ONLY,执行最终 RMAN 全备(含归档+当前控制文件) - 把备份集拷到目标机 NFS 或本地路径,确保 19c
ORACLE_HOME下的rman可访问 - 在目标机用 19c
ORACLE_HOME启动空实例(NOMOUNT),restore spfile和controlfile(注意:此时控制文件仍是 11g 版本) - 用
ALTER DATABASE MOUNT挂载后,RESTORE DATABASE——这步成功,但数据文件仍属 11g 格式 - 关键动作:
STARTUP UPGRADE(不是STARTUP),然后运行@?/rdbms/admin/catuppst.sql等升级脚本,或调用dbua
此时 RMAN 的作用是提供“干净、一致的物理副本”,而真正的版本跃迁由升级过程完成。
常见卡点与绕过条件
如果你坚持走纯 RMAN 还原流(比如异机 + 不停机窗口极短),必须满足这些硬性条件:
- 源库必须是
11.2.0.4+(低于此版本需先打 PSU),否则preupgrade.jar不支持生成 19c 兼容脚本 - 目标端不能用 ASM 存储直接接收 11g 文件:11g 的 ASM 兼容属性(
compatible.asm)默认是11.2.0.0,19c 要求至少12.1.0.0,需提前用ALTER DISKGROUP ... SET ATTRIBUTE升级 -
RMAN备份时禁用压缩(as compressed backupset在部分 11g 版本中会导致 19c 恢复时报ORA-19505),改用AS BACKUPSET - 如果用了可传输表空间(TTS),注意
XTTS工具要求源端开启block change tracking,且增量同步前必须运行dbms_tdb.check_db验证外部对象
真正省时间的操作不是备份,是 preupgrade 阶段
实测中,一次 2TB 的 11g → 19c 迁移,RMAN 全备耗时约 4 小时,但 catuppst.sql + utlrp.sql 占了 5.5 小时。而很多人花 3 小时手工清理回收站、重编译对象、刷新物化视图,其实可以在 preupgrade 阶段就自动完成——只要在 preupgrade.jar 执行后,按它输出的 fixups.sql 和 postupgrade_fixups.sql 脚本顺序执行。
最容易被跳过的细节是:19c 默认启用 UNDO_RETENTION_GUARANTEE,而 11g 备份里没这个设置,升级后首次大事务可能触发 ORA-30036。得在 UPGRADE 模式下就手动 set 它,而不是等 open 后再改。











