【鎖】Latch、lock、 pin的區別
【鎖】Latch、lock、 pin的區別
我之前寫過的幾篇鎖的文章:
【鎖】Oracle鎖系列:http://blog.itpub.net/26736162/viewspace-2128896/
【鎖】Oracle死鎖(DeadLock)的分類及其模擬:http://blog.itpub.net/26736162/viewspace-2127247/
【故障處理】佇列等待之TX - allocate ITL entry引起的死鎖處理:http://blog.itpub.net/26736162/viewspace-2124771/
Latch是Oracle提供的輕量級鎖,它用於快速,短時間的鎖定資源,防止多個併發程式同時修改訪問某個共享資源,它只工作在記憶體中,我們可以不大準確的說,記憶體中資源的鎖叫latch,資料庫物件(表,索引等)的鎖叫Lock。
比如資料快取中的某個塊要被讀取,我們會獲得這個塊的latch,這個過程叫做pin,另外一個程式恰好要修改這個塊,他也要pin這個塊,此時他必須等待,當前
一個程式釋放latch後才能pin住,然後修改,如果多個程式同時請求的話,他們之間將出現競爭,沒有一個入隊機制,一旦前面程式釋放latch,後面的程式就蜂
擁而上,沒有先來後到的概念,這個和Lock是有本質區別的,這一切都發生的非常快,因為Latch的特點是快而短暫,當然這個只是大致過程。
先來看下Latch和Lock的區別
1。 Latch是對記憶體資料結構提供互斥訪問的一種機制,而Lock是以不同的模式來套取共享資源物件,各個模式間存在著相容或排斥,從這點看出,Latch 的訪問
,包括查詢也是互斥的,任何時候,只能有一個程式能pin住記憶體的某一塊,幸好這個過程是相當的短暫,否則系統效能將沒的保障,現在從9I開始,允許多個進
程同時查詢相同的記憶體塊,但效能並沒有想象中的好。
2。 Latch只作用於記憶體中,他只能被當前例項訪問,而Lock作用於資料庫物件,在RAC體系中例項間允許Lock檢測與訪問
3。 Latch是瞬間的佔用,釋放,Lock的釋放需要等到事務正確的結束,他佔用的時間長短由事務大小決定
4。 Latch是非入隊的,而Lock是入隊的
5。 Latch不存在死鎖,而Lock中存在(死鎖在Oracle中是非常少見的)
看看下面這個例子,你會感覺到Latch的存在
CREATE TABLE MYTEST AS SELECT OBJECT_NAME FROM USER_OBJECTS WHERE ROWNUM=4;
SET TIMING ON
DECLARE lv_name VARCHAR2(25):='';
BEGIN
FOR i IN 1 .. 100000LOOP
SELECT OBJECT_NAME INTO lv_name FROM MYTEST WHERE ROWNUM=1;
END LOOP;
END;
/
PL/SQL procedure successfully completed
Executedin 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使用兩種資料結構來進行shared pool的併發控制:lock 和 pin.
Lock比pin具有更高的級別.
Lock在handle上獲得,在pin一個物件之前,必須首先獲得該handle的鎖定.
鎖定主要有三種模式: Null,share,Exclusive.
在讀取訪問物件時,通常需要獲取Null(空)模式以及share(共享)模式的鎖定.
在修改物件時,需要獲得Exclusive(排他)鎖定.
在鎖定了Library Cache物件以後,一個程式在訪問之前必須pin該物件.
同樣pin有三種模式,Null,shared和exclusive.
只讀模式時獲得共享pin,修改模式獲得排他pin.
通常我們訪問、執行過程、Package時獲得的都是共享pin,如果排他pin被持有,那麼資料庫此時就要產生等待.
------------------------------------------------------------------------
library cache lock和library cache pin都是我們關心的.接下來我們就研究一下這幾個等待事件.
(一).LIBRARY CACHE PIN等待事件
Oracle文件上這樣介紹這個等待事件:
"library cache pin" 是用來管理library cache的併發訪問的,pin一個object會引起相應的heap被
載入記憶體中(如果此前沒有被載入),Pins可以在三個模式下獲得:NULL,SHARE,EXCLUSIVE,可以認為pin是一種特定
形式的鎖.
當Library Cache Pin等待事件出現時,通常說明該Pin被其他使用者已非相容模式持有.
"library cache pin"的等待時間為3秒鐘,其中有1秒鐘用於PMON後臺程式,即在取得pin之前最多等待3秒鐘,否則就超時.
"library cache pin"的引數如下,有用的主要是P1和P2:
P1 - KGL Handle address.
P2 - Pin address
P3 - Encoded Mode & Namespace
"LIBRARY CACHE PIN"通常是發生在編譯或重新編譯PL/SQL,VIEW,TYPES等object時.編譯通常都是顯性的,
如安裝應用程式,升級,安裝補丁程式等,另外,"ALTER","GRANT","REVOKE"等操作也會使object變得無效,
可以透過object的"LAST_DDL"觀察這些變化.
當object變得無效時,Oracle 會在第一次訪問此object時試圖去重新編譯它,如果此時其他session已經把此object pin
到library cache中,就會出現問題,特別時當有大量的活動session並且存在較複雜的dependence時.在某種情況下,重新
編譯object可能會花幾個小時時間,從而阻塞其它試圖去訪問此object的程式.
------------------------------------------------------------------------------------------------------------
Latch及latch衝突
引言
Oracle Rdbms應用了各種不同型別的鎖定機制,latch即是其中的一種,本文將集中介紹latch(閂)的概念,理解latch的實現方法並說明引起latch衝突的原因。
什麼是latch
Latch是用於保護SGA區中共享資料結構的一種序列化鎖定機制。Latch的實現是與作業系統相關的,尤其和一個程式是否需要等待一個latch、需要等待多長時間有關。
Latch是一種能夠極快地被獲取和釋放的鎖,它通常用於保護描述buffer cache中block的資料結構。與每個latch相聯絡的還有一個清除過程,當持有latch的程式成為死程式時,該清除過程就會被呼叫。Latch還具有相關級別,用於防止死鎖,一旦一個程式在某個級別上得到一個latch,它就不可能再獲得等同或低於該級別的latch。
Latch與Enqueue(佇列)
Enqueue是Oracle使用的另一種鎖定機制,它更加複雜,允許幾個併發程式不同程度地共享某些資源。任何可被併發使用的物件均可使用enqueue加以保護。一個典型的例子是表的鎖定,我們允許在一個表上有不同級別的共享。與latch不同之處在於,enqueue是使用作業系統特定的鎖定機制,一個enqueue允許使用者在鎖上存貯一個標記,來表明請求鎖的模式。作業系統lock manager跟蹤所有被鎖定的資源,如果某個程式不能獲取它所請求的那種鎖,作業系統就把請求程式置於一個等待佇列中,該佇列按FIFO原則排程,而在latches中是沒有象enqueue中排序的等待佇列,latch等待程式要麼使用定時器來喚醒和重試,要麼spin(只用於多處理器情況下)。
何時需要latch
當一個程式準備訪問SGA中的資料結構時,它就需要獲得一個latch。當程式獲得latch後,它將一直持有該latch直到它不再使用此資料結構,這時latch才會被釋放。可透過latch名稱來區分它所保護的不同資料結構。
Oracle使用元指令對latch進行操作, 當所需的latch已被其他程式持有時,執行指令程式將停止執行部分指令,直到該latch被釋放為止。從根本上講,latch防止併發訪問共享資料結構,由於設定和釋放latch的指令是不可分割的,作業系統就可以保證只有一個程式獲得latch,又由於這只是單條指令,所以執行速度很快。latch被持有的時間是很短,而且提供了當持有者不正常中斷時的清除機制,該清除工作是由Oracle後臺程式PMON來完成的。
什麼導致latch衝突
Latch保護SGA中的資料結構被多個使用者同時訪問,如果一個程式不能立即得到所需latch,它就必須等待,這就導致了CPU的額外負擔和系統的速度降低。額外的CPU使用是程式‘spining’導致的,‘spining’是指程式定時地重複嘗試獲取latch,在連續兩次之間,程式處於休眠狀態,在得到latch之前,spining過程將重複進行下去。
如何標識內部latch的衝突
Server manager monitor是一個相當有用的來監視latch等待、請求和衝突的工具。也可查詢相關的資料字典表:v$latch, v$latchholder, v$latchname。
v$latch表的每一行包括了對不同型別latch的統計,每一列反映了不同型別的latch請求的活動情況。不同型別的latch請求之間的區別在於,當latch不可立即獲得時,請求程式是否繼續進行。按此分類,latch請求的型別可分為兩類:willing-to-wait和immediate。
Willing-to-wait : 是指如果所請求的latch不能立即得到,請求程式將等待一很短的時間後再次發出請求。程式一直重複此過程直到得到latch。
Immediate:是指如果所請求的latch不能立即得到,請求程式就不再等待,而是繼續執行下去。
在v$latch中的以下欄位反映了Willing-to-wait請求:
GETS---成功地以Willing-to-wait請求型別請求一個latch的次數。
MISSES---初始以Willing-to-wait請求型別請求一個latch不成功的次數。
SLEEPS---初始以Willing-to-wait請求型別請求一個latch不成功後,程式等待獲取latch的次數。
在v$latch中的以下欄位反映了Immediate類請求:
IMMEDIATE_GETS---以Immediate請求型別成功地獲得一個latch的次數。
IMMEDIATE_MISSES---以Immediate請求型別請求一個latch不成功的次數。
我們可以透過對v$latch, v$latchholder, v$latchname的查詢獲得有關latch資訊,例如:
/* 已知一個latch地址,找到latch名字 */
col name for a40
select a.name from v$latchname a, v$latch b
where b.addr = '&addr'
and b.latch#=a.latch#;
/* 顯示系統範圍內的latch統計 */
column name format A32 truncate heading "LATCH NAME"
column pid heading "HOLDER PID"
select c.name,a.addr,a.gets,a.misses,a.sleeps,
a.immediate_gets,a.immediate_misses,b.pid
from v$latch a, v$latchholder b, v$latchname c
where a.addr = b.laddr(+)
and a.latch# = c.latch#
order by a.latch#;
/* 由latch名稱顯示對latch的統計 */
select c.name,a.addr,a.gets,a.misses,a.sleeps,
a.immediate_gets,a.immediate_misses,b.pid
from v$latch a, v$latchholder b, v$latchname c
where a.addr = b.laddr(+) and a.latch# = c.latch#
and c.name like '&latch_name%' order by a.latch#;
latch有40餘種,但作為DBA關心的主要應有以下幾種:
Cache buffers chains latch: 當使用者程式搜尋SGA尋找database cache buffers時需要使用此latch。
Cache buffers LRU chain latch: 當使用者程式要搜尋buffer cache中包括所有 dirty blocks的LRU (least recently used) 鏈時使用該種latch。
Redo log buffer latch: 這種latch控制redo log buffer中每條redo entries的空間分配。
Row cache objects latch: 當使用者程式訪問快取的資料字典數值時,將使用Row cache objects latch。
下面我們將著重介紹一下如何檢測和減少redo log buffer latch的衝突。對redo log buffer的訪問是由redo log buffer latch來控制的,這種latch有兩種型別, redo allocation latch和redo copy latch。
Redo allocation latch控制redo entries在redo log buffer中的空間分配。Oracle的一個使用者程式只有得到redo allocation latch後才能為redo entries在redo log buffer中分配空間,又由於一個instance只有一個redo allocation latch,所以一次只有一個使用者程式在buffer中分配空間。當使用者程式獲得latch後,首先為redo entry分配空間,然後程式繼續持有latch並複製entry到buffer中,這種複製稱為“在redo allocation latch上的複製”(copying on the redo allocation latch),複製完畢後,使用者程式釋放該latch。
一個“在redo allocation latch上的複製”的redo entry的最大值是由初始化引數LOG_SMALL_ENTRY_MAX_SIZE定義的,根據作業系統的不同而不同。
Redo Copy Latch只應用於多CPU的系統。在多CPU的instance中,如果一個redo entry太大,超過了LOG_SMALL_ENTRY_MAX_SIZE定義值,則不能進行“在redo allocation latch上的複製”, 此時使用者程式必須獲取redo copy latch。一個instance中可以有多個redo copy latch,其數目由初始引數LOG_SIMULTANEOUS_COPIES決定,預設值為CPU數目。
在單CPU情況下,不存在redo copy latch,所有的redo entry無論大小, 都進行“在redo allocation latch上的複製”。
對redo log buffer的過多訪問將導致redo log buffer latch的衝突,latch衝突將降低系統效能,我們可透過如下查詢來檢測這種latch衝突:
col name for a40
SELECT ln.name,gets,misses,immediate_gets,immediate_misses
FROM v$latch l,v$latchname ln
WHERE ln.name IN('redo allocation','redo copy') AND ln.latch#=l.latch#
/
若misses與gets的比例超過1%或immediate_misses與(immediate_gets+immediate_misses)比例超過1%時,應考慮採取措施減少latch的衝突。
大多數的redo log buffer latch衝突是在多個CPU情況下,兩個或多個Oracle程式試圖同時得到相同的latch發生的。由於一個instance只有一個redo allocation latch,為減少redo allocation latch的衝突,應減少單個程式持有latch的時間,這可以透過減小初始引數LOG_SMALL_ENTRY_MAX_SIZE以減小redo entry的數目和大小來實現。如果觀察到有redo copy latch衝突,可以透過增大LOG_SIMULTANEOUS_COPIES 初始引數來加大latch數目,其預設值為CPU數目,最大可增大到CPU數目的兩倍。
Latches and Internal Locks (摘自 Oracle Concepts)
Latches and internal locks protect internal database and memory structures. Both are inaccessible to users, because users have no need to control over their occurrence or duration.
Latches are simple, low-level serialization mechanisms to protect shared data structures in the system global area (SGA). For example, latches protect the list of users currently accessing the database and protect the data structures describing the blocks in the buffer cache. A server or background process acquires a latch for a very short time while manipulating or looking at one of these structures. The implementation of latches is operating system dependent, particularly in regard to whether and how long a process will wait for a latch.
(最重要的是:latch是保護SGA中的共享的結構,而這種結構顯然是描述記憶體塊的組織方式的,而最常見的結構顯然就是各種lists/buckets。)
Internal locks are higher-level, more complex mechanisms than latches and serve a variety of purposes.
These locks are of very short duration and are held on entries in dictionary caches while the entries are being modified or used. They guarantee that statements being parsed do not see inconsistent object definitions.
Dictionary cache locks can be shared or exclusive. Shared locks are released when the parse is complete. Exclusive locks are released when the DDL operation is complete.
These locks protect various files. For example, one lock protects the control file so that only one process at a time can change it. Another lock coordinates the use and archiving of the redo log files. Datafiles are locked to ensure that multiple instances mount a database in shared mode or that one instance mounts it in exclusive mode. Because file and log locks indicate the status of files, these locks are necessarily held for a long time.
These locks protect tablespaces and rollback segments. For example, all instances accessing a database must agree on whether a tablespace is online or offline. Rollback segments are locked so that only one instance can write to a segment.
摘自:http://www.itpub.net/forum.php?mod=viewthread&tid=1320117&extra=&highlight=&page=2
Latches are the more restrictive mechanism, because they do not allow multiple processes to inspect the protected data structure at the same time—they provide for exclusive access only.
Locks allow for better concurrency, because they maybe held in a shared mode when the data structure is simply being inspected.
This is a simplification. The redo copy latches can be shared, but this is hardware dependent.
Another significant difference between locks and latches is request queuing.(是否排隊)
Requests for locks are queued if necessary and serviced in order, whereas latches do not support request queuing. (lock會排隊,而latch不會排隊,所以lock會發生死鎖,而latch會有餓死現象。)
If a request to get a latch fails because the latch is busy, the process just continues to retry until it succeeds. So latch requests are not necessarily serviced in order.
Because a latch can only be held by one process at a time, and because there is no inherent concept of queuing, the latch data structure itself is very simple—essentially just a single location in memory representing the state of the latch.
And because the latch data structure is so simple, the functions to get and release a latch have very little work to do. By contrast, the data structures for locks are much more sophisticated because of their support for queuing and concurrency.So the functions to get, convert, and release locks have correspondingly more work to do.
Of course, it is necessary for Oracle to ensure that only one process at a time can modify the latch and lock data structures themselves.
For latches this is easy. Because each latch is just a single location in memory, Oracle is able to use the TEST AND SET, LOAD AND CLEAR, or COMPARE AND SWAP instructions of the underlying hardware's instruction set for its latch get operations. Because these are simple machine instructions that are guaranteed to be atomic, no other locking mechanism is needed. This simplicity makes latch getsvery efficient.
Oracle's lock data structures, on the other hand, have several parts, and therefore cannot be modified atomically. For this reason, Oracle actually protects operations on locks with latches. (因為lock不能被原子性地修改,所以在修改lock時,實際上是利用了latch來保證唯一性的修改的。) The type of latch used varies depending on the type of lock. For example, the cache buffer locks are indirectly protected by the cache buffers chains latches, and the row cache enqueue locks are protected by the row cache objects latch.
總結一下:
Oracle中lock和latch的區別如下:
1)latch是十分輕量級的,而lock是複雜的結構;
2)latch是排他性的訪問,沒有排隊機制,存在餓死現象;而lock允許併發,有排隊機制,存在死鎖現象;
3)latch是修改是原子性的,而lock的修改時要latch保護的;
4)latch只用於SGA記憶體中的structures;
About Me
...............................................................................................................................
● 本文整理自網路
● 本文在itpub(http://blog.itpub.net/26736162)、部落格園(http://www.cnblogs.com/lhrbest)和個人微信公眾號(xiaomaimiaolhr)上有同步更新
● 本文itpub地址:http://blog.itpub.net/26736162/abstract/1/
● 本文部落格園地址:http://www.cnblogs.com/lhrbest
● 本文pdf版及小麥苗雲盤地址:http://blog.itpub.net/26736162/viewspace-1624453/
● 資料庫筆試面試題庫及解答:http://blog.itpub.net/26736162/viewspace-2134706/
● QQ群:230161599 微信群:私聊
● 聯絡我請加QQ好友(646634621),註明新增緣由
● 於 2017-07-01 09:00 ~ 2017-07-31 22:00 在魔都完成
● 文章內容來源於小麥苗的學習筆記,部分整理自網路,若有侵權或不當之處還請諒解
● 版權所有,歡迎分享本文,轉載請保留出處
...............................................................................................................................
拿起手機使用微信客戶端掃描下邊的左邊圖片來關注小麥苗的微信公眾號:xiaomaimiaolhr,掃描右邊的二維碼加入小麥苗的QQ群,學習最實用的資料庫技術。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26736162/viewspace-2142070/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- ORACLE LOCK,LATCH,PINOracle
- 【 latch和lock的區別 】
- latch和lock的區別
- Latch 與 Lock 的區別
- Latch和Lock的區別(轉)
- Oracle中latch和lock的區別Oracle
- snapshot 和 view,lock 和 latch 的區別View
- Lock、Synchronized鎖區別解析synchronized
- 共享池之六:shared pool latch/ library cache latch /lock pin 簡介
- 由最長SQL想到的Latch Free( Library Cache Pin/Lock)整理~~草稿SQL
- library cache lock和library cache pin區別總結
- Oracle Latch & LockOracle
- 【筆記】lock and latch筆記
- enqueue, latch的理解及區別ENQ
- 【ASK_ORACLE】Library cache pin 與 library load lock的關係和區別Oracle
- Oracle 之pin和lockOracle
- synchronized與Lock的區別synchronized
- Lock 和 synchronized的區別synchronized
- sql version count引發cursor:pin s wait x及library cache latch library cache lockSQLAI
- mutex,latch,lock,enqueue hash chains latch基礎概念MutexENQAI
- create index online與非online在library cache lock/pin方面的區別Index
- latch:library cache lock等待事件事件
- 原子鎖和普通鎖的區別
- 【JavaSE】Lock鎖和synchronized鎖的比較,lock鎖的特性,讀寫鎖的實現。Javasynchronized
- spin_lock、spin_lock_irq、spin_lock_irqsave區別【轉】
- library cache pin/lock的解決辦法
- enq:Library cache lock/pin等待事件ENQ事件
- Library cache lock/pin詳解(轉)
- 分散式鎖的區別分散式
- ORACLE鎖存器(LATCH)Oracle
- zt_oracle lock type鎖型別詳解Oracle型別
- library cache lock\pin的查詢與處理
- oracle lock鎖_v$lock_轉Oracle
- synchronized與Lock的區別與使用詳解synchronized
- 基礎才是重中之重~lock和monitor的區別
- Mysql中S 鎖和 X 鎖的區別MySql
- oracle資料庫事務transaction 不同的鎖lock型別Oracle資料庫型別
- Shared pool的library cache lock/pin及硬解析