<p>enq: TS - contention 是唯一明确指向 Temp 表空间头块或位图块争用的ASH信号,源于多会话并发申请临时段时对 TS$ 或位图块的串行化更新锁等待。</p>
直接查 enq: TS - contention 事件最有效
ash 中唯一能明确指向 temp 表空间头块或位图块争用的信号就是 enq: ts - contention。这不是“临时段用得多”的表现,而是多个会话**同时申请分配新临时段**时,oracle 必须串行化更新 ts$ 或位图块导致的锁等待。它和 direct path write temp 完全不同:后者是溢出已发生,前者是分配路径卡住了。
实操建议:
- 必须加时间过滤:
SAMPLE_TIME > SYSDATE - 1/1440(最近1分钟),否则默认查全内存 buffer,容易超时或返回无效旧样本 - 只筛真实等待状态:
SESSION_STATE = 'WAITING',排除 ON CPU 或空闲会话干扰 - 别只看 EVENT 字段——
enq: TS - contention的P1是锁类型(TS),P2是文件号,P3是块号;若P2 = 1且P3 = 1,基本可断定是表空间头块(file#1, block#1)争用 - RAC 环境下务必检查
INST_ID和BLOCKING_INSTANCE,跨节点争用不会出现在本地V$SESSION中
聚合 SESSION_ID + SQL_ID + CURRENT_OBJ# 才能定位根因
单条 enq: TS - contention 样本只告诉你“谁在等”,但不知道“为什么等”。同一秒内多个会话卡在同一个 TS 锁上,大概率是因为执行了相同逻辑:比如批量 INSERT SELECT、大表 GROUP BY、或大量并行排序。这时候光看 SQL 文本没用,得确认它们是否操作同一类对象。
实操建议:
- 按
SESSION_ID,SQL_ID,CURRENT_OBJ#三字段分组,避免把不同语句或不同对象的等待混在一起 -
CURRENT_OBJ#在该事件中通常为 NULL(TS 锁不绑定具体对象),但若非空,说明正在为某个特定临时表或物化视图分配空间,需结合DBA_OBJECTS查类型 - 用
SQL_ID关联V$SQL_PLAN,重点找含SORT、HASH JOIN、TEMP TABLE TRANSFORMATION的操作;如果OBJECT_NAME是ORA$PTT_*开头,基本是隐式临时表 - 别忽略
MODULE和CLIENT_IDENTIFIER——Web 应用里同一模块高频触发,往往暴露的是应用层未控制并发量的问题
别指望 TEMP_SPACE_ALLOCATED 出现在 ASH 里
TEMP_SPACE_ALLOCATED 这个字段压根不存在于 V$ACTIVE_SESSION_HISTORY 或 DBA_HIST_ACTIVE_SESS_HISTORY 中。ASH 的设计目标是记录“正在等什么”,不是“用了多少空间”。你如果写 WHERE TEMP_SPACE_ALLOCATED IS NOT NULL,结果永远为空。
实操建议:
- 要查实时分配量,必须切到
V$TEMPSEG_USAGE,其中ALLOCATED_SPACE是数据库块数,需乘(SELECT VALUE FROM V$PARAMETER WHERE NAME = 'db_block_size')才得字节数 -
V$TEMPSEG_USAGE只反映“此刻活跃”的临时段,一旦 SQL 执行结束或 PGA 回收,行就消失;它无法回溯历史,也不能告诉你谁卡在分配路径上 - 如果看到
ALLOCATED_SPACE远大于USED_SPACE,说明计划预估偏差大,或用了类似/*+ OPT_PARAM('_smm_max_size' 2048) */的 hint 强制放大 PGA,反而加剧了 TS 分配压力 - 想确认是否真有大量临时段被反复创建/释放,得查
V$SORT_SEGMENT中的CURRENT_USERS和USED_EXTENTS变化趋势,配合 ASH 中enq: TS - contention的密度交叉判断
缓解 TS 头块争用,关键不在加 TEMP 文件,而在分散分配压力
很多人第一反应是“加数据文件”——但若只加一个新文件,而所有会话仍通过同一 TS$ 控制结构申请空间,争用一点没减少。真正有效的做法是让 Oracle 能并行管理多个分配单元。
实操建议:
- 增加 TEMP 表空间的数据文件数(至少 4 个),且每个文件大小一致、AUTOEXTEND ON,确保 Oracle 使用“循环分配”策略
- 禁用
UNIFORM SIZE,改用SYSTEM管理方式,让位图块分散在不同文件中,降低单点争用概率 - 对已知高并发 SQL,考虑用
/*+ USE_HASH_AGGREGATION */或/*+ NO_USE_HASH_AGGREGATION */显式控制哈希/排序路径,避免计划波动引发不可控的临时段申请 - 检查应用层是否在短事务中频繁调用
CREATE GLOBAL TEMPORARY TABLE——这类 DDL 会触发 TS 分配,且无法被缓存重用,比 DML 更伤
最易被忽略的一点:TS 头块争用往往和 PGA 设置无关,调大 PGA_AGGREGATE_TARGET 可能适得其反——它只是推迟溢出时间,不减少分配次数;真正要压的,是单位时间内发起分配请求的会话数量。


















