ora-01187是因异机恢复后控制文件仍保留源库临时文件路径导致校验失败,需用alter database tempfile drop删除无效记录,再用alter tablespace add tempfile在有效路径重建,不可依赖rman备份或复制原文件。

异机恢复后查询 dba_temp_files 报 ORA-01187
这不是备份没包含临时文件的问题,而是路径映射失效导致的校验失败。RMAN 异机恢复时,控制文件里仍存着原库的 temp01.dbf 路径(比如 /oradata/old_db/temp01.dbf),但目标机上该路径要么不存在、要么权限不对、要么磁盘空间不足——Oracle 启动时尝试读取这个“已记录但不可达”的文件,就抛出 ORA-01187: cannot read from file because it failed verification tests。
注意:此时数据库能 OPEN,v$tempfile 里还能看到该文件记录且状态是 ONLINE,但实际已无法分配临时段,后续任何 ORDER BY、GROUP BY 或哈希连接都会触发 ORA-01652。
- 别去查 RMAN 备份里有没有 tempfile —— 它压根不备份,
BACKUP DATABASE默认跳过所有TEMPFILE - 别在目标机手动复制原
temp01.dbf文件过来 —— 即使文件存在,Oracle 也不会用;临时文件必须由 SQL 命令重建 - 先确认当前默认临时表空间名:
SELECT PROPERTY_VALUE FROM DATABASE_PROPERTIES WHERE PROPERTY_NAME = 'DEFAULT_TEMP_TABLESPACE';
ALTER DATABASE TEMPFILE ... DROP 执行失败或卡住
常见于目标库已有活跃会话正在使用该临时文件。Oracle 不允许直接 DROP 正在被分配段的 TEMPFILE,命令会 hang 住或报 ORA-01148(文件正忙)。
实操建议:
- 查是否有残留临时段:
SELECT TABLESPACE_NAME, SESSION_ADDR FROM V$SORT_SEGMENT WHERE TABLESPACE_NAME = 'TEMP'; - 对应查这些会话是否还活跃:
SELECT SID, SERIAL#, STATUS, PROGRAM FROM V$SESSION WHERE SADDR IN (SELECT SESSION_ADDR FROM V$SORT_SEGMENT WHERE TABLESPACE_NAME = 'TEMP'); - 若会话已断连但段未释放(
STATUS为INACTIVE或查不到对应V$SESSION记录),可安全执行:ALTER DATABASE TEMPFILE '/old/path/temp01.dbf' DROP INCLUDING DATAFILES; - 若仍有活跃会话,优先杀掉:
ALTER SYSTEM KILL SESSION 'sid,serial#';,再重试DROP
重建临时文件时路径或权限出错
最常踩的坑是:误用原路径重建,但目标机该路径所属目录不存在、Oracle 用户无写权限、或磁盘已满。此时 ALTER TABLESPACE temp ADD TEMPFILE 会直接报 ORA-25153 或 ORA-01119,而不是静默失败。
正确做法:
- 指定一个明确存在、Oracle 进程有写权限、且空间充足的路径,例如:
ALTER TABLESPACE temp ADD TEMPFILE '/u02/oradata/ORCL/temp02.dbf' SIZE 100M AUTOEXTEND ON NEXT 64M; - 不要依赖
REUSE关键字试图复用原路径 —— 若原文件已删但目录权限异常,REUSE仍会失败 - 建完后立刻验证:
SELECT FILE_NAME, BYTES/1024/1024 MB FROM DBA_TEMP_FILES WHERE TABLESPACE_NAME = 'TEMP';,确保行数 > 0 且大小符合预期
应用连接池仍报 ORA-01652,但数据库层面已正常
临时文件重建成功后,旧连接可能还绑定着已失效的临时表空间句柄。尤其 Tomcat、WebLogic 等连接池默认缓存连接,不会自动感知底层临时表空间变更。
这意味着:
- 新连接执行排序没问题,老连接仍卡在
ORA-01652 -
V$SESSION里看这些会话的TEMPSEG_SIZE可能为 0,SQL_ID卡在解析阶段 - 重启应用服务或清空连接池(如 Tomcat 的
removeAbandonedOnBorrow=true配置)才能彻底解决
真正容易被忽略的是:临时表空间不是“恢复”出来的,而是“替换”出来的。整个过程不依赖任何备份介质,只靠 SQL 操作和路径控制。只要路径写对、权限给足、旧文件清理干净,问题就解了一大半。剩下那点连接残留,不是数据库问题,是中间件缓存问题。











