TX鎖(Transaction Lock)分析 (zt)
資料記錄被鎖
我們知道,Oracle中事務產生的索都是行級鎖。也就說,事務在對錶做更新操作(Update、Delete)時,只在針對資料塊中需要更新的資料記錄加鎖。這種型別的鎖就是我們最常見的鎖。看下面的例子:
SQL> create table
t_lock(a number, b varchar2(20), c char(10)) initrans 1 maxtrans 3;
Table created
SQL> insert into t_lock values(1,1,1);
1 row inserted
SQL> commit;
Commit complete
會話1:
SQL> update t_lock se
t b='2' where a=1;
1 row updated
會話2:
SQL> delete t_lock where a
=
1;
會話1鎖住了a=1的記錄,會話試圖刪除該記錄時,被hung住。
SQL> select * from dba_waite
rs;
WAITING_SESSION HOLDING_SESSION
LOCK_TYPE MODE_HELD MODE_REQUESTED LOCK_ID1 LOCK_ID2
--------------- --------------- ---------
---------
-------------- -------- --------
28 20 Transaction Exclusive Exclusive 1048671 40361
並且,如果將t_lock的資料塊dump出來的話,也可以看到在記錄行上的鎖標誌
tl: 19 fb: --H-FL-- lb: 0x1
cc: 3
其中,0x1對應的是產生鎖的事務在資料塊itl列表中的條目號。
資料塊中itl條目達到最大限制時產生的鎖
ITL(Interested Transaction List)直白點說就是對該資料塊“有興趣”的事務列。也就是會對該資料塊進行修改的事務。一個表的資料塊上同時最多可以有多少個事務對其進行更新,是由建立表時的引數maxtrans指定的。但是,如果表建立在基於9i新特性ASSM(自動段空間管理)的表空間上的話,那麼指定的maxtrans就無效,一律都是255。比如上面的例子中,我們指定了maxtrans為3(表空間不是ASSM),所以同時最多隻能有3個事務對一個資料塊進行更新。看下面的例子。
先給上面的表多插入一些資料:
SQL> insert into t_lock values(
2,2,2);
1 row inserted
SQL> insert into t_lock values(3,3,3);
1 row inserted
SQL> insert into t_lock values(4,4,4);
1 row inserted
SQL> insert into t_lock values(5,5,5);
1 row inserted
SQL> commit;
Commit complete
會話1:
SQL> update t_lock set b='2' w
here a=1;
1 row updated
會話2:
SQL> update t_lock set b=
'2' where a=2;
1 row updated
會話3:
SQL> update t_lock set b=
'2' where a=3;
1 row updated
會話4:
SQL> update t_lock set b=
'2' where a=4;
1 row updated
前面已經佔用了3個itl slot,第4個事務再申請itl時被hung住了。
SQL> select * from dba_wa
iters;
WAITING_SESSION HOLDING_SESSI
ON LOCK_TYPE MODE_HELD MODE_REQUESTED LOCK_ID1 LOCK_ID2
--------------- --------------- ---------
---------
-------------- -------- --------
19 27 Transaction Exclusive Exclusive 1048671 40361
Dump出資料塊,可以看到itl已經達到最大限制條目數:
seg/obj: 0x87c0 csc: 0x00.a337
dee9 itc: 3 flg: - typ: 1 - DATA
fsl: 0 fnx: 0x0 ver: 0x01
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0008.053.00009ef3 0x00802e6a.71b4.2b ---- 1 fsc 0x0000.00000000
0x02 0x000d.037.0000a98a 0x0080655a.ac1f.2b ---- 1 fsc 0x0000.00000000
0x03 0x000c.004.0000acb9 0x008006a6.06bc.28
---- 1 fsc 0x0000.00000000
這裡我們需要提出另外一個問題,如果事務操作不是update、delete,而是進行Insert操作,會不會也會達到maxtrans的限制呢?做個試驗看下吧:
會話1:
SQL> update t_lock set b='2' wh
ere a=1;
1 row updated
會話2:
SQL> update t_lock set b
='2' where a=2;
1 row updated
會話3:
SQL> update t_lock set b=
'2' where a=3;
1 row updated
會話4:
SQL> insert into t_lock va
lues(6,6,6);
1 row inserted
這時,儘管已經分配itl條目給三個事務,但是第四個事務在做insert插入操作時並沒有被hung住。
看下資料塊dump內容:
Object id on Block? Y
seg/obj: 0x87c0 csc: 0x00.a337df1b itc: 3 flg: O typ: 1 - DATA
fsl: 0 fnx: 0xa03000c ver: 0x01
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0003.00b.0000a3ab 0x0080397c.0b0f.2a ---- 1 fsc 0x0000.00000000
0x02 0x0000.000.00000000 0x00806a5a.as1e.2b ---- 1 fsc 0x0000.00000000
0x03 0x000e.037.0000a458 0x1440
1ff2.17d8.2b ---- 1 fsc 0x0000.00000000
我們發現,確實只有三個transaction在這個資料塊上。那麼還有一個事務呢?別急,把下一個資料塊dump出來看看:
Object id on Block? Y
seg/obj: 0x87c0 csc: 0x00.a337df22 itc: 1 flg: O typ: 1 - DATA
fsl: 0 fnx: 0x0 ver: 0x01
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0004.038.0000a6dc 0x00806
fbf.bb4e.0e ---- 1 fsc 0x0000.00000000
原來如此!在做insert操作時,如果發現資料塊已經達到maxtrans的最大限制,就從freelist中取出下一空閒資料塊進行插入操作,而不管是否達到pctused的限制了。
Table上有Index時達到maxtrans限制
以上的測試是針對table上沒有index時做的測試。當在table上建了index,情況就變得複雜多了。
· 場景一:
SQL> drop table t_l
ock;
Table dropped
SQL> create table t_lock(a number, b varchar2(20), c char(10)) initrans 1 maxtrans 5;
Table created
SQL> insert into t_lock values(1,1,1);
1 row inserted
SQL> insert into t_lock values(2,2,2);
1 row inserted
SQL> insert into t_lock values(3,3,2);
1 row inserted
SQL> insert into t_lock values(4,4,2);
1 row inserted
SQL> insert into t_lock values(5,5,1);
1 row inserted
SQL> commit;
Commit complete
SQL> create index t_lock_idx on t_lock(a) maxtrans 3;
Index created
會話1:
SQL> delete from t_lock where a
=1;
1 row deleted
會話2:
SQL> delete from t_lock where a
=2;
1 row deleted
(注意:以上操作都會索引列)
會話3:
SQL> update t_lock2 set b=2
where b=2;
1 row updated
(注意:這個會話沒有涉及索引列)
會話4:
SQL> delete from
t_lock
where a=3;
第4個會話被hung住了:
SQL> select * from dba_
waiters;
WAITING_SESSION HOLDING_SESSION LOCK_TYPE MODE_HELD MODE_REQUESTED LOCK_ID1 LOCK_ID2
--------------- --------------
- --------- --------- -------------- -------- --------
19 20 Transaction Exclusive Share 393284 42733
我們的table上的maxtrans是5,這裡並沒有達到,而index上的maxtrans是3,第4個Transaction被hung。這裡似乎可以下一個結論:table上有index的話,如果達到index上的maxtrans限制,後面的事務就會被hung住。但是,請注意第3個會話,他的操作並沒有涉及到索引列,那麼去掉第3個會話會怎樣?
· 場景二:
會話1:
SQL> delete from t_lock
where a=1;
1 row deleted
會話2:
SQL> delete from t_lock wh
ere a=2;
1 row deleted
(注意:以上操作都會索引列)
會話3:
SQL> delete from t_lock
where
a=3;
第3個會話被hung住了:
SQL> select * from dba_waiters;
WAITING_SESSION HOLDING_SESSION LOCK_TYPE MODE_HELD MODE_REQUESTED LOCK_ID1 LOCK_ID2
--------------- --------------- --------- ---
------ -------------- -------- --------
27 20 Transaction Exclusive Share 1048605 40351
這裡,第3個會話就被hung住了。那就是說對有index得情況來說,itl數的限制是minx(maxtrans_of_index1 - 1, maxtrans_of_index2 – 1..., maxtrans_of_table) 。
我們前面提到,如果在insert時發現資料塊的itl數已經達到maxtrans的限制,那麼會在一個新的資料塊進行插入,以避免會話阻塞。那麼有了index以後,是否還是這樣呢?看下面這種情況。
· 場景三:
會話1:
SQL> delete from t_lo
ck where a=1;
1 row deleted
會話2:
SQL> delete from t_lock w
here a=2;
1 row deleted
(注意:以上操作都會索引列)
會話3:
SQL> insert into t_lock values(6,
6
,6);
第3個會話被hung住了:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/35489/viewspace-997020/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Fabric 1.0原始碼分析(43) Tx(Transaction 交易)原始碼
- 等待事件enq TX row lock contention分析事件ENQ
- 關於enq: TX - row lock contention行鎖的總結ENQ
- AWR實戰分析之----enq: TX - row lock contentionENQ
- zt_oracle lock type鎖型別詳解Oracle型別
- ORACLE TX鎖Oracle
- oracle資料庫事務transaction 不同的鎖lock型別Oracle資料庫型別
- oracle資料庫事務transaction鎖lock模式思考之一Oracle資料庫模式
- enq: TX - row lock contentionENQ
- TX:ITL LOCK(INITRANS,MAXINTRANS)
- enq: TX – row lock contention的測試和案例分析ENQ
- oracle的TM鎖、TX鎖Oracle
- oracle事務transaction鎖lock一點兒小思考或總結Oracle
- 產生TX鎖等待不同情形的分析
- TX鎖查詢
- zt_library cache pin和lock等待分析
- 等待事件enq: TX - row lock contention事件ENQ
- 【等待事件】-enq: TX - row lock contention事件ENQ
- Lock的獨佔鎖和共享鎖的比較分析
- Oracle的TX鎖(行級鎖、事務鎖)Oracle
- 奇異的enq: TX - row lock contentionENQ
- Oracle TX鎖的處理Oracle
- enq: TX - row lock contention等待事件處理ENQ事件
- oracle lock鎖_v$lock_轉Oracle
- oracle的TM鎖、TX鎖知識完全普及Oracle
- 對TM鎖和TX鎖的簡單理解
- 結合ReentrantLock獲得鎖分析AQS,lock過程分析ReentrantLockAQS
- 【Oracle九大效能檢視】之1.v$lock_處理TX鎖實驗及總結Oracle
- lock鎖和monitor.enter鎖
- 【JavaSE】Lock鎖和synchronized鎖的比較,lock鎖的特性,讀寫鎖的實現。Javasynchronized
- 關於 TX 鎖的兩句sqlSQL
- zt_Orace ITL(Interested Transaction List) 說明REST
- Lock wait timeout exceeded; try restarting transactionAIREST
- mysql innodb lock鎖之record lock之一MySql
- Oracle Enqueues Wait Events 三 enq: TX - row lock contentionOracleENQAI
- 無關的表引起的enq: TX - row lock contentionENQ
- 【Mysql】metadata lock鎖MySql
- MYSQL 鎖:metadata lockMySql