oracle 19c临时表空间必须显式指定extent management local,否则报ora-02153;切换默认临时表空间前须确认v$sort_usage无活跃排序段,且需手动更新dba_users中用户的temporary_tablespace字段。

Oracle 19c 中临时表空间必须是本地管理(LOCAL)的,不能用字典管理(DICTIONARY);创建时若漏写 EXTENT MANAGEMENT LOCAL,语句会静默失败或报 ORA-02153(仅适用于 19c 及以后版本的严格校验)。
CREATE TEMPORARY TABLESPACE 必须显式指定 LOCAL
Oracle 19c 默认要求临时表空间使用本地管理方式,但语法上不自动补全 —— 如果你只写 CREATE TEMPORARY TABLESPACE temp2 TEMPFILE '/path/to/t2.dbf' SIZE 1G,Oracle 会报错:ORA-02153: invalid VALUES clause 或直接拒绝执行(取决于补丁级别)。这是因为 19c 强制要求明确声明区管理方式。
正确写法必须包含 EXTENT MANAGEMENT LOCAL:
CREATE TEMPORARY TABLESPACE temp2 TEMPFILE '+DATADG01' SIZE 1G EXTENT MANAGEMENT LOCAL;
注意:AUTOEXTEND 可选,但生产环境建议关掉(AUTOEXTEND OFF),避免临时文件无节制增长掩盖真实排序压力。
- 不写
EXTENT MANAGEMENT LOCAL→ 报错或静默失败,不是兼容性问题,是强制策略 - 写成
EXTENT MANAGEMENT DICTIONARY→ 直接报ORA-01221:无法将数据文件设为字典管理临时表空间 - ASM 路径(如
+DATADG01)无需指定文件名,Oracle 自动命名;文件系统路径则必须带后缀(如/u01/oradata/ORCL/temp2_01.dbf)
ALTER DATABASE DEFAULT TEMPORARY TABLESPACE 切换前要确认无活跃使用
切换默认临时表空间不是“改个参数就完事”。如果旧表空间(如 TEMP)仍有会话在用其临时段,ALTER DATABASE DEFAULT TEMPORARY TABLESPACE temp2 虽能成功,但后续删旧表空间时必卡在 ORA-60100。
真正要盯的是实时使用状态,不是“有没有会话连上来”,而是“有没有正在用临时段”:
- 查活跃排序段:
SELECT sid, serial#, username, sql_id FROM v$session WHERE tempseg_used > 0 AND tablespace = 'TEMP'—— 结果非空就不能删 - 查具体排序对象:
SELECT * FROM v$sort_usage,重点关注SEGTYPE = 'SORT'且TABLESPACE是旧名的行 - 不要依赖
v$session.status = 'ACTIVE',很多长事务中排序已结束但临时段未释放,tempseg_used才是关键指标
DROP TABLESPACE temp INCLUDING CONTENTS AND DATAFILES 容易被 ORA-60100 阻塞
ORA-60100 不是权限或语法错误,是 Oracle 内部保护机制:只要控制文件里还登记着某个 session 曾经分配过该表空间的 sort segment,就拒绝删除。硬杀会话(ALTER SYSTEM KILL SESSION)可能引发实例级锁争用,尤其在 RAC 环境下风险更高。
安全做法是“等它自己释放”,而不是强推:
- 先切默认:
ALTER DATABASE DEFAULT TEMPORARY TABLESPACE temp2 - 轮询检查:
SELECT COUNT(*) FROM v$sort_usage WHERE tablespace = 'TEMP',直到返回 0 - 若长时间不归零,检查是否有长 SQL(如大表
ORDER BY、GROUP BY、建索引)未结束;可结合v$sql查sql_text和elapsed_time - 极少数情况需重启 PDB(非 CDB),比硬杀更可控 —— 但这是兜底手段,不是首选
重建后用户 TEMPORARY TABLESPACE 不自动更新
即使你把数据库默认临时表空间改回 TEMP,已有用户的 TEMPORARY_TABLESPACE 字段仍指向旧值(比如 TEMP2 或空),DBA_USERS 视图里不会同步刷新。
这意味着:用户下次登录执行排序操作,仍会去用旧表空间,可能触发 ORA-01652(无法扩展临时段),哪怕新 TEMP 已建好。
- 查谁没更新:
SELECT username, temporary_tablespace FROM dba_users WHERE temporary_tablespace NOT IN ('TEMP', 'SYSTEM') - 逐个修正:
ALTER USER scott TEMPORARY TABLESPACE TEMP - 不能用
ALTER USER ... DEFAULT TABLESPACE代替,那个管的是永久表空间 - 脚本化处理建议:
SELECT 'ALTER USER ' || username || ' TEMPORARY TABLESPACE TEMP;' FROM dba_users WHERE temporary_tablespace != 'TEMP' AND account_status = 'OPEN';
真正麻烦的从来不是建表空间那几条命令,而是没人盯着 v$sort_usage 和 dba_users.temporary_tablespace 这两个地方。一个漏查,一个漏改,重建就白做了。











