recover table 不支持表级恢复,需通过辅助实例和data pump离线重建,且必须连接cdb$root,时间点须早于误操作scn,依赖完整归档链与充足空间,rac环境不可用,优先考虑回收站或flashback database。
不能直接“表级恢复”,recover table 是一套离线重建流程,必须走辅助实例 + data pump 路径,原库虽不停机,但资源开销大、限制多、易失败。
RECOVER TABLE 必须连 CDB$ROOT 才生效
哪怕你要恢复的是 PDB 里的表,RMAN 也只认 CDB$ROOT。连错 PDB 会静默失败或报 ORA-65096、ORA-19554。
确认当前连接容器:SELECT SYS_CONTEXT('USERENV', 'CON_NAME') FROM DUAL; 返回值必须是 CDB$ROOT。
常见错误操作:
- 用 tnsnames.ora 连了 PDB 的服务名(如 myapp_pdb),而不是 CDB 的服务名(如 orcl)
- ORACLE_SID 指向的是 PDB 名(如 myapp),而非 CDB 实例名(如 orcl)
- OS 用户不是 oracle,导致权限不足或环境变量未加载
时间点必须早于 DROP/TRUNCATE 的 SCN
一旦过了误操作的 SCN,数据字典里表定义就没了,RECOVER TABLE 会找不到对象,最终报 ORA-19921: no archive log found 或导出为空。
查误操作 SCN 最可靠方式是 LogMiner:
EXEC DBMS_LOGMNR.START_LOGMNR(OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG + DBMS_LOGMNR.COMMITTED_DATA_ONLY);
然后查 V$LOGMNR_CONTENTS 中 OPERATION = 'DROP' 或 'TRUNCATE' 对应的 SCN。
别依赖 DBA_LOGSTDBY_LOG —— 它只在开了逻辑备库时才有记录。
归档日志链必须完整:缺失关键 DDL 前后那几个归档(比如 sequence# = 11 和 12),恢复会在应用日志阶段卡住,不报错但不动。
AUXILIARY DESTINATION 空间不够就直接失败
RECOVER TABLE 底层会还原整个 CDB(含所有 PDB)到目标时间点,不是只还原一张表。磁盘空间需求 ≈ 当前 PDB 数据文件总大小 × 2(含临时文件、redo、controlfile 复本)。
RMAN 不提前校验空间,直到启动辅助实例才报 ORA-19809,此时已浪费大量时间。
两个路径必须提前建好且分开:
- AUXILIARY DESTINATION:放辅助实例的数据文件
- DATAPUMP DESTINATION:放 .dmp 文件,避免 I/O 竞争
RAC 环境下该命令天然不可用——辅助实例是单机进程,与 OCR、ASM、集群心跳冲突,强行运行大概率报 ORA-19566 或辅助实例起不来。
真正能落地的恢复路径往往不是 RECOVER TABLE
如果没提前建保证型还原点(CREATE RESTORE POINT before_drop GUARANTEE FLASHBACK DATABASE),RECOVER TABLE 会直接报 ORA-65086: cannot recover table without restore point。
更现实的抢救顺序是:
- 先查回收站:SELECT * FROM RECYCLEBIN WHERE ORIGINAL_NAME = 'YOUR_TABLE';,存在就 FLASHBACK TABLE "BIN$xxx" TO BEFORE DROP
- 回收站已清空?检查是否有近期 expdp 备份,或能否用 FLASHBACK DATABASE 回退
- 都没有?那就得走传统 PITR:用 RMAN RESTORE DATABASE UNTIL TIME + RECOVER DATABASE UNTIL TIME 启一个只读副本,再用 expdp 带 FLASHBACK_TIME 导出表
最易被忽略的细节是归档日志路径匹配——新机上 log_archive_dest_1 目录不存在,或归档文件名格式(如 %t_%s_%r.dbf vs %t_%s.dbf)不一致,RMAN recover 阶段就会卡住。











