暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle TEMP文件报 ORA-01187 / ORA-01110 的处理案例

原创 孙莹 7小时前
12

Oracle TEMP文件报 ORA-01187 / ORA-01110 的处理案例

一、故障现象

接到客户电话反馈说查询视图报错:

ORA-01187: 由于验证测试失败而无法从文件读取 ORA-01110: 数据文件 201: '/u01/app/oracle/oradata/WMPROD/temp01.dbf'

ORA01187.png

这类报错容易误判为普通数据文件损坏。实际上,如果 ORA-01110 指向的是 临时文件 tempfile,处理思路不要做 recover datafile。
TEMP 文件不保存业务数据,标准处理是重建临时表空间。

二、处理过程

检查 TEMP 当前使用率

先看 TEMP 表空间总量、已用、剩余、使用率

set lines 300 pages 1000 col tablespace_name for a20 select tablespace_name, round(sum(bytes_used + bytes_free) / 1024 / 1024 / 1024, 2) total_gb, round(sum(bytes_used) / 1024 / 1024 / 1024, 2) used_gb, round(sum(bytes_free) / 1024 / 1024 / 1024, 2) free_gb, round(sum(bytes_used) / nullif(sum(bytes_used + bytes_free),0) * 100, 2) used_pct from v$temp_space_header group by tablespace_name order by tablespace_name;

本次现场查询结果类似:

TABLESPACE_NAME TOTAL_GB USED_GB FREE_GB USED_PCT -------------------- ---------- ---------- ---------- ---------- TEMP 32 32 0 100.00

继续查 tempfile 明细:

set lines 300 pages 1000 col tablespace_name for a20 col file_name for a120 col autoextensible for a15 select tablespace_name, file_id, file_name, round(bytes / 1024 / 1024 / 1024, 2) size_gb, autoextensible, round(maxbytes / 1024 / 1024 / 1024, 2) max_gb, status from dba_temp_files order by tablespace_name, file_id;

输出查询结果:

TEMP 1 /u01/app/oracle/oradata/WMPROD/temp01.dbf 32G YES 32G ONLINE

这里有一个关键判断:temp01.dbf 显示 AUTOEXTENSIBLE=YES,但是 MAX_GB=32。说明它已经到最大值,实际上不能继续扩展。

重建临时表空间

1. 创建新临时表空间

create temporary tablespace TEMP_NEW tempfile '/u01/app/oracle/oradata/WMPROD/temp_new01.dbf' size 31G autoextend off;

再添加第二个 tempfile:

alter tablespace TEMP_NEW add tempfile '/u01/app/oracle/oradata/WMPROD/temp_new02.dbf' size 31G autoextend off;

2. 切换数据库默认临时表空间

先确认当前默认 TEMP:

select property_name, property_value from database_properties where property_name = 'DEFAULT_TEMP_TABLESPACE';

切换:

alter database default temporary tablespace TEMP_NEW;

再次确认:

select property_name, property_value from database_properties where property_name = 'DEFAULT_TEMP_TABLESPACE';

结果:

DEFAULT_TEMP_TABLESPACE TEMP_NEW

3. 检查是否还有用户配置旧 TEMP

set lines 300 pages 1000 col username for a30 col temporary_tablespace for a30 col account_status for a30 select username, temporary_tablespace, account_status from dba_users where temporary_tablespace = 'TEMP' order by username;

如果还有业务用户使用旧 TEMP,例如 WMPROD

alter user WMPROD temporary tablespace TEMP_NEW;

也可以批量生成:

set pages 0 lines 300 feedback off heading off verify off select 'alter user "' || username || '" temporary tablespace TEMP_NEW;' from dba_users where temporary_tablespace = 'TEMP' order by username;

本次处理时,切换默认临时表空间后,查询 dba_users where temporary_tablespace='TEMP' 已经没有记录,说明新会话默认会走 TEMP_NEW

删除旧 TEMP 表空间

切换完成后尝试删除旧 TEMP:

drop tablespace TEMP including contents and datafiles;

如果报:

ORA-60100: dropping temporary tablespace with tablespace ID number (...) is blocked due to sort segments

说明旧 TEMP 仍有 sort segment 或老会话残留。查 gv$sort_segment

