oracle 21c中local temporary tablespaces自9i起已存在,优化核心是隔离负载以避免争用、i/o瓶颈和ora-1652错误;需按业务模块、用户角色或存储性能显式划分并绑定,禁用default_temp_tablespace滥用,且须验证会话级实际使用情况。
oracle 21c 中 local temporary tablespaces 不是新功能,而是自 9i 起就存在的标准机制;所谓“优化临时段分配”,核心在于避免争用、减少 i/o 延迟、防止 ora-1652,而不是靠启用某个开关就能自动解决。
为什么不能只依赖一个 TEMP 表空间
默认的 TEMP 表空间被所有用户共享,当多个会话同时执行大排序(如 ORDER BY、GROUP BY)、哈希连接或并行查询时,临时段分配会集中在同一组临时文件上,引发:
- 文件级争用:多个进程竞争同一
tempfile的 extent 分配锁 - 单点 I/O 瓶颈:尤其在机械盘或未做条带化的存储上,吞吐迅速见顶
- 扩展失败风险:即使总空间充足,
autoextensible无法及时响应突发请求,仍可能报ORA-1652: unable to extend temp segment
如何合理划分 Local Temporary Tablespaces
关键不是“越多越好”,而是按负载特征隔离。实际中建议按以下维度拆分:
- 按业务模块:例如
TEMP_APP1专供报表服务,TEMP_APP2专供 ETL 批处理 - 按用户角色:DBA 维护任务、应用连接池用户、ETL 调度账号各用独立表空间
- 按性能层级:高速 NVMe 存储挂
TEMP_FAST,普通 SAS 盘挂TEMP_SLOW,通过ALTER USER ... TEMPORARY TABLESPACE显式绑定
创建示例:
CREATE TEMPORARY TABLESPACE temp_app1 TEMPFILE '/oradata/prod/temp_app1_01.dbf' SIZE 2G AUTOEXTEND ON NEXT 512M MAXSIZE 16G;
绑定用户:
ALTER USER report_user TEMPORARY TABLESPACE temp_app1;
必须关闭的两个危险配置
即便用了多个临时表空间,以下两项若开启,仍会导致争用回归单点:
-
DEFERRED_SEGMENT_CREATION = TRUE(默认值):虽对永久段友好,但临时段分配不走此路径,无需调整 -
UNIFORM SIZE在临时表空间中无效——Oracle 强制使用SYSTEM管理方式,所以建表空间时不要写EXTENT MANAGEMENT LOCAL UNIFORM SIZE,否则报错 - 最关键的是:不要给多个临时表空间设置相同的
DEFAULT_TEMP_TABLESPACE。数据库只有一个默认值,它只是新用户未显式指定时的 fallback,不能实现分流
验证是否真正在用目标临时表空间
别只看 DBA_TEMP_FILES 是否存在,要查实时分配行为:
- 检查会话当前使用的表空间:
SELECT s.sid, s.username, u.tablespace, u.segtype, u.blocks * 8 / 1024 AS mb_used FROM v$session s, v$sort_usage u WHERE s.saddr = u.session_addr AND u.tablespace = 'TEMP_APP1';
- 确认 SQL 实际走的是哪个临时段:结合
V$SQL的SQL_ID和V$TEMPSEG_USAGE关联,注意SEGTYPE = 'SORT'或'HASH'才是真实消耗点 - 如果发现大量会话仍落在默认
TEMP上,说明应用连接未执行ALTER SESSION SET CURRENT_SCHEMA或未绑定用户级临时表空间
真正起效的临界点,往往卡在用户权限配置和连接池初始化脚本里——这点最容易被忽略。











