RECOVER TABLE 是 Oracle 12c 起唯一原生表级恢复手段,需归档完整、备份可用、时间点准确;TRUNCATE 不生成行级 undo,故 AS OF TIMESTAMP 查不到数据;必须连 CDB$ROOT、显式指定充足空间的 AUXILIARY DESTINATION、选对早于 TRUNCATE 的时间点;恢复后需手动重建索引等对象;无归档备份时应转向块级恢复工具。

RECOVER TABLE 是 Oracle 12c 起支持的唯一原生、可落地的表级恢复手段,前提是归档完整、备份可用、时间点准确——其他所谓“闪回查询”“闪回表”对 TRUNCATE 完全无效。
为什么 AS OF TIMESTAMP 查不到 TRUNCATE 前的数据
TRUNCATE 是 DDL,不生成行级 undo,只重置段头和高水位线(HWM)。这意味着:
-
SELECT * FROM t AS OF TIMESTAMP ...语法合法,但返回空结果——不是报错,是底层根本没存 -
UNDO_RETENTION再大也没用,TRUNCATE不走 undo 流程 - 常见错误
ORA-01466: unable to read data - table definition has changed往往是误以为能闪回,实际是表结构在闪回窗口内被改过
RECOVER TABLE 必须连 CDB$ROOT 才生效
哪怕你要恢复的是 PDB1.HR.EMPLOYEES,RMAN 也只在根容器协调辅助实例。连错容器会静默失败:
- 检查当前容器:
SELECT SYS_CONTEXT('USERENV', 'CON_NAME') FROM DUAL;—— 必须返回CDB$ROOT - 别用 PDB 的服务名连接(如
myapp_pdb),要用 CDB 实例名(如orcl) - 别设
ORACLE_SID=myapp,得是 CDB 实例名(orcl) - 错误现象:命令执行后 RMAN 立即退出、无日志、无文件生成、表也没回来——八成是连错了容器
AUXILIARY DESTINATION 必须显式指定且空间充足
RMAN 不校验空间,直到启动辅助实例才报错,此时已浪费大量时间。关键要求:
- 路径必须显式指定:
AUXILIARY DESTINATION '/u01/oradata/aux',不写就卡住 - Oracle OS 用户要有读写权限:
chown oracle:oinstall /u01/oradata/aux && chmod 755 /u01/oradata/aux - 可用空间 ≥ 目标 PDB 所有数据文件总大小的 2–3 倍(含控制文件、临时表空间、redo 复本)
- 不能是 ASM 路径(除非你明确配置了 ASM alias 支持)
- 务必与
DATAPUMP DESTINATION分开,避免 I/O 竞争
时间点选错会导致静默失败或导出为空
目标时间必须早于 TRUNCATE 的 SCN,且建议留至少 3 分钟余量:
- 别依赖
DBA_OBJECTS.LAST_DDL_TIME,它可能被后续 DDL 覆盖 - 查统一审计日志最可靠:
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%'; - 如果归档缺失关键序列(比如
TRUNCATE前后那几个),会卡在ORA-19921: no archive log found - 恢复后必须手动重建索引、约束、触发器,并收集统计信息——RMAN 不还原
TRUNCATE后新增的对象
没有归档、没有备份时,RECOVER TABLE 就走不通。这时候再花时间调参数、换路径,不如立刻转向 FY_Recover_Data 这类基于数据块嫁接的工具包——但它依赖 truncate 后未被覆盖的原始数据块,越早操作成功率越高。











