Oracle Latch 說明

Davis_itpub發表於2018-06-27

http://blog.csdn.net/tianlesoftware/article/details/5263238

 Latch 說明


 

. Latch說明

 

1.1    Latch

在之前的一篇文章裡的第四部分對Latch有了說明,參考:

           死鎖阻塞Latch等待詳解

           http://blog.csdn.net/tianlesoftware/archive/2010/08/20/5822674.aspx

 

 

           Latch屬於System Lock,用於保護SGA區中共享資料結構的一種序列化鎖定機制。Latch的實現是與作業系統相關的,尤其和一個程式是否需要等待一個latch、需要等待多長時間有關。

 

           LatchOracle提供的輕量級鎖資源,是一種能夠極快地被獲取和釋放的鎖,能快速,短時間的鎖定資源,防止多個併發程式同時修改訪問某個共享資源,它只工作在SGA中,通常用於保護描述buffer cacheblock的資料結構。

 

           比如SGA中,各種資料被反覆從磁碟讀取到記憶體,又被重新寫回到磁碟上,如果有併發的使用者做相同的事情,Oracle必須使用一種機制,來保證資料在讀取的時候,只能由一個會話來完成,這種保護機制就是Latch

           併發(concurrency):是說有超過兩個以上的使用者對同樣的資料做修改(可能包括插入,刪除和修改)。

           並行(parallel):是說將一件事情分成很多小部分,讓每一部分同時執行,最後將執行結果彙總成最終結果。

 

           與每個latch相聯絡的還有一個清除過程,當持有latch的程式成為死程式時,該清除過程就會被呼叫。Latch還具有相關級別,用於防止死鎖,一旦一個程式在某個級別上得到一個latch,它就不可能再獲得等同或低於該級別的latch

           

           Latch不會造成阻塞,只會導致等待。阻塞是一種系統設計上的問題,等待是一種系統資源爭用的問題。

 

1.2 有關SPin的說明:

           比如資料快取中的某個塊要被讀取,我們會獲得這個塊的latch這個過程叫做spin,另外一個程式恰好要修改這個塊,他也要spin這個塊,此時他必須等待,當前一個程式釋放latch後才能spin住,然後修改,如果多個程式同時請求的話,他們之間將出現競爭,沒有一個入隊機制,一旦前面程式釋放所定,後面的程式就蜂擁而上,沒有先來後到的概念,並且這一切都發生的非常快,因為Latch的特點是快而短暫。

 

SPIN休眠:

           休眠意味著暫時的放棄CPU,進行上下文切換(context switch),這樣CPU要儲存當前程式執行時的一些狀態資訊,比如堆疊,訊號量等資料結構,然後引入後續程式的狀態資訊,處理完後再切換回原來的程式狀態,這個過程如果頻繁的發生在一個高事務,高併發程式的處理系統裡面,將是個很昂貴的資源消耗,所以Oracle選擇了spin,讓程式繼續佔有CPU,執行一些空指令,之後繼續請求,繼續spin,直到達到_spin_count值,這時會放棄CPU,進行短暫的休眠,再繼續剛才的動作。

 

 

