Monitoring and Detecting Lock Contention
1、Locking機制
1)Oracle Server中是自動管理鎖的。默認會使用最低的鎖級別對數(shù)據(jù)進行一致性的保護,從而滿足最大的并發(fā)度。
note:默認的鎖機制可以通過ROW_LOCKING改變。默認該值是ALWAYS,它將在DML語句中使用最低級別的鎖。另一個可能的值是 INTENT,它將使用更高級別的限制(table level),除了select for update語句,它將使用行級鎖。
2)quiesced database:如果Oracle被設置為只有DBA可以訪問的狀態(tài)時,就是quiesced database。
3)鎖的種類:
** DML locks:
①表級鎖(TM):當修改table data時,被設置,如:INSERT, UPDATE, DELETE, SELECT … FOR UPDATE或LOCK TABLE。此時table將被加鎖,避免其他DDL的操作引起transaction之間的沖突。
## 在TM中又可分為兩種鎖,是由server根據(jù)當前其他表鎖的加載情況而自動為DML選擇加上的。這兩種鎖具體是:row exclusive(RX),運行其他transaction中的insert、update、delete或其他加行級鎖的并發(fā)操作在當前同一 table上,但不允許其他手動加載的排他讀/寫鎖;row share(RS),運行SELECT … FOR UPDATE命令時加載的表鎖,這只會對避免其他事務手動的對當前table加載鎖用于排他的寫操作。
## 表鎖模式:
(i)手動加載表鎖模式使用語句LOCK TABLE table_name IN mode_name MODE; –一般不使用這種明確加鎖的方法,只有application要求,才會不得不加較高級別的鎖。
(ii)Share(S)鎖模式:此類表鎖只允許其他transaction發(fā)出select … from update的請求,不允許任何對table的修改。隱含式的獲得share lock的sql語句中,會包含相應的完整性約束。在9i中,不會申請子表中外鍵字段的索引約束。
(iii)Share Row Exclusive(SRX):它是比S模式更高的鎖模式。它不允許任何其他的DML語句和手動加載的共享鎖模式。相應的SQL語句會隱式的獲得相應的完整性約束的SRX鎖。
(iv)Exclusive(X)鎖:這是最高的鎖模式,只允許其他對該表的查詢請求,拒絕一切對表的任何DML操作和手動鎖。
②行級鎖(TX):當發(fā)出命令INSERT, UPDATE, DELETE, SELECT … FOR UPDATE命令時,會自動為所操作的row對象加TX,從而確保沒有其他user同時對同一行進行才操作。
一個DML事務,會同時獲得兩個鎖:共享表級鎖和排他行級鎖。獲得行級鎖的每行都返回
③在blocks中的DML鎖:加鎖的信息只有在transaction被commit或是rollback后才會被清除。而不是在當前事務的下一個請求語句發(fā)起時被釋放。在blocks header中,Oracle server為每個當前active的transaction保存了一個標識符。在每條row中,會有一個lock byte存儲了包含當前transaction的slot的標識符。
** DDL locks:避免對schema對象的定義時,有其他相關的DDL操作進行。
Oracle是通過入隊的方式對鎖進行維護的,入隊機制會記錄下面的信息:user等待的locks被其他user占用;users請求的locks的具體類型;users請求的locks的順序。
可以通過改變參數(shù)DML_LOCKS和ENQUEUE_RESOURCES參數(shù)來增加可被request的locks。這在Parallel server中是必須的設置。DDL鎖的分類有:
①Exclusive DDL Locks:某些DDL語句,如CREATE, ALTER, DROP,必須獲得其操作object的排他鎖。如果其他user獲得了其他任何級別的lock,當前user都不能得到其DDL的排他鎖。
②Shared DDL locks:當發(fā)起GRANT和CREATE PACKAGE操作時,需要獲得相應object的共享DDL lock。該類locks不會阻止類似的DDL語句或是任何DML語句,但會防止其他user對當前引用的object被修改或刪除。
③Breakable Parse Locks:保存在library cache中的statement和PL/SQL對象保存了其引用的每個object的breakable parse Lock,直到該statement過期。它用于檢驗library cache中的相應內(nèi)容是否因為object的改變而可用。
2、可能引起Locks沖突的原因:
1)使用了不必要的high-level鎖
2)長期運行的transaction的存在
3)user沒有及時的commit對database的修改
4)使用Oracle instance的application使用了higher locks
3、監(jiān)控并診斷當前加鎖情況的工具
1)如上圖所示,其中視圖DBA_WAITERS和DBA_BLOCKERS用于進一步查看當前獲得或是等待不同table的locks的信息。對此,需要用$ORACLE_HOME/rdbms/admin中的catblock.sql腳本創(chuàng)建。
2)對于v$lock視圖來說,當lock tpye為TX時,id1中顯示的回滾段的number和slot number;當lock tpye為TM時,id1中顯示的是被修改表的object ID。
SELECT owner, object_id, object_name, object_type, v$lock.type FROM dba_objects, v$lock WHERE object_id=v$lock.id1 and object_name=table_name;
3)V$LOCKED_OBJECT視圖
XIDUSN:Rollback segment number
OBJECT_ID:ID of the object being modified
SESSION_ID:ID of the session locking the object
ORACLE_USERNAME
LOCKED_MODE
在此視圖中,當XIDUSN為0時,則表示當前session正在等他其他已經(jīng)獲得該lock的session釋放。
4)關于腳本utllockt.sql
可以使用$ORACLE_HOME/rdbms/admin/utllockt.sql腳本顯示當前等待lock的進程繼承關系。但使用之前必須用catblock.sql腳本創(chuàng)建視圖dba_locks和dba_blockers。
5)如果想要得知哪一行造成了lock沖突,可以查看v$session中的row_wait_block#, row_wait_row#, row_wait_file#, row_wait_obj#四個字的的值。
4、解決locks的沖突方法有:一方面可以請相應的user做commit/rollback;在萬不得已的時候,可以kill掉某些user session,從而回滾相應的transaction并釋放locks。具體方法如下:
select sid, serial#, username from v$session where type=’USER’;
alter system kill session ’sid,serial#’;
5、死鎖:對于Oracle,當其檢測到死鎖的存在,會rolling back那個檢測到死鎖的語句,當不是整個transaction的rollback。必要時,需要DBA完成剩下的rollback工作。明確的指明語 句中使用的鎖,從而覆蓋默認的鎖機制,可能容易引起deadlock。
當發(fā)生死鎖后,server會將deadlock的情況記錄到USER_DUMP_DEST目錄下的跟蹤文件。在分布式transaction中,本地的 deadlock是通過等待關系圖(waits for graph)來判斷的,全局死鎖是通過time-out來判斷的。
posted on 2010-01-12 12:31 gdufo 閱讀(512) 評論(0) 編輯 收藏 所屬分類: Database (oracle, sqlser,MYSQL)