set lines 300 pages 1000 col tablespace_name for a20 select inst_id, tablespace_name, current_users, total_extents, used_extents, free_extents, round(used_blocks * 8192 / 1024 / 1024, 2) used_mb, round(free_blocks * 8192 / 1024 / 1024, 2) free_mb from gv$sort_segment where tablespace_name = 'TEMP' order by inst_id, tablespace_name;

本次现场结果是:

INST_ID TABLESPACE_NAME CURRENT_USERS TOTAL_EXTENTS USED_EXTENTS FREE_EXTENTS USED_MB FREE_MB ------- --------------- ------------- ------------- ------------ ------------ ------- ------- 1 TEMP 1018 33544 1023 32521 1023 32521

这说明旧 TEMP 上仍有 1018 个使用者,不能删除。随后查询 gv$tempseg_usage 也能看到大量 WMPRODINACTIVE JDBC 连接仍然挂在旧 TEMP 上。

继续查旧 TEMP 的会话来源:

set lines 300 pages 1000 col username for a20 col machine for a35 col program for a45 col status for a15 select s.username, s.machine, s.program, s.status, count(*) session_count, round(sum(u.blocks * p.value)/1024/1024,2) temp_mb from gv$tempseg_usage u join gv$session s on u.inst_id = s.inst_id and u.session_addr = s.saddr join gv$parameter p on p.inst_id = u.inst_id and p.name = 'db_block_size' where u.tablespace = 'TEMP' group by s.username, s.machine, s.program, s.status order by session_count desc;

处理选择:

场景 建议
业务允许重启应用 重启应用连接池,让老连接释放旧 TEMP
业务允许 kill 会话 生成 kill 语句清理旧 TEMP 会话
不允许影响业务 保留旧 TEMP,等低峰窗口重启数据库

生成 kill 语句示例,RAC 环境要带 ,@inst_id

set lines 300 pages 0 heading off feedback off verify off spool /tmp/kill_old_temp_sessions_rac.sql select distinct 'alter system kill session ''' || s.sid || ',' || s.serial# || ',@' || s.inst_id || ''' immediate;' from gv$tempseg_usage u join gv$session s on u.inst_id = s.inst_id and u.session_addr = s.saddr where u.tablespace = 'TEMP' and s.username = 'WMPROD' and s.status = 'INACTIVE'; spool off

清理后再次确认:

select count(*) old_temp_sessions from gv$tempseg_usage where tablespace = 'TEMP'; select inst_id, tablespace_name, current_users, used_extents, round(used_blocks * 8192 / 1024 / 1024, 2) used_mb from gv$sort_segment where tablespace_name = 'TEMP';

如果 current_users=0,再执行:

drop tablespace TEMP including contents and datafiles;

把 TEMP_NEW 改回 TEMP

旧 TEMP 删除成功后,为了兼容历史脚本、监控和巡检习惯,建议把 TEMP_NEW 改回 TEMP

alter tablespace TEMP_NEW rename to TEMP;

确认默认临时表空间:

select property_name, property_value from database_properties where property_name = 'DEFAULT_TEMP_TABLESPACE';

如果仍显示 TEMP_NEW,再执行:

alter database default temporary tablespace TEMP;

最终确认:

set lines 300 pages 1000 col tablespace_name for a20 col file_name for a120 select tablespace_name, file_id, file_name, round(bytes/1024/1024/1024,2) size_gb, status from dba_temp_files order by tablespace_name, file_id;

期望结果:

TABLESPACE_NAME FILE_ID FILE_NAME SIZE_GB STATUS -------------------- ---------- ------------------------------------------------------------ ---------- ---------- TEMP 1 /u01/app/oracle/oradata/WMPROD/temp_new01.dbf 31 ONLINE TEMP 2 /u01/app/oracle/oradata/WMPROD/temp_new02.dbf 31 ONLINE

三、最终结论

ORA-01187 / ORA-01110 如果指向 TEMP 文件,本质上是 临时文件不可读或校验失败,不是业务数据损坏。处理重点重建临时表空间 TEMP_NEW 并切换默认临时表空间,旧 TEMP 因老连接和 sort segment 残留无法立即删除,最终需要释放老连接/重启后删除,并把 TEMP_NEW 改回 TEMP

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论