Oracle中有關Latch的介紹

2021-04-27 04:28:44 字數 3137 閱讀 4905

本文向各位闡述oracle的latch機制,latch,用金山詞霸翻譯是門插栓,閉鎖,專業術語叫鎖存器,我開始接觸時就不大明白為什麼不寫lock,不都是鎖嗎?只是翻譯不同而以?研究過後才知道兩者有很大的區別。

latch是oracle提供的輕量級鎖資源,他用於快速,短時間的鎖定資源,防止多個併發程序同時修改訪問某個共享資源,他只工作在記憶體中,我們可以不大準確的說,記憶體中資源的鎖叫latch,資料庫物件(表,索引等)的鎖叫lock。比如資料快取中的某個塊要被讀取,我們會獲得這個塊的latch,這個過程叫做pin,另外乙個程序恰好要修改這個塊,他也要pin這個塊,此時他必須等待,當前乙個程序釋放latch後才能pin住,然後修改,如果多個程序同時請求的話,他們之間將出現競爭,沒有乙個入隊機制,一旦前面程序釋放所定,後面的程序就蜂擁而上,沒有先來後到的概念,這個和lock是有本質區別的,這一切都發生的非常快,因為latch的特點是快而短暫,當然這個只是大致過程,細節部分在後面討論

先來看下latch和lock的區別

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

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

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

4. latch是非入隊的,而lock是入隊的

5. latch不存在死鎖,而lock中存在(死鎖在oracle中是非常少見的)

看看下面這個例子,你會感覺到latch的存在 

sql> create table mytest as select object_name from user_objects where rownum <= 4;

table created

sql> set timing on

sql>

declare lv_name varchar2(25) := '';

begin

for i in 1..100000 loop

select object_name into lv_name from mytest where rownum = 1;

end loop;

end;

/ pl/sql procedure successfully completed

executed in 3.359 seconds

這個程序不斷的訪問表上的同乙個資料塊,他先會物理讀取資料塊到資料緩衝區,然後在記憶體中不斷的獲取這個塊的latch,現在只有單個程序,執行的還好,10萬次用了3秒多,但當我拉出4個視窗同時併發的執行這個語句時,問題就出現了,多個程序pin同乙個資料塊,每個大概花了15秒,並且看到他們乙個乙個的結束,到最後只剩乙個時一閃就過去了,因為沒人和他搶了,這個實驗展現了latch競爭的現象,對於9i提出的查詢可以共享latch在此我表示了質疑。

現在來看看程序獲取latch的詳細過程,任何時候,只有乙個程序可以訪問記憶體中的某乙個塊(9i提出的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-休眠。。。占用,這裡有人會問為什麼要spin,為什麼不直接休眠等待?這裡要明白休眠意味著什麼,他意味著暫時的放棄cpu,進行上下文切換(context switch),這樣cpu要儲存當前程序執行時的一些狀態資訊,比如堆疊,訊號量等資料結構,然後引入後續程序的狀態資訊,處理完後再切換回原來的程序狀態,這個過程如果頻繁的發生在乙個高事務,高併發程序的處理系統裡面,將是個很昂貴的資源消耗,所以他選擇了spin,讓程序繼續占有cpu,執行一些空指令,之後繼續請求,繼續spin,直到達到_spin_count值,這時會放棄cpu,進行短暫的休眠,再繼續剛才的動作,oracle軟體就是這麼設計的,世界大師們的傑作,自然有他的道理,我就不在這上面再費文字了。

系統發生關於latch的等待是沒發避免的,因為這是oracle的運作機制,當你看到很高的latch get時並不意味著你的系統需要調整,有時候很高的get值背後只有很短的等待時間,我們調整的物件應該以消耗的時間來圈定,而不是看到乙個很高的獲取次數值,當然,獲取值異常的高出別的等待時間幾十萬倍時我們還是要關心的,oracle關於latch的等待非常繁多,主要的包括share pool,library cache,cache buffer chains,buffer busy wait,每乙個的調整幾乎都可以寫幾頁紙,以後慢慢完成吧。

Oracle中有關Latch的介紹

latch是oracle提供的輕量級鎖資源,用於快速,短時間的鎖定資源,防止多個併發程序同時修改訪問某個共享資源,他只工作在記憶體中,我們可以不大準確的說,記憶體中資源的鎖叫latch,資料庫物件 表,索引等 的鎖叫lock。本文向各位闡述oracle的latch機制,latch,用金山詞霸翻譯是門...

Oracle中有關日期的一些設定

1 select timestamp 2009 11 03 09 26 50.124 fromdual 預設毫秒儲存六位 2 此語句只能在伺服器端執行,如果執行以下操作,則在插入 oracle 時,可以直接寫 nls date format 設定的格式,但是只能針對一次繪畫,如果關掉視窗則失效。al...

oracle中有關於字串的問題。

1 字串 execute immediate alter table sys form detail add hidden char 5 default false 剛開始的時候 false 執行這一句的時候就會報錯,原因是由於 有兩個單引號,那樣子的話,程式就不能夠識別出 報錯資訊如下 error...