必须在cdb$root执行recover table,因rman依赖根容器协调辅助实例;目标时间须早于truncate scn且留3分钟余量;auxiliary destination须显式指定、空间充足且非asm;恢复后需手动重建索引、约束、触发器并收集统计信息。

必须在 CDB$ROOT 容器下执行 RECOVER TABLE,且目标时间点要早于 TRUNCATE 的 SCN,否则恢复会静默失败或报 ORA-19554、ORA-65096。
为什么必须连 CDB$ROOT 而不是 PDB?
Oracle 12c 的 RECOVER TABLE 是基于辅助实例(auxiliary instance)的机制,RMAN 需要在根容器中协调整个流程。哪怕你要恢复的是 PDB1.SALES.ORDER_ITEMS,也必须用 rman target / 连到 CDB 实例,并确认当前容器是 CDB$ROOT:
SELECT SYS_CONTEXT('USERENV', 'CON_NAME') FROM DUAL; 返回值必须是 CDB$ROOT;如果返回的是某个 PDB 名,命令不会报错,但实际不触发任何恢复动作。
常见错误现象:执行完 RECOVER TABLE ... 后 RMAN 立即退出、无日志、无文件生成、表也没回来——八成是连错了容器。
UNTIL TIME 时间点怎么选才安全?
TRUNCATE 是 DDL,它修改 DBA_OBJECTS.LAST_DDL_TIME,但这个字段可能被后续 DDL 覆盖。更可靠的方式是结合 LogMiner 或统一审计日志定位精确时间戳:
- 查统一审计:
SELECT event_timestamp, sql_text FROM unified_audit_trail WHERE sql_text LIKE 'TRUNCATE%TABLE%YOUR_TABLE%' ORDER BY event_timestamp DESC; - 查 LogMiner:
SELECT timestamp, sql_redo FROM v$logmnr_contents WHERE sql_redo LIKE 'TRUNCATE%TABLE%YOUR_TABLE%';
建议目标时间至少比误操作时间早 3 分钟,避开归档日志切换边界。如果归档缺失关键序列(尤其是 TRUNCATE 前后那几个),会卡在 ORA-19921: no arc。
AUXILIARY DESTINATION 必须显式指定且空间充足
不指定 AUXILIARY DESTINATION,RMAN 会在 “creating auxiliary instance” 阶段卡住,错误信息模糊,容易误判为权限或网络问题。
该路径需满足:
- Oracle OS 用户有读写权限:
chown oracle:oinstall /u01/oradata/aux && chmod 755 /u01/oradata/aux - 可用空间 ≥ 被恢复 PDB 所有数据文件总大小的 2–3 倍(辅助实例要重建控制文件、临时表空间、并导入导出)
- 不能是 ASM 路径(除非你明确配置了 ASM alias 支持)
示例命令:RECOVER TABLE HR.EMPLOYEES UNTIL TIME "TO_DATE('20260825 142700','yyyymmdd hh24miss')" AUXILIARY DESTINATION '/u01/oradata/aux';
恢复后必须手动重建索引、约束和触发器
RECOVER TABLE 默认只恢复表数据和基本结构(列定义、主键约束),但不会自动重建以下对象:
- 普通索引(包括唯一索引、函数索引)
- 外键约束(即使主表存在,外键定义也不会还原)
- 触发器、物化视图日志、统计信息
恢复完成后,务必检查 DBA_INDEXES 和 DBA_CONSTRAINTS,补建缺失对象。如果原表有大量索引,建议提前导出 DDL:SELECT DBMS_METADATA.GET_DDL('INDEX', index_name, owner) FROM dba_indexes WHERE table_name = 'EMPLOYEES' AND owner = 'HR';
最易被忽略的一点:恢复后的表默认不带统计信息,可能导致执行计划突变。别忘了跑一次 DBMS_STATS.GATHER_TABLE_STATS。











