临时表空间满时不可直接删除,须先切换默认临时表空间:查使用率用dba_temp_files,查活跃排序段用v$sort_segment,定位占用会话用v$session与v$sort_usage关联查询,再创建新临时表空间、设为默认、迁移用户、最后drop旧表空间并清理物理文件。
临时表空间满了,不能直接删掉再重建——oracle 会拒绝删除正在被使用的临时表空间,强行操作会导致 ora-01652 或会话挂起。必须先切换默认临时表空间,再清理旧空间。
怎么查哪个临时表空间满了、被谁占着
先确认当前默认临时表空间和使用率:
SELECT tablespace_name, file_name, bytes/1024/1024 AS mb FROM dba_temp_files;
再看实际使用峰值(注意:v$temp_space_header 反映的是分配状态,v$sort_segment 才反映活跃排序段):
SELECT tablespace_name, segfile#, segblk#, blocks * 8 / 1024 AS mb_used FROM v$sort_segment;
查正在用临时表空间的大查询(尤其是没加 ORDER BY / GROUP BY 却消耗大量 temp 的 SQL):
SELECT s.sid, s.serial#, s.username, s.sql_id, t.blocks * 8 / 1024 AS mb_used FROM v$session s, v$sort_usage t WHERE s.saddr = t.session_addr;
- 如果
blocks持续不降,说明会话卡在大排序或哈希连接上,可能需要 kill 掉对应sid,serial# -
v$sort_usage为空但dba_temp_files显示已满?很可能是临时文件被 truncate 后未释放(常见于异常中断),需重启数据库或执行ALTER DATABASE TEMPFILE ... DROP INCLUDING DATAFILES(仅限非默认临时文件)
如何安全切换并重建临时表空间
不能直接删默认临时表空间,必须先建新空间、设为默认、再删旧的:
- 创建新临时表空间:
CREATE TEMPORARY TABLESPACE temp_new TEMPFILE '/u01/oradata/DB/temp_new01.dbf' SIZE 1G AUTOEXTEND ON NEXT 100M MAXSIZE 10G; - 切换默认临时表空间:
ALTER DATABASE DEFAULT TEMPORARY TABLESPACE temp_new; - 确认所有用户都指向新空间:
SELECT username, temporary_tablespace FROM dba_users WHERE temporary_tablespace = 'TEMP';;如有,逐个改:ALTER USER xxx TEMPORARY TABLESPACE temp_new; - 等所有活跃会话自然退出或手动 kill 后,再删旧空间:
DROP TABLESPACE temp INCLUDING CONTENTS AND DATAFILES;
注意:INCLUDING CONTENTS AND DATAFILES 是关键,否则只删字典信息,物理文件还在,磁盘不会释放。
重建后还要注意这些细节
重建不是一劳永逸,容易漏掉几个隐性问题:
- 监听器或应用连接串里硬编码了
TEMP表空间名?某些 JDBC 连接池(如 DBCP)会在初始化时查dba_users缓存默认临时表空间,重启应用更稳妥 - RMAN 备份脚本里是否包含
tempfile?不用备份,但若脚本写了INCLUDE TEMPFILE会报错,应去掉 - ASM 环境下路径要写
+DATA/db/temp_new01.dbf,不能用操作系统路径;且需确认 ASM diskgroup 有足够空闲 AU - 临时表空间无法 shrink,
ALTER DATABASE TEMPFILE ... RESIZE只能调大,不能调小——想减小就得重建
真正麻烦的不是重建动作本身,而是旧临时表空间被多个长事务、物化视图刷新、AWR 报告生成过程隐式占用,导致切换延迟。别光盯着 SQL,先盯 v$sort_usage 和 v$session 关联结果,才能知道“到底是谁不肯放手”。











