enq:SQ-contention / DFS lock handle(SV)

yantaicuiwei發表於2011-02-15

Oracle 為了管理Sequence 使用了以下三種鎖。

 

*  row cache lock : 在呼叫Sequnece.nextval 過程中,將資料字典資訊進行物理修改時獲取。賦予了NOCACHE 屬性的Sequence 上發生。

*  SQ 鎖 : 在記憶體上快取(cache)的範圍內,呼叫Sequence.nextval 期間擁有此鎖。賦予了CACHE 屬性的Sequence 上發生。

*  SV 鎖 : RAC 上節點之間順序得到保障的情況下,呼叫Sequence.nextval期間擁有。賦予了CACHE+ORDER 屬性的Sequence 上發生。

 

      賦予了CACHE 屬性的Sequence 呼叫nextval 期間,應該以SSX 模式獲得SQ 鎖。許多會話同時為了獲取SQ 鎖而發生爭用過程中,若發生爭用,則等待enq:SQ-contention 事件。enq:SQ-contention 事件的P2 值是Sequence 的OBJECT ID。因此,若利用P2 值與DBA_OBJECTS 的結合,就可以知道對哪個Sequence 發生了等待現象。

 
      建立Sequence 賦予的CACHE 值較小時,有enq:SQ-contention 等待增加的趨勢。CACHE 值較小時,記憶體上事先CACHE 的值很快被耗盡,這時需要將資料字典資訊物理修改後,再次執行CACHE 的工作。在此期間,因為一直擁有SQ 鎖,相應的enq:SQ-contention 事件的等待時間也會延長。很不幸的是,在建立Sequence 時,將CACHE 值的預設值設定為較小的20。因此建立使用量多的Sequence 時,CACHE 值應該取1000 以上的較大值。
 
      偶爾一次性同時建立許多會話時,有時會發生enq:SQ-contention 等待事件。其理由是V$SESSION.AUDSID(auditing session id)列值是利用Sequence建立的。Oracle 在建立新的會話後,利用名為SYS.AUDSES$的Sequence 的nextval,建立AUDSID 值。SYS.AUDSES$ Sequence 的CACHE 大小的預設值設定為20。許多會話同時連線時,可以將SYS.AUDSES$ Sequence 的CACHE大小擴大至1000,以此可以解決enq:SQ-contention 等待問題。
 
      RAC 上建立Sequence 時,在賦予了CACHE 屬性的狀態下,若沒有賦予ORDER 屬性,則各節點將會把不同範圍的Sequence 值CACHE 到記憶體上。比如,擁有兩個節點的RAC 環境下,建立CACHE 值為100 的Sequence 時,1號節點使用1~100,2 號節點使用101~200。若兩個節點之間都透過遞增方式使用Sequence,必須賦予如下ORDER 屬性。
 
      SQL> create sequence ordered_sequence cache 100 order;
 
      如果是已賦予了CACHE+ORDER 屬性的Sequence,Oracle 使用SV 鎖進行行同步。即,對賦予了ORDER 屬性的Sequence 呼叫nextval 時,應該以SSX模式擁有SV 鎖。在獲取SV 鎖過程中,如果發生爭用時,不是等待row cache lock 事件或enq:SQ-contention 事件,而是等待名為DFS lock handle 事件。正因如此,V$EVENT_NAME 檢視上不存在類似“enq:SV-contention”的事件。DFS lock handle 事件是在OPS 或RAC 環境下,除了高速緩衝區同步之外,還有行高速緩衝區或庫高速緩衝區的為了同步獲取鎖的過程中等待的事件。若要保障多個節點之間Sequence 順序,應該在全域性範圍內獲得鎖,在此過程中會發生DFS lock handle 等待。在獲取SV 鎖的過程中發生的DFS lock handle等待事件的P1 、P2 值與enq:SQ-contention 等待事件相同( P1=mode+namespace、P2=object#)。因此從P1 值能確認是否是SV 鎖,透過P2值可以確認對哪些Sequence 發生過等待。SV 鎖爭用問題發生時的解決方法與SQ 鎖的情況相同,就是將CACHE 值進行適當調整,這也是唯一的方法。
 
      在RAC 等多節點環境下,Sequence 的CACHE 值給效能帶來的影響比單節點環境更嚴重。因此,儘量賦予CACHE+NOORDER 屬性,並要給予足夠大的CACHE 值。如果需要保障順序,必須賦予CACHE+ORDER 屬性。但這時為了保障順序,例項之間不斷髮生資料的交換。因此,與賦予了NOORODER屬性的時候相比效能稍差。
 
有一點必須要注意,沒有賦予CACHE 屬性時,不管ORDER 屬性使用與否或RAC 環境與否,一直等待row cache lock 事件。row cache lock 是可以在全域性範圍內使用的鎖,單例項環境或多例項環境同樣可以發生。根據建立Sequence時賦予的屬性,整理等待事件的結果如下:

- NOCACHE: row cache lock
- CACHE+NOORDER: enq:SQ-contention
- CACHE+ORDER (RAC): DFS lock handle

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/21601207/viewspace-687277/,如需轉載,請註明出處,否則將追究法律責任。

相關文章