导出RMAN恢复目录前必须停掉所有注册的target数据库;需先注销数据库、确认无RMAN会话、同步目录,再用Data Pump配合QUERY参数导出关键表,导入后必须运行catrman.sql重建视图和同义词,并处理DBID与RESETLOGS_ID冲突。
导出 RMAN 恢复目录前必须停掉所有注册的 target 数据库
恢复目录(rman catalog)本质是普通 oracle 数据库中的一个 schema,但它的数据被 rman 严格锁定管理。如果在导出过程中有 target 数据库仍在连接并执行 backup、delete obsolete 等操作,dbms_rcvcat 包内部会持续更新控制表(如 rc_backup_set),导致导出结果不一致甚至失败。
实操建议:
- 用
RMAN连接 catalog,执行LIST REGISTERED DATABASE;查出所有已注册 DBID - 逐个连接对应 target 数据库,运行
UNREGISTER DATABASE;(注意:这不会删备份集,只断开 catalog 关联) - 确认无活跃
RMAN会话:SELECT SID, SERIAL#, PROGRAM FROM V$SESSION WHERE PROGRAM LIKE '%rman%'; - 导出前再执行一次
EXEC DBMS_RCVCAT.SYNC_CATALOG;强制刷新内存状态到磁盘
用 Data Pump 导出 catalog schema 要加 QUERY 参数过滤大表
RC_BACKUP_PIECE 和 RC_BACKUP_SET 这两张表通常占 catalog schema 总体积 70% 以上,且含大量历史归档记录。直接 expdp 全量导出会慢、占空间、导入时易因 UNDO 不足报 ORA-01555。
实操建议:
- 优先导出最近 2 年数据:
QUERY=RC_BACKUP_PIECE:"WHERE COMPLETION_TIME > SYSDATE-730" - 跳过已删除备份的元数据(节省 30%+):
QUERY=RC_BACKUP_SET:"WHERE STATUS != 'D'" - 不要用
CONTENT=METADATA_ONLY—— catalog 的核心就是数据,不是结构 - 导出命令示例:
expdp catalog_user/password@catalog_db \ SCHEMAS=CATALOG_USER \ DUMPFILE=catalog_2024.dmp \ QUERY=RC_BACKUP_PIECE:\"WHERE COMPLETION_TIME \> SYSDATE-730\" \ QUERY=RC_BACKUP_SET:\"WHERE STATUS != 'D'\" \ LOGFILE=expdp_catalog.log
导入后必须手动运行 catrman.sql 重建视图和同义词
Data Pump 导入只还原表、索引、约束等基础对象,但 RMAN catalog 依赖的视图(如 RC_DATABASE)、包(DBMS_RCVCAT)、同义词(RC_BACKUP_SET)不会自动重建。没它们,RMAN 连接新 catalog 后执行 LIST BACKUP 会报 ORA-00942: table or view does not exist。
实操建议:
- 导入完成后,用 catalog 用户登录新库,运行:
@?/rdbms/admin/catrman.sql
- 确认
DBMS_RCVCAT包状态为 VALID:SELECT OBJECT_NAME, STATUS FROM USER_OBJECTS WHERE OBJECT_NAME = 'DBMS_RCVCAT'; - 检查关键视图是否可查:
SELECT COUNT(*) FROM RC_DATABASE;(应返回原注册 DB 数) - 别跳过
@catrmans.sql—— 它补的是权限和角色绑定,漏了会导致 target 注册时报ORA-01031: insufficient privileges
target 数据库重新注册时要注意 DBID 冲突和 resetlogs ID
迁移后首次注册 target,RMAN 会校验 DBID + RESETLOGS_ID 组合是否唯一。如果旧 catalog 中残留了相同 DBID 的旧记录(比如你没清空或没加 QUERY 过滤),新注册会失败并提示 ORA-20001: Database already registered in recovery catalog。
实操建议:
- 注册前先查重:
SELECT DB_NAME, DBID, RESETLOGS_TIME FROM RC_DATABASE WHERE DBID = &your_dbid; - 若存在旧记录且确定废弃,用
UNREGISTER DATABASE删除;不确定就改用REGISTER DATABASE NOCHECK(需 12cR2+) - 确保 target 控制文件中
RESETLOGS_ID是最新值:SELECT RESETLOGS_ID FROM V$DATABASE;,否则 catalog 里会存两套时间线混乱的备份记录 - 注册后立刻
RESYNC CATALOG;,别等下次备份 —— 否则 catalog 缺失 controlfile 中的新 backup piece 记录
最麻烦的不是导出导入本身,而是 catalog 表里那些隐式依赖的时间戳、SCN、resetlogs 序列 —— 它们不像普通业务数据能随便 truncate 或 update,一动错整个恢复链就断了。