1.3 程式獲取Latch的過程:

           任何時候,只有一個程式可以訪問記憶體中的某一個資料塊,如果程式因為別的程式正佔用塊而無法獲得Latch時,他會對CPU進行一次spin(旋轉),時間非常的短暫,spin過後繼續獲取,不成功仍然spin,直到spin次數到達閥值限制(這個由隱含引數_spin_count指定),此時程式會停止spin,進行短期的休眠,休眠過後會繼續剛才的動作,直到獲取塊上的Latch為止。

 

           程式休眠的時間也是存在演算法的,他會隨著spin次數而遞增,以釐秒為單位,如11224488,。。。休眠的閥值限制由隱含引數_max_exponential_sleep控制,預設是2,如果當前程式已經佔用了別的Latch,則他的休眠時間不會太長(過長會引起別的程式的Latch等待),此時的休眠最大時間有隱含引數_max_sleep_holding_latch決定,預設是4釐秒這種時間限制的休眠又稱為短期等待。

           另外一種情況是長期等待鎖存器(Latch Wait Posting),此時等待程式請求Latch不成功,進入休眠,他會向鎖存器等待連結串列(Latch Wait List)壓入一條訊號,表示獲取Latch的請求,當佔用程式釋放Latch時會檢查Latch Wait List,向請求的程式傳遞一個訊號,啟用休眠的程式。Latch Wait List是在SGA區維護的一個程式列表,他也需要Latch來保證其正常執行,預設情況下share pool latchlibrary cache latch是採用這個機制

           如果將隱含引數_latch_wait_posting設定為2,則所有Latch都採用這種等待方式,使用這種方式能夠比較精確的喚醒某個等待的程式,但維護Latch Wait List需要系統資源,並且對Latch Wait ListLatch的競爭也可能出現瓶頸。

 

  如果一個程式請求,旋轉,休眠Latch用了很長時間,他會通知PMON程式,檢視Latch的佔用程式是否已經意外終止或死亡,如果是則PMON會清除釋放佔用的Latch資源。

 

           總之,Latch獲取的流程:請求-SPIN-休眠-請求-SPIN-休眠... ...佔用。

 

 

1.4 LatchLock

           從某種意義上說,Latch是記憶體中的資源鎖,物件(表,索引等)的鎖叫Lock

 

