您好,登錄后才能下訂單哦!
這篇文章給大家介紹如何進行Oracle Latch 說明,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
一. Latch說明
1.1 Latch
在之前的一篇文章里的第四部分對Latch有了說明,參考:
鎖死鎖阻塞Latch等待詳解
http://blog.csdn.net/tianlesoftware/archive/2010/08/20/5822674.aspx
Latch屬于System Lock,用于保護SGA區中共享數據結構的一種串行化鎖定機制。Latch的實現是與操作系統相關的,尤其和一個進程是否需要等待一個latch、需要等待多長時間有關。
Latch是Oracle提供的輕量級鎖資源,是一種能夠極快地被獲取和釋放的鎖,能快速,短時間的鎖定資源,防止多個并發進程同時修改訪問某個共享資源,它只工作在SGA中,通常用于保護描述buffer cache中block的數據結構。
比如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次數而遞增,以厘秒為單位,如1,1,2,2,4,4,8,8,。。。休眠的閥值限制由隱含參數_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 latch和library cache latch是采用這個機制。
如果將隱含參數_latch_wait_posting設置為2,則所有Latch都采用這種等待方式,使用這種方式能夠比較精確的喚醒某個等待的進程,但維護Latch Wait List需要系統資源,并且對Latch Wait List上Latch的競爭也可能出現瓶頸。
如果一個進程請求,旋轉,休眠Latch用了很長時間,他會通知PMON進程,查看Latch的占用進程是否已經意外終止或死亡,如果是則PMON會清除釋放占用的Latch資源。
總之,Latch獲取的流程:請求-SPIN-休眠-請求-SPIN-休眠... ...占用。
1.4 Latch和Lock
從某種意義上說,Latch是內存中的資源鎖,數據庫對象(表,索引等)的鎖叫Lock。
Latch和Lock的區別:
(1). Latch是對內存數據結構提供互斥訪問的一種機制,而Lock是以不同的模式來套取共享資源對象,各個模式間存在著兼容或排斥,從這點看出,Latch的訪問,包括查詢也是互斥的,任何時候,只能有一個進程能pin住內存的某一塊,幸好這個過程是相當的短暫,否則系統性能將沒的保障,從9I開始,允許多個進程同時查詢相同的內存塊。
(2). Latch只作用于內存中,他只能被當前實例訪問,而Lock作用于數據庫對象,在RAC體系中實例間允許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導致用戶等待,這時需要考慮系統在邏輯設計上是否有問題,比如多用戶對主鍵的刪除或者修改,是否有用戶使用select…for update這樣的語法,外鍵是否創建索引的因素。這些因素是需要結合系統的業務邏輯性來進行數據庫對象設計的。
如果發現系統慢是因為很多的Latch爭用,就要考慮系統及數據庫自身設計上是否存在問題,比如是否使用綁定變量,是否存在熱快,數據存儲參數設計是否合理等因素。
導致Latch爭用而等待的原因非常多,內存中很多資源都可能存在爭用。最常見的兩類latch爭用如下:
(1)共享池中的Latch爭用。
(2)數據緩沖池中的latch爭用。
Oracle內存架構詳解
http://blog.csdn.net/tianlesoftware/archive/2010/05/16/5594080.aspx
2.1 共享池中的Latch爭用
共享池中如果存在大量的SQL被反復分析,就會造成很大的Latch爭用和長時間的等待,最常見的現象就是沒有綁定變量。
最常見的集中共享池里的Latch是library 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 查詢當前數據庫最繁忙的Buffer,TCH(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信息
SELECT*
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獲取當前持有最熱點數據塊的Latch和buffer信息
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等操作)來減少熱點塊競爭
breakonhash_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;
關于如何進行Oracle Latch 說明就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。