Oracle數據庫用了多種系統鎖保護內部數據庫和內存結構,這些機制對於用戶來說是透明的。
闩是簡單的、低級別的序列化機制,協調多個用戶使用共享數據結構、對象和文件,闩在並行處理中保護共享內存資源,特別地,闩在下面的場景中保護數據結構:
1)被多個session並行修改;
2)當被一個session讀的同時被另一個session修改;
3)當被訪問時重新分配內存。
通常,在SGA中單個闩保護多個對象,例如,後台進程(例如DBWn和LGWR)從共享池(shared pool)分配內存創建數據結構,為了分配這些內存,這些進程用一個共享池闩防止兩個進程同時檢查或修改共享池。內存被分配後,其它進程可能需要訪問共享池,例如庫緩存(library cache),用於解析,這時,進程闩只鎖庫緩存,不鎖整個共享池。
不像隊列闩,例如行鎖,闩不允許session排隊。當一個闩成為可用時,發起請求的第一個session獲取到闩。當一個進程在一個循環中重復地請求一個闩,叫做Latch spinning,而一個進程等待請求闩期間睡眠釋放CPU,則叫做latch sleeping。
通常,一個Oracle進程在操作或查看一個數據結構時只獲取闩極短的時間,例如,當處理一個雇員的薪水更新時,數據庫可以獲取和釋放幾千次鎖。闩的實現依賴於操作系統,特別是對於怎麼處理闩的等待。
闩的增加意味著並行度的減少,例如,排它硬解析操作會競爭庫緩存闩。V$LATCH試圖包含了每種闩使用的統計信息,包括每種闩被請求的次數和等待的時間。
互斥排它對象(互斥鎖)是一個低級別的機制,用於防止一個內存對象在並發操作時過期或者腐化。互斥鎖和闩類似,但通常闩保護一組對象,互斥鎖則保護單個對象。
互斥鎖通常用於:
1)減少競爭;
因為闩保護多個對象,當多個進程嘗試並發的進入這多個對象的任意一個時,都會阻塞其它進程對其它對象的訪問。而互斥鎖減少了鎖的范圍,減少競爭。
2)互斥鎖比闩花費更少的內存;
3)當使用共享模式時,一個互斥鎖允許被多個session並行引用。
內部鎖是比闩和互斥鎖更高級別、更復雜的機制,數據庫使用那個下面幾種類型的互斥鎖:
這些鎖持續時間很短,當字典緩存的條目被修改或者使用時使用。它們保證被解析的語句看不到不一致的對象定義。字典緩存做能是共享的或者排它的,當解析完成時共享鎖被釋放,而當DDL操作完成時排它鎖被釋放。
這些鎖保護各種文件,例如,一種內部鎖保護控制文件(control file)以至於一次僅有一個進程能夠改變它,另一種鎖協調在線重做日志文件的使用和歸檔。數據文件被鎖以確保多個實例在共享模式下裝載一個數據庫或者一個實例在排它模式裝載一個數據庫。因為文件和日志鎖表示了文件的狀態,這些鎖不可避免是需要長時間持有的。
這些鎖保護表空間和undo段。例如,一個數據庫的所有實例對於一個表空間是在線還是下線必須保持一致。為了保證一次僅一個數據庫能寫入一個undo段,undo段必須加鎖。