rac中enq: ts–contention“传染”源于多实例争抢同一tempfile文件头latch,因共享表空间且仅含单个tempfile导致串行排队;须为每实例配专属tempfile(路径含实例名)、逐实例设置default temporary tablespace并验证挂载状态。
为什么rac中enq: ts – contention总在节点间“传染”
这不是网络延迟或锁传播慢,而是多个实例在争抢同一tempfile的文件头(file header)latch。rac里临时段物理上不跨实例共享,但若所有实例都指向同一个表空间(比如temp),而该表空间只含一个tempfile(哪怕它在asm共享磁盘组里),所有排序操作就会串行排队等这个文件头锁——表现为持续的enq: ts – contention,且在gv$lock里看到多个inst_id同时等待同一id1(即表空间号)。
- 查证方式:在每个节点分别执行
SELECT event, p1, p2 FROM v$session_wait WHERE event = 'enq: TS - contention',比对p1(表空间号)是否一致 - 常见假象:
dba_temp_files显示文件存在 ≠ 当前实例能写入;可能因ASM diskgroup未在该节点挂载,导致status为OFFLINE却仍被DEFAULT_TEMP_TABLESPACE引用 - 别信“组名一样就负载均衡”:
TABLESPACE GROUP只是逻辑标签,组内若只放一个表空间,等于没分片
怎么给每个RAC实例配专属临时表空间
核心不是“建个表空间加进组”,而是确保路径、权限、状态三者同时满足本地化——tempfile路径必须带实例标识,且仅本实例可独占访问。
- ASM路径必须显式含实例名:
'+DATADG/racdb_inst1/temp01.dbf',禁用'+DATADG/racdb/temp01.dbf'这类笼统路径 - 禁用OMF:
ALTER SYSTEM SET db_create_file_dest='' SCOPE=BOTH,否则CREATE TEMPORARY TABLESPACE会自动生成无实例区分的路径 - 逐实例执行建表空间命令:
CREATE TEMPORARY TABLESPACE temp_inst1 TEMPFILE '+DATADG/racdb_inst1/temp01.dbf' SIZE 2G TABLESPACE GROUP 'TEMP_GROUP' - 建完立刻验证:
SELECT tablespace_name, status, enabled FROM dba_temp_files WHERE tablespace_name = 'TEMP_INST1'——status必须是ONLINE,enabled必须是YES
ALTER DATABASE DEFAULT TEMPORARY TABLESPACE为什么只在当前实例生效
这个命令不会广播,也不会同步到其他节点。你在inst1上执行ALTER DATABASE DEFAULT TEMPORARY TABLESPACE temp_inst1,只改inst1的默认值;inst2仍用原来的TEMP,除非你连过去再执行一遍。
- 验证方式:在每个实例分别查
SELECT property_value FROM database_properties WHERE property_name = 'DEFAULT_TEMP_TABLESPACE',不能只查gv$视图——它不反映本实例实际生效值 - 错误做法:在节点1建好
temp_inst1后,以为“全局设置完成”,结果节点2的SQL仍在往TEMP写,触发争用 - 必须逐实例执行+逐实例验证,漏掉任意一个节点,争用就还在
查gv$sort_segment时为什么总误判TEMP负载
v$sort_segment只反映当前连接实例的状态;直接查gv$sort_segment却不按inst_id分组,等于把不同实例的内存段混在一起统计,完全失真。
- 错误写法:
SELECT tablespace_name, SUM(used_extents) FROM gv$sort_segment GROUP BY tablespace_name——这会掩盖实例间分配严重不均的问题 - 正确写法:
SELECT inst_id, tablespace_name, used_extents FROM gv$sort_segment ORDER BY inst_id, used_extents DESC - 典型误判场景:你在节点1查
v$sort_segment发现全是0,就认为“TEMP没压力”,却不知节点2上TEMP_INST2的USED_EXTENTS已超95% - 真正要盯的是每个
inst_id+tablespace_name组合的used_extents,而不是汇总值
最易被忽略的点:diskgroup全节点挂载检查。即使路径带实例名、表空间已创建、DEFAULT_TEMP_TABLESPACE也设对了,只要某个节点上+DATADG没挂载,temp_inst1就不可用——dba_temp_files里status可能是OFFLINE,但DBA往往只查gv$视图,错过这个细节。











