天天看點

oracle等待事件8——段上的等待事件 如何找到'事件:enq: HW - contention'對應的熱點segment

1、enq:HW-contention

為防止多個程序同時修改HWM而提供的鎖稱為HW鎖(官方文檔解釋:Space management operations on a specific segment)。想要移動HWM的程序必須獲得HW鎖。HW鎖争用大部分是因為大量執行insert所引發的,偶爾也會因大量執行update在復原段中發生HW鎖争用現象。若是update,表中段的擴充的大小雖然不多,但在建立復原資料的過程中,需要復原段的急速擴張。HW鎖争用是在段的急速空間擴張時普遍出現的等待現象,有時也會引發嚴重的性能下降。

問題1:請問如何了解"HW

Enqueue是用于segment的HWM的, 可以通過手工配置設定extents來解決"

在手動段管理的時代,可以通過這個ALLOCATION EXTENT把新的BLOCK加入FREELIST中,也就是提高了HWM。來避免HW ENQUEUE

自動段管理我覺得這個方法已經不适用了吧~當初freelist時代,解決HW enq的辦法,就是減少hwm的提升次數~,通過alter table extent + instance子句 把新的extent中的block都加入freelist中,來達到目的。

問題2:HWM越高,每次尋找具體資料塊時就要找得越多, HW Enqueue應該越嚴重吧? 不了解HW Enqueue的工作方式,期望高手解答!!!

隻有當新的extents需要配置設定的時候,才會發生HW鎖的争用,主要明确HW鎖不是使用新的extents時候等待,而是配置設定extents的時候,也就是提高HWM的時候争用,是以,一次配置設定更大的extents可以減少這個鎖的争用哦。。

問題3:那是我在系統配置設定extents的時候存在這個等待嗎?

HW enqueue The HW enqueue is used to serialize the allocation of space beyond the  high water mark of a segment.

如文檔所說,HW enqueue 是發生在一個段的HWM連續提升的狀況下~ 提升HWM要做什麼工作呢?

首先HWM的位置是存儲在段頭塊,并且HWM的提升會增加Freelist中的free blocks,而freelist中的塊數的紀錄,也存儲在段頭(當然如果freelist

group=n>1,那麼存儲在段頭後面的n個塊中~),是以這個時候要修改的是段頭塊(以及freelist 所在的塊),還有一個地方要修改,就是原來freelist中最後一個block,這個裡面記錄了freelist單項清單的最後一個位址,要把他修改,指向新加入freelist的塊的位址~還要在所有新加入freelist的塊上建立freelist單項連結清單~ 可見提高HWM是需要修改很多塊的~

但是如果新加入一個extent呢?對于字典管理表空間,需要修改資料字典等待為ST enqueue(印象中)~ 而本地管理表空間,僅僅需要修改以下資料檔案頭上的位圖~這個工作量是非常小的~ 我不認為配置設定extent會造成多大的等待~ 當然就算有等待也不是hw enqueue

問題4:對于assm,可以采用uniform,配置設定更大的extent——metalink的确有這個說法~ 但是我覺得更主要的是assm本身的段管理機制使用位圖管理本身提高了free

block的并發性~ 較少了等待的發生~

但是為什麼要配置設定大extent我就不是很明白了~按理說大extent和hwm的提升沒什麼關系呀~

而且assm下有兩條hwm~ 是以我覺得high hwm low hwm的機制是不是也可以減少hwm變化的開銷

通過不同大小uniform測試可以看出extent大的好處。

原因應該是不必過多的配置設定extent,減少對HW enquence的争用

對于HHWM和LHWM,可以參見tanel的一段話

ASSM high-HWM extensions(擴張) are not done over extent boundaries(邊界) IIRC, thus with small extents you'd have lots of extensions to do, each requiring HW-enqueue get.ASSM relieves(解除,降低) HW-enqueue contention by increasing HHWM in

large sizes (depending on extent and current segment size),so less HW operations have to be done.

The LHWM extensions can be done without having HW-enqueue as they involve(包含) only changing few records in a BMB block (我估計應該是位圖塊,不确定)and the BMB is pinned(釘住) for that exclusively anyway. The actual batch formatting(批量格式化) of datablocks is done while having

FB enqueue, allowing finer(出色的) granularity(粒度) of locking block ranges in case of multiple parallel inserts.

HW enqueue

The HW enqueue is used to serialize the allocation of space beyond the high water mark of a segment.

<code>V$SESSION_WAIT.P2</code>/<code>V$LOCK.ID1</code>is

the tablespace number.

