smon卡住不清理临时段是因它仅在特定时机(如启动、扩展、每5分钟轮询)触发清理,且需获取st锁;若遇长事务、分布式事务挂起或并行查询残留,会等待或跳过,导致临时段延迟释放。
smon 为什么卡住不清理临时段
oracle 的 smon 进程负责自动清理死事务、合并空闲临时段等后台维护,但它不会“实时”清理——只在特定时机触发,比如数据库启动、表空间扩展、或周期性轮询(默认每5分钟)。如果你发现 temp 表空间里有大量未释放的临时段(dba_sort_segments 或 v$tempseg_usage 显示活跃但实际会话已断),大概率不是 smon 坏了,而是它还没轮到这次检查,或者被更高优先级任务阻塞。
-
SMON清理临时段前会先尝试获取ST(System Transaction)锁,如果此时有长事务、挂起的分布式事务(DBA_2PC_PENDING非空)、或异常终止的并行查询残留,SMON会等待或跳过 - 手动 kill 会话后,若客户端未正常断开连接(比如网络闪断但服务器端 socket 未超时),对应临时段可能标记为 “reusable” 但不会立刻回收——需等
SMON下次扫描识别 - 11g 及以后版本中,
_smu_debug_mode隐含参数设为 4 可让SMON输出更多清理日志(写入 trace 文件),但生产环境慎用
怎么确认临时段到底该不该清
别一看到 V$TEMPSEG_USAGE 有记录就急着清。先区分是“真残留”还是“合理占用”:临时段分两类——排序段(sort)和哈希段(hash),前者来自 ORDER BY/GROUP BY,后者来自大表哈希连接。只要对应会话还活着,这些段就是合法存在的。
- 查
V$SESSION和V$PROCESS,比对SID、SPID是否真实存活;STATUS = 'INACTIVE'且LAST_CALL_ET > 3600的会话,大概率是僵死的 - 执行
SELECT * FROM V$TEMPSEG_USAGE WHERE SESSION_NUM NOT IN (SELECT SID FROM V$SESSION),结果非空才说明存在孤儿临时段 - 注意
V$SORT_SEGMENT中USED_EXTENTS为 0 的段,可能是已释放但未从数据字典抹除的“幽灵段”,这类必须靠SMON主动清理,无法人工干预
强制清理临时段的可行手段
没有“直接删临时段”的 SQL 命令。Oracle 不允许你用 DROP 或 ALTER TABLESPACE ... DROP SEGMENT 操作临时段。唯一安全的强制路径,是重启 SMON 的清理逻辑,或重置临时表空间状态。
- 最稳妥:执行
ALTER TABLESPACE TEMP COALESCE—— 触发SMON立即扫描并合并相邻空闲区,顺带清理可回收段(注意:仅对本地管理的 LMT 表空间有效) - 较激进:重启数据库(
SHUTDOWN IMMEDIATE+STARTUP),SMON启动时会做一次全量清理,这是 Oracle 官方文档明确保证的行为 - 禁用再启用(风险高):
ALTER DATABASE TEMPFILE '/path/to/temp01.dbf' DROP INCLUDING DATAFILES再重建,会导致所有当前使用该 tempfile 的操作失败,仅限紧急且无业务影响时段
为什么 ALTER TABLESPACE TEMP SHRINK SPACE 不起作用
SHRINK SPACE 是针对永久表空间设计的命令,对临时表空间完全无效。执行 ALTER TABLESPACE TEMP SHRINK SPACE 会报错 ORA-10633: Non-existent segment or invalid tablespace,因为临时段不走段管理(segment management)那一套,它的空间由 TEMPFILE 的文件头结构 + 内存中的 sort extent pool 共同管理。
- 临时表空间的空间释放依赖于会话释放、
SMON扫描、以及DBWR刷脏块(如果有临时表缓存)——和永久表空间的 HWM(High Water Mark)机制完全不同 - 想看真实可用空间,别信
DBA_FREE_SPACE,改查V$TEMP_SPACE_HEADER里的FREE_SPACE字段 - 如果
TEMP表空间持续膨胀,优先排查是否用了GLOBAL TEMPORARY TABLE并忘记加ON COMMIT DELETE ROWS,导致数据长期滞留
临时段清理不是“手动删文件”,而是让 Oracle 自己意识到哪些空间可以复用。最常被忽略的是:SMON 的清理动作本身不记日志、不落数据字典变更,所以你永远看不到它“正在清理”的中间状态——只能看前后快照对比。一旦发现清理延迟,先查是否有分布式事务卡住,再查 SMON trace,而不是翻文档找“强制删除命令”。