LatchLock的區別:

  (1. Latch是對記憶體資料結構提供互斥訪問的一種機制,而Lock是以不同的模式來套取共享資源物件,各個模式間存在著相容或排斥,從這點看出,Latch的訪問,包括查詢也是互斥的,任何時候,只能有一個程式能pin住記憶體的某一塊,幸好這個過程是相當的短暫,否則系統效能將沒的保障,從9I開始,允許多個程式同時查詢相同的記憶體塊。

  (2. Latch只作用於記憶體中,他只能被當前例項訪問,而Lock作用於資料庫物件,在體系中例項間允許Lock檢測與訪問

  (3. Latch是瞬間的佔用,釋放,Lock的釋放需要等到事務正確的結束,他佔用的時間長短由事務大小決定

  (4. Latch是非入隊的,而Lock是入隊的

           5. Latch不存在死鎖,而Lock中存在。

 

關於lock鎖可以參考我的blog

           oracle鎖機制

           http://blog.csdn.net/tianlesoftware/archive/2009/10/20/4696896.aspx

 

           oracle鎖問題的解決

           http://blog.csdn.net/tianlesoftware/archive/2009/10/28/4733630.aspx

 

 

. Latch爭用

 

           如果發現系統中經常由於Lock導致使用者等待,這時需要考慮系統在邏輯設計上是否有問題,比如多使用者對主鍵的刪除或者修改,是否有使用者使用selectfor update這樣的語法,外來鍵是否建立索引的因素。這些因素是需要結合系統的業務邏輯性來進行資料庫物件設計的。

 

           如果發現系統慢是因為很多的Latch爭用,就要考慮系統及資料庫自身設計上是否存在問題,比如是否使用繫結變數,是否存在熱快,資料儲存引數設計是否合理等因素。

 

           導致Latch爭用而等待的原因非常多,記憶體中很多資源都可能存在爭用。最常見的兩類latch爭用如下:

           1)共享池中的Latch爭用。

           2)資料緩衝池中的latch爭用。

 

           Oracle記憶體架構詳解

           http://blog.csdn.net/tianlesoftware/archive/2010/05/16/5594080.aspx

 

2.1 共享池中的Latch爭用

           共享池中如果存在大量的被反覆分析,就會造成很大的Latch爭用和長時間的等待,最常見的現象就是沒有繫結變數

           

           最常見的集中共享池裡的Latchlibrary cache可以透過一下SQL來查詢:

 

SQL> select * from v$latchname where name like 'library cache%';

 

            LATCH# NAME                        HASH

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

      217 library cache                       3055961779

      218 library cache lock                   916468430

      219 library cache pin                    2802704141

      220 library cache pin allocation            4107073322

      221 library cache lock allocation           3971284477

      222 library cache load lock                2952162927

      223 library cache hash chains              1130479025

 

 

           在分析系統效能時,如果看到有library cache這樣的Latch爭用,就可以斷定是共享池中出現了問題,這種問題基本是由SQL語句導致的,比如沒有繫結變數或者一些儲存過程被反覆分析。

 

資源的爭用可以透過如下SQL來檢視:

SQL> select event,count(*) from v$session_wait group by event;

 

EVENT                                    COUNT(*)

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

SQL*Ne tmessage from client                        4

Streams AQ: waiting for messages in the queue          1

ASM background timer                             1

gcs remote message                                                                                                                1

ges remote message                                                                                         1

jobq slave wait                                                                                                                  1

rdbms ipc message                                                                                                             14

smon timer                                                                                                                                         1

pmon timer                                                                                                                                       1

Streams AQ: qmn slave idle wait                                                         1

class slave wait                                                                                                        1

SQL*Net message to client                                                                          1

Streams AQ: waiting for time management or cleanup tasks 1

Streams AQ: qmn coordinator idle wait                                                  1

DIAG idle wait                                                                                                1

 

15 rows selected.

 

 

2.2資料緩衝池Latch爭用

           訪問頻率非常高的資料塊被稱為熱快(Hot Block),當很多使用者一起去訪問某幾個資料塊時,就會導致一些Latch爭用,最常見的latch爭用有:

           1  buffer busy waits

           2  cache buffer chain

這兩個Latch的爭用分別發生在訪問資料塊的不同時刻。

           

關於等待事件的說明,具體參考:

           Oracle常見的33個等待事件

           http://blog.csdn.net/tianlesoftware/archive/2010/08/12/5807800.aspx

 

Cache buffer chian產生原因:

           當一個會話需要去訪問一個記憶體塊時,它首先要去一個像連結串列一樣的結構中去搜尋這個資料塊是否在記憶體中,當會話訪問這個連結串列的時候需要獲得一個Latch,如果獲取失敗,將會產生Latch cache buffer chain等待,導致這個等待的原因是訪問相同的資料塊的會話太多或者這個列表太長(如果讀到記憶體中的資料太多,需要資料塊的hash列表就會很長,這樣會話掃描列表的時間就會增加,持有chache buffer chain latch的時間就會變長,其他會話獲得這個Latch的機會就會降低,等待就會增加)。

 

Buffer busy waits產生原因:

           當一個會話需要訪問一個資料塊,而這個資料塊正在被另一個使用者從磁碟讀取到記憶體中或者這個資料塊正在被另一個會話修改時,當前的會話就需要等待,就會產生一個buffer busy waits等待。

 

 

           產生這些Latch爭用的直接原因是太多的會話去訪問相同的資料塊導致熱快問題,造成熱快的原因可能是資料庫設定導致或者重複執行的SQL頻繁訪問一些相同的資料塊導致。

 

           Latch是簡單的、低層次的序列化,用以保護SGA中的共享資料結構,比如併發使用者列表和buffer cache裡的blocks資訊。一個程式或後臺程式在開始操作或尋找一個共享資料結構之前必須獲得對應的latch,在完成以後釋放latch不必對latch本身進行最佳化,如果latch存在競爭,表明SGA的一部分正在經歷不正常的資源使用。

 

有關這部分的更多內容,參考:

           死鎖阻塞Latch等待詳解

           http://blog.csdn.net/tianlesoftware/archive/2010/08/20/5822674.aspx

 

 

 

. 檢查Latch的相關SQL

 

3.1檢視造成LATCH BUFFER CACHE CHAINS等待事件的熱快

 

SELECTDISTINCTa.owner,a.segment_name

 FROMdba_extentsa,

      (SELECTdbarfil,dbablk

         FROMx$bh

        WHEREhladdrIN(SELECTaddr

                           FROM( SELECTaddr

                                     FROMv$latch_children

                                 ORDERBYsleepsDESC)

                          WHEREROWNUM<20))b

 WHERE    a.RELATIVE_FNO=b.dbarfil

      ANDa.BLOCK_ID<=b.dbablk

      ANDa.block_id+a.blocks>b.dbablk;

 

3.2 查詢當前資料庫最繁忙的BufferTCH(Touch)表示訪問次數越高,熱點快競爭問題就存在

 

SELECT*

 FROM( SELECTaddr,

                ts#,

                file#,

                dbarfil,

                dbablk,

                tch

           FROMx$bh

       ORDERBYtchDESC)

 WHEREROWNUM<11;

 

3.3 查詢當前資料庫最繁忙的Buffer,結合dba_extents查詢得到這些熱點Buffer來自哪些物件

 

SELECTe.owner,e.segment_name,e.segment_type

          FROMdba_extentse,

               (SELECT*

                  FROM(SELECT  addr,ts#,file#,dbarfil,dbablk,tch

                            FROMx$bh

                        ORDERBYtchDESC)

                 WHEREROWNUM<11)b

         WHEREe.relative_fno=b.dbarfil

           ANDe.block_id<=b.dbablk

           ANDe.block_id+e.blocks>b.dbablk;

 

3.4 如果在Top 5中發現latch free熱點塊事件時,可以從V$latch_children中查詢具體的子Latch資訊

 

*

 FROM(SELECT  addr,child#,gets,misses,sleeps,immediate_gets igets,

                immediate_misses imiss,spin_gets sgets

           FROMv$latch_children

          WHERENAME='cache buffers chains'

       ORDERBYsleepsDESC)

 WHEREROWNUM<11;

 

 

3.5獲取當前持有最熱點資料塊的Latchbuffer資訊

 

SELECTb.addr,a.ts#,a.dbarfil,a.dbablk,a.tch,b.gets,b.misses,b.sleeps

 FROM(SELECT*

         FROM(SELECT  addr,ts#,file#,dbarfil,dbablk,tch,hladdr

                   FROMx$bh

               ORDERBYtchDESC)

        WHEREROWNUM<11)a,

      (SELECTaddr,gets,misses,sleeps

         FROMv$latch_children

        WHERENAME='cache buffers chains')b

 WHEREa.hladdr=b.addr;

 

3.6利用前面的SQL可以找到這些熱點Buffer的物件資訊

 

SELECTdistincte.owner,e.segment_name,e.segment_type

          FROMdba_extentse,

               (SELECT*

                  FROM(SELECT  addr,ts#,file#,dbarfil,dbablk,tch

                            FROMx$bh

                        ORDERBYtchDESC)

                 WHEREROWNUM<11)b

         WHEREe.relative_fno=b.dbarfil

           ANDe.block_id<=b.dbablk

           ANDe.block_id+e.blocks>b.dbablk;

 

3.7結合SQL檢視可以找到操作這些物件的相關SQL,然後透過最佳化SQL減少資料的訪問,或者最佳化某些容易引起爭用的操作(如connect by等操作)來減少熱點塊競爭

 

 

onhash_valueskip1

SELECT/*+ rule */hash_value,sql_text

   FROMv$sqltext

  WHERE(hash_value,address)IN(

           SELECTa.hash_value,a.address

             FROMv$sqltexta,

                  (SELECTDISTINCTa.owner,a.segment_name,a.segment_type

                              FROMdba_extentsa,

                                   (SELECTdbarfil,dbablk

                                      FROM(SELECT  dbarfil,dbablk

                                                FROMx$bh

                                            ORDERBYtchDESC)

                                     WHEREROWNUM<11)b

                             WHEREa.relative_fno=b.dbarfil

                               ANDa.block_id<=b.dbablk

                               ANDa.block_id+a.blocks>b.dbablk)b

            WHEREa.sql_textLIKE'%'|| b.segment_name ||'%'

              ANDb.segment_type='TABLE')

ORDERBYhash_value,address,piece;

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

相關文章