oracle鎖機制研究
oracle鎖機制研究
不同於其他資料庫,oracle提供了行級鎖,在保證資料一致性的情況下極大的提高了併發訪問的效率
oracle提供了三中鎖模式
Null 主要用於對資料字典物件的訪問
Share 鎖持有者對資源進行只讀訪問,允許其他程式併發對資源只讀訪問
Exclusive 鎖持有者對資源進行修改,不允許其他進行對資源做任何訪問
對於行級鎖,oracle提供了TM鎖和TX鎖來分別保護表和被修改的資料行
(一)TX鎖用於保護當前修改的資料行不被其他併發訪問的事務所修改
開啟一個會話,修改資料
--會話1
SQL> update t set seq=10 where seq=10;
1 row updated.
我們開啟另外一個會話,也修改同一資料行
會話2
SQL> update t set seq=10 where seq=10;
沒有任何反應,被阻塞
查詢會話等待事件
SQL> select w.SID,w.EVENT from v$session_wait w where w.WAIT_CLASS<>'Idle';
SID EVENT
---------- ----------------------------------------------------------------
48 enq: TX - row lock contention
可以看到會話2被TX鎖阻塞,等待TX鎖的釋放
處理會話1
SQL> commit;
Commit complete.
再觀察一下會話2
SQL> update t set seq=10 where seq=10;
1 row updated.
再次進行查詢等待時間,發現等待時間消失。
進一步驗證了TX主要用來保護資料行不被其他併發訪問的事務所修改
(二)TM鎖:TM鎖用於在併發事務訪問過程中保護表的結果,TM鎖共有以下五種模式
1、行級排他鎖(RX鎖)
我們進行DML操作更新表的資料或者顯示執行lock table * in row exclusive mode,都會在對應的表上加行級排他鎖(RX鎖)
該鎖定模式允許其他事務修改資料表中的其他資料行,也允許其他併發事務在該表上加RX鎖,
但是不允許在該表上加S和X模式的鎖
會話1
SQL> lock table t in row exclusive mode;
Table(s) Locked.
會話2
SQL> lock table t in row exclusive mode;
Table(s) Locked.
SQL> lock table t in share mode;
同樣在該表上加share模式的鎖也產生等待
通過等待事件查詢如下:
SQL> select w.SID,w.EVENT from v$session_wait w where w.WAIT_CLASS<>'Idle';
SID EVENT
---------- ----------------------------------------------------------------
10 enq: TM - contention
等待獲得TM鎖的釋放
2、行級共享鎖(RS鎖)
通常是通過select … from for update語句新增的,同時該方法也是我們用來手工鎖定某些記錄的主要方法。比如,當我們在查詢某些記錄的過程中,
不希望其他使用者對查詢的記錄進行更新操作,則可以發出這樣的語句。當資料使用完畢以後,直接發出commit或者rollback命令將鎖定解除。
當表上新增了RS鎖定以後,不允許其他事務對相同的表新增排他鎖(RX,X,SRX),允許其他事務對錶增加RS,S鎖,也允許其他的事務通過DML語句或lock命令鎖定相同表裡的其他資料行。
會話1
SQL> select * from t where seq=10 for update;
SEQ
----------
10
會話2
SQL> select * from t where seq=10 for update;
產生了等待,同樣是等待TM鎖的釋放
會話1
SQL> lock table t in row share mode;
Table(s) Locked.
會話2
SQL> lock table t in row share mode;
Table(s) Locked.
SQL> lock table t in share mode;
Table(s) Locked.
執行以下三個語句都產生了等待
SQL> lock table t in exclusive mode;
SQL> lock table t in row exclusive mode;
SQL> lock table t in share row exclusive mode;
3、共享鎖(S鎖)
通過lock table * in share mode對錶增加共享鎖,不允許併發事務更新該表,也不允許併發對該表增加排他型別的鎖(X,RX,SRX),但允許共享模式索引該表(S,RS)
允許其他使用者以select * from .. for update鎖定該表
會話1
SQL> lock table t in share mode;
Table(s) Locked.
會話2
SQL> lock table t in share mode;
Table(s) Locked.
SQL> lock table t in row share mode;
Table(s) Locked.
新增以下三種模式的鎖都產生了等待
SQL> lock table t in exclusive mode;
SQL> lock table t in row exclusive mode;
SQL> lock table t in share row exclusive mode;
同樣不允許更新該表資料
SQL> update t set seq=10 where seq=1;
4、排他鎖(X)
通過lock table .. in exclusive mode,對錶增加拍他鎖,這時對該表不能做DML操作,只能做查詢,同樣不允許併發事務對該表新增任何型別的鎖
會話1
SQL> lock table t in exclusive mode;
Table(s) Locked.
其他併發會話的以下所有操作都產生等待
SQL> lock table t in share mode;
SQL> lock table t in row share mode;
SQL> lock table t in share row exclusive mode;
SQL> lock table t in exclusive mode;
SQL> update t set seq=10 where seq=1;
都在等待TM鎖的釋放
5、共享行級排他鎖(SRX)
可以通過lock table .. in share row exclusize mode對錶加SRX鎖,可以對該表加RS鎖,同樣併發事務不能對該表加任何模式的鎖,
會話1
SQL> lock table t in exclusive mode;
Table(s) Locked.
會話2的以下操作都產生等待
SQL> lock table t in share row exclusive mode;
SQL> lock table t in share mode;
SQL> lock table t in row exclusive mode;
SQL> update t set seq=10 where seq=1;
這五種TM相容關係如下
- S X RS RX SRX
S √ × √ × ×
X × × × × ×
RS √ × √ √ √
RX × × √ √ ×
SRX × × √ × ×
對Oracle資料庫中的各SQL語句所產生的表級鎖的情況進行彙總,如下表所示:
SQL語句 表鎖定模 允許的表鎖定模式
Select * from …… RS RS、RX、S、SRX、X
Insert into …… RX RS、RX
Update …… RX RS、RX
Delete from …… RX RS、RX
Select * from for update RS RS、RX、S、SRX
lock table in row share mode RS RS、RX、S、SRX
lock table in row exclusive mode RX RS、RX
lock table in share mode S RS、S
lock table in share row exclusive mode SRX RS
lock table in exclusive mode X
對於通過lock table命令主動新增的鎖定來說,如果要釋放它們,只需要發出rollback命令即可。
(三)單例項下oracle鎖的型別
根據保護的物件不同,Oracle資料庫鎖可以分為以下幾大類:DML鎖(data locks,資料鎖),用於保護資料的完整性;DDL鎖(dictionary locks,字典鎖),
用於保護資料庫物件的結構,如表、索引等的結構定義;內部鎖和閂(internal locks and latches),保護資料庫的內部結構。
當Oracle執行DML語句時,系統自動在所要操作的表上申請TM型別的鎖。當TM鎖獲得後,系統再自動申請TX型別的鎖,並將實際鎖定的資料行的鎖標誌位進行置位。
這樣在事務加鎖前檢查TX鎖相容性時就不用再逐行檢查鎖標誌,而只需檢查TM鎖模式的相容性即可,大大提高了系統的效率
(四)與鎖相關的檢視
1、v$lock檢視
v$lock檢視列出當前系統持有的或正在申請的所有鎖的情況,其主要欄位說明如下:
欄位名稱 |
型別 |
說明 |
SID |
NUMBER |
會話(SESSION)標識; |
TYPE |
VARCHAR(2) |
區分該鎖保護物件的型別; |
ID1 |
NUMBER |
鎖標識1; |
ID2 |
NUMBER |
鎖標識2; |
LMODE |
NUMBER |
鎖模式:0(None),1(null),2(row share), 3(row exclusive),4 (share),5(share row exclusive),6(exclusive) |
REQUEST |
NUMBER |
申請的鎖模式:具體值同上面的LMODE |
CTIME |
NUMBER |
已持有或等待鎖的時間; |
BLOCK |
NUMBER |
是否阻塞其它鎖申請;0未阻塞 1 阻塞 |
在rac環境下,block欄位值還會多一個數值2,表示rac環境下節點間潛在的鎖申請。
兩個節點各有一個程式申請鎖
節點1
SQL> update t set t.seq=10 where seq=10
1 row updated.
SQL> select * from gv$lock where type='TX';
INST_ID ADDR KADDR SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK
---------- -------- -------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
1 322E2C84 322E2DA0 120 TX 655365 165 6 0 7 2
雖然其他節點並沒有修改這一行資料,但是仍然存在block為2的潛在鎖申請。
節點2修改這一行資料
SQL> update t set seq=10 where seq=10;
產生等待。
SQL> select * from gv$lock where type='TX';
INST_ID ADDR KADDR SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK
---------- -------- -------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
2 343BAB70 343BAB84 132 TX 524312 230 0 6 59 0
1 322E2C84 322E2DA0 120 TX 524312 230 6 0 187 2
已經有了全域性鎖申請,但是block欄位沒有變化。
其中在TYPE欄位的取值中,本文只關心TM、TX兩種DML鎖型別;
關於ID1、ID2,TYPE取值不同其含義也有所不同:
TYPE |
ID1 |
ID2 |
TM |
被修改表的標識(object_id) |
0 |
TX |
以十進位制數值表示該事務所佔用的回滾段號與該事務在該回滾段的事務表(Transaction table)中所佔用的槽號(slot number,可理解為記錄號)。其組成形式為: 0xRRRRSSSS ( RRRR = RBS number, SSSS = slot )。 |
以十進位制數值表示環繞(wrap)次數,即該槽(slot)被重用的次數; |
2、v$locked_object檢視
v$locked_object檢視
v$locked_object檢視列出當前系統中哪些物件正被鎖定,其主要欄位說明如下:
欄位名稱 |
型別 |
說明 |
XIDUSN |
NUMBER |
回滾段號; |
XIDSLOT |
NUMBER |
槽號; |
XIDSQN |
NUMBER |
序列號; |
OBJECT_ID |
NUMBER |
被鎖物件標識; |
SESSION_ID |
NUMBER |
持有鎖的會話(SESSION)標識; |
ORACLE_USERNAME |
VARCHAR2(30) |
持有該鎖的使用者的Oracle使用者名稱; |
OS_USER_NAME |
VARCHAR2(15) |
持有該鎖的使用者的作業系統使用者名稱; |
PROCESS |
VARCHAR2(9) |
作業系統的程式號; |
LOCKED_MODE |
NUMBER |
鎖模式,取值同v$lock檢視的LMODE; |
3、dba_blockers和dba_waiters檢視雖。
為了方便我們查詢會話的阻塞狀態,當前會話被那個會話阻塞,哪些會話處於被阻塞,oracle提供dba_blockers和dba_waiters檢視,為了能夠訪問這兩個檢視,需要執行 $ORACLE_HOME/rdbms/admin/catblock.sql.舉例如下
會話1
SQL> update t set seq=10 where seq=10;
會話2
SQL>update t set seq=20 where seq=20;
回到會話1
SQL>update t set seq=20 where seq=20;
會話1被會話2阻塞,通過查詢這兩個檢視
SQL> select * from dba_blockers;
HOLDING_SESSION
---------------
25
只有一列,記錄了哪些session持有tx鎖導致其他會話阻塞,當前查詢得知sid=25的會話阻塞了其他會話持有tx鎖
進一步查詢dba_waiters可以查詢到哪個會話被sid=25的會話阻塞
SQL> SQL> select WAITING_SESSION,HOLDING_SESSION from dba_waiters;
WAITING_SESSION HOLDING_SESSION
--------------- ---------------
28 25
sid=28的會話被sid=25的會話阻塞,我們可以通過
alter system kil session '25,1'
清除25會話之後,發現兩個檢視中對應記錄消失。
當然只是比較簡單的情況,具體的生產環境會比較複雜,需要通過關聯v$session檢視來進一步檢視具體的會話資訊,連線資訊以便及時監控,並聯系應用開發人員處理。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7483882/viewspace-762671/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle多粒度封鎖機制研究2Oracle
- Oracle多粒度封鎖機制研究1Oracle
- Oracle多粒度封鎖機制研究(zt)Oracle
- Oracle多粒度封鎖機制研究二(zt)Oracle
- Oracle鎖機制Oracle
- oracle 鎖機制Oracle
- ORACLE鎖機制-轉載Oracle
- oracle中的鎖機制Oracle
- ORACLE DML鎖定機制Oracle
- ORACLE鎖機制深入理解Oracle
- ORACLE 鎖機制及解決方法Oracle
- ORACLE 資料庫中的鎖機制Oracle資料庫
- oracle的鎖和並行機制薦Oracle並行
- Oracle的鎖機制歸納總結Oracle
- PHP 鎖機制PHP
- SQLite鎖機制SQLite
- Mysql鎖機制MySql
- java鎖機制Java
- SQL鎖機制SQL
- oracle deadlock 之(一)--鎖機制介紹Oracle
- Oracle回收站表閃回機制研究Oracle
- 轉貼:Oracle的鎖機制歸納總結Oracle
- Oracle資料庫資料鎖機制解析(zt)Oracle資料庫
- Mysql鎖機制分析MySql
- Enqueue 鎖定機制ENQ
- MS SQL鎖機制SQL
- mysql的鎖機制MySql
- 分散式鎖機制分散式
- [鎖機制] 鎖相關查詢
- Java反射機制研究Java反射
- ckpt(checkpoint)機制研究
- cbo機制的研究
- ORACLE DML語句鎖機制導致事務等待示例Oracle
- Mysql中的鎖機制——MyISAM表鎖MySql
- synchronized鎖機制 之 程式碼塊鎖synchronized
- 資料庫鎖機制資料庫
- Mysql各種鎖機制MySql
- mysql myisam的鎖機制MySql