<code>V$SESSION_WAIT.P3</code>/<code>V$LOCK.ID2</code>is

the relative dba of segment header of the object for which space is being allocated.

If this is a point of contention for an object, then manual allocation of extents solves the problem.

SQL&gt; select p1, p2, p3 from v$session_wait where event = 'enq: HW - contention';

        P1         P2         P3

---------- ---------- ----------

1213661190          7  140003563

7 rows selected

SQL&gt; select dbms_utility.data_block_address_block(140003563),

           dbms_utility.data_block_address_file(140003563)

      from dual ;

DBMS_UTILITY.DATA_BLOCK_ADDRES DBMS_UTILITY.DATA_BLOCK_ADDRES

------------------------------ ------------------------------

                       1591531                             33

SQL&gt; select  name from v$tablespace where ts#=7;

NAME

------------------------------

INFORES

通過下面語句找到熱點segment

select *

  from dba_extents.segment_name

 where tablespace_name = 'INFORES'

   and FILE_ID = 33

   and 1591531 between block_id and block_id + blocks

2、enq:ST-contention   enq:TT-contention

ST:空間事務鎖

·每個資料庫(非執行個體)擁有一個ST鎖。

·除了本地管理表空間,在space管理操作(建立或删除extents)時必須是排它模式。

·對象creation, dropping, extension, 以及truncation都處于這種鎖

·多數公共原因的争奪,是在磁盤排序(并非使用真正的臨時表空間)或復原段擴充或收縮。

 按如下項以避免競争:

  ·使用真正的臨時表空間(true temporary tablespaces),利用臨時檔案。臨時段在磁盤排序之後并不建立或删除。(因為如果将永久表空間作為排序區使用時,執行排序時伴随着過多的區配置設定和釋放引發ST鎖的争用,特别是SMON程序為了整理排序區,等待ST鎖時可能發生嚴重的性能下降,臨時表空間使用LMT,進而在配置設定和釋放臨時段的過程中使用更有效的算法,是以可以避免排序引起嚴重ST鎖争用)

  ·使用本地管理表空間。

  ·指定復原段避免動态擴充和收縮,或使用自動undo management。

  ·避免應用執行建立或删除資料庫對象。

使用本地管理室,完全不能實作對于UET$(used extent) TET$(free extent)的掃描和DML。這是因為使用LMT時,extent的資訊時通過資料檔案頭的位圖管理的,是以不需要對UET$,FET$的工作,而使用資料字典管理表空間時,可以發現發生對UET$ 、FET$ 的掃描和DML。因為在DMT(資料字典管理)上是通過UET$ ,FET$等區相關的資料字典表管理區資訊的,是以每當有區的變化時需要查詢和修改表的一連串工作。如因為大量執行insert工作,發生10萬個區配置設定,則需要在UET$,FET$上寫入10萬個相應的資料。這些工作隻能在獲得ST鎖之後方可執行。因ST鎖發生激烈争用。而使用LMT(本地管理表空間)時,區資訊被位于資料檔案頭的位圖區域管理,幾乎不參考資料字典資訊,是以幾乎不發生ST鎖引起的争用。9i之後,基本上都是LMT管理,是以ST鎖争用的問題不再是嚴重的性能問題。

一個用來存儲報表的資料庫上,有一系列資料導入的程序,但在今天發現這些程序一直未執行結束,在資料導入端可以看到資料導入速度為零,檢視資料庫上的等待事件,發現它們的等待事件全部是enq: ST – contention(EXTENT配置設定或者回收的鎖)。 

oracle等待事件8——段上的等待事件 如何找到'事件:enq: HW - contention'對應的熱點segment

SID MACHINE                HASH Event Name                       P1      P2  

------ -------------- ------------ -------------------------- -------- ---------  

  1069 gateway208063.   2384721791 enq: ST - contention     1398013958        0  

   775 gateway208063.   2384721791 enq: ST - contention     1398013958        0  

通過查詢v$lock這個視圖,可以發現某個會話一直占用着ST鎖,殺掉這個程序之後,其他的程序的資料導入速度恢複正常。至于這個會話為啥會長久地占用這個鎖,沒有進一步追查。 

oracle等待事件8——段上的等待事件 如何找到'事件:enq: HW - contention'對應的熱點segment

SQL&gt; select * from gv$lock where type='ST';  

SID TY        ID1        ID2      LMODE    REQUEST      CTIME      BLOCK  

---- -- ---------- ---------- ---------- ---------- ---------- ----------  

 661 ST          0          0          0          6         73          0  

 720 ST          0          0          0          6         73          0  

 685 ST          0          0          0          6         72          0  

 887 ST          0          0          0          6         72          0  

 922 ST          0          0          0          6         72          0  

