必须三步联动(set until time、restore database、recover database),因recover仅应用归档日志,要求数据文件检查点足够新;单独执行会因文件过旧报ora-01190/ora-01113。

不能只用 RECOVER DATABASE UNTIL TIME,必须配合 RESTORE DATABASE 和 SET UNTIL TIME 三步联动,否则必然报 ORA-01190 或 ORA-01113。
为什么单独执行 RECOVER DATABASE UNTIL TIME 会失败
RMAN 的 RECOVER DATABASE UNTIL TIME 不是“智能跳转”,它只应用归档日志到目标时间点,但前提是当前数据文件的检查点(checkpoint)已足够新——即数据文件本身已是某个较新备份的状态。生产环境中,你手头的数据库文件往往停留在上次全备时刻,远早于目标恢复时间,直接 recover 就会因“数据太旧”而拒绝执行。
常见错误现象:
ORA-01190: control file or data file is from before the last RESETLOGSORA-01113: file 1 needs media recovery-
v$datafile.checkpoint_time明显早于你指定的UNTIL TIME
SET UNTIL TIME 必须放在 RUN 块最开头
SET UNTIL TIME 不是独立命令,而是为后续所有 RESTORE 和 RECOVER 操作设定统一的时间边界。它只对当前 RUN 块生效,且必须在 RESTORE 和 RECOVER 之前设置。
正确写法示例:
run {
shutdown immediate;
startup mount;
set until time "to_date('2026-07-25 14:22:00', 'yyyy-mm-dd hh24:mi:ss')";
restore database;
recover database;
alter database open resetlogs;
}
容易踩的坑:
- 把
set until time放在restore后面 → 对restore不生效,还原出的仍是最新备份,而非目标时间点前的文件 - 用双引号包裹日期字符串,但格式与 NLS_DATE_FORMAT 不匹配 → RMAN 解析失败,报
RMAN-06004 - 日期字符串里混用单引号和双引号,如
'to_date(...)'→ 语法错误
时间精度依赖归档日志中的 timestamp
RMAN 时间点恢复不是毫秒级精确的。它靠归档日志里记录的 redo 时间戳推进,如果某分钟内没有 redo 写入,就只能停在上一个有时间戳的 commit 之后。比如指定 '2026-07-25 14:22:33',但最近一条日志 timestamp 是 14:22:28,那恢复就停在 14:22:28,而非你写的秒数。
因此:
- 尽量用分钟级时间(如
'2026-07-25 14:22:00'),避免纠结秒数 - 确认归档日志连续:用
list archivelog all;查看是否有缺口 - 误操作发生后立刻查
select to_char(sysdate, 'YYYY-MM-DD HH24:MI:SS') from dual;记下时间,别等几分钟后再回忆
真正容易被忽略的是数据库 incarnation 状态。每次 OPEN RESETLOGS 都会生成新 incarnation,后续若要回退到更早状态(比如第二次恢复想回到第一次恢复前),必须先用 RESET DATABASE TO INCARNATION n 切换上下文,否则 RMAN 找不到对应备份集。











