1. 程式人生 > >奇怪的等待事件“enq: ss - contention”

奇怪的等待事件“enq: ss - contention”

資料庫有時會遇到大量的程序發生'enq: ss - contention'等待,持續5到10分鐘,然後自動消失。從字面上看,'SS'是Sort Segment:

select * from v$lock_type where type='SS'

TYPE       NAME   ID1_TAG     ID2_TAG   IS_USER DESCRIPTION

--------------------------- ---------------------------------- -------------------------- --------------------
SS    Sort Segment   tablespace #   dba    NO  Ensures that sort segments created during parallel DML operations aren't prematurely cleaned up

為何大量的程序需要等待Sort Segment enqueue呢?

 

 

從ASH的資訊看,Sort Segment enqueue的持有者1581也是一個使用者程序,他在等待'DFS lock handle'

5931 1 WAITING 1581 2 JDBC Thin Client dfcdxr0v3hn6n DFS lock handle 1128857605 14 2 26522266 147 1370406 N N
 

1674 1 WAITING 5931 1 JDBC Thin Client dfcdxr0v3hn6n enq: SS - contention 1397948422 6 2 142364 25 147677 N N
1772 1 WAITING 5931 1 JDBC Thin Client dfcdxr0v3hn6n enq: SS - contention 1397948422 6 2 140883 131 3809055 N N
1852 1 WAITING 5931 1 JDBC Thin Client dfcdxr0v3hn6n enq: SS - contention 1397948422 6 2 19434636 102 1265728 N N


<=========session 5931 是阻塞者,在等 'DFS lock handle','DFS lock handle'的持有者是節點2上的session 1581 .

從DFS lock handle的P1和P2可以看出他為何申請DFS lock handle,
<========DFS lock handle P1=1128857605 P2=14 P3=2


P1 DEC1128857605 =>HEX 43490005 <======CI enqueue
P2=14 <===========Release unused space of the sort segments. Handled by SMON

這是一個Cross Instance(CI)請求,請求的目的是釋放未使用的sort segments,也就是清理TEMP表空間。

節點2上的session 1581 是DBW0:

2016-12-07 16:27:27 db file parallel write 1581 2 WAITING [email protected] (DBW0)

 

所以,節點1上的應用程序在等節點2上的DBW0清理TEMP表空間。

wait a minute,為何節點1的程序要等節點2的DBW0,他們為什麼不請求本地的DBW0?

在RAC中,TEMP表空間是在各個節點間共享的(當然,其他所有的表空間都一樣),但是TEMP表空間會在各個節點有快取,可以通過以下檢視查詢到TEMP在各個節點的使用情況:

select inst_id, tablespace_name, blocks_cached, blocks_used from gv$temp_extent_pool;

 

如果一個節點快取的TEMP blocks耗盡,會請求另一個節點釋放一些未使用的TEMP給他用,釋放的過程中會較長時間等待enq: ss - contention,這是一個正常的行為。

為了避免申請臨時空間時較長的等待,可以通過手工方式釋放各個節點的cached block。
ALTER SESSION SET events 'immediate trace name drop_segments level tablespace_number+1';