1054 ST          0          0          6          0        261          2  

 704 ST          0          0          0          6         75          0  

 849 ST          0          0          0          6         75          0  

 976 ST          0          0          0          6         75          0  

 978 ST          0          0          0          6         75          0  

 815 ST          0          0          0          6         75          0  

以上是一個非常簡單的使用v$lock解決enqueue的問題,但是在解決過程中卻花費了我很長的時間,這應該是我沒有按照最為直接的思維考慮這個問題導緻的。對于這個問題,我們應該這麼想:既然等待ST鎖,那麼ST鎖肯定被某個會話占用着,通過V$LOCK查找到這個會話,并審查這個會話的這種行為是否正常。 

從8i起,對之前使用ST鎖的部分表空間相關的工作上會使用TT鎖,使用TT鎖的工作類型被指定ID2值上,下面解釋一下ID2值的含義:

0   ——   used to prevent deadlocks between dropping tablespaces and creating a  rollback segment  in it .

1   ——   used to serialise the creation of datafiles within a given tablespace.

2   ——   used to prevent other operations from happening to  a tablespace during tablespace point in time recovery.

4   ——   used to lock the tablespace id when creating a  tablespace;

8   ——   pervents deadlocks during ALTER TABLESPACE operations 。 this was added for bug 503594

16  ——  used for synchronising the allocation and deallocation of extents. 

TT鎖與ST鎖不同,每個表空間都可使用一個(ID1=tablespace#),是以比使用ST鎖時有減少争用的效果,若為了獲得TT鎖等待,則在V$SESSION_WAT視圖上會記錄enq:TT-contention事件。很幸運,TT鎖争用幾乎不發生。

下面看一個轉載的例子:

今天資料庫更新日志表,完全是insert,結果在9點後發生嚴重阻塞;剛開始以為是事物并發太多,但是觀察,發現猜測錯誤

經過分析v$lock發現有如下情況

SID        TYPE        ID1        ID2           LMODE        REQUEST      CTIME        BLOCK

59         HW          15       -834666487       0            6             0            0

59         TM        727716        0             3            0             4            0

59         TT          15         16             4            0             0            0

其中id1=727716為日志表cx_log6,id1=15為undo$,越有600組同樣的狀況

要insert cx_log6,需要操作undo$表,undo$鎖類型為hw,需要擷取lockmod 為6的鎖;而持有TT鎖(lmod為4)的始終不釋放,導緻undo$不能擷取lockmod為6的鎖

阻塞insert。

TT鎖類型的解釋為:The TT enqueue is used to avoid deadlocks in parallel tablespace operations (deleting and creating tablespaces, creating data files, tablespace point-in-time recovery, creating undo segments in the tablespace, ALTER TABLESPACE, extent

allocation and deallocation in the tablespace, ...).

在metalink有如下内容:

When adding space (extending) an undo segment it is possible to leak(洩露) an in-memory lock (an enqueue) when certain exceptions occur(某個異常發生). Repeated execution of this code path can lead to process death or multi-process hangs.

現在有如下猜測:

2、   是一個bug

3、   跟新加入的磁盤有一定的關系;以前空間不足,現在把表重建在新加入的表空間後,出現此類問題。

但是沒有進一步的證據去證明,很頭疼

3、enq:US-contention

在對此事件說明之前,需要了解在使用AUM(atuomatic undo management)時,復原段在何時聯機或脫機。AUM與RBU(rollback segment management)不同,復原段的管理室oracle自動完成的。使用AUM時,復原段的聯機或脫機的時刻如下:

1)在執行alter database open 的時候将復原段聯機

2)通過alter system set undo_tablespace=xxx 修改撤銷表空間時,将原來的復原段脫機後,再将新的復原段聯機。

3)通過SMON,自動脫機或者聯機復原段,如果一段時間内,事務量增加,聯機狀态的復原段也會增加,一段時間内若是沒有實物或事務減少,復原段就會被smon程序脫機。

如上所示,為了同步将復原段聯機或脫機的過程,執行該工作的伺服器程序或背景程序應獲得US鎖,每個復原段非配一個US鎖,ID1=Undo segment#。若在獲得US鎖的過程中發生争用,則等待enq:US-contention事件。伺服器程序應該在開始事務時配置設定到復原段,但如果不存在可用的復原段時,應該建立新的復原段或将脫機狀态的復原段聯機。在實作此項工作期間,伺服器程序為了獲得US鎖而等待,等待占有可用復原段。