DML操作引起的blocking(二)
2、並行插入相同主鍵記錄
我們嘗試構建一個同時插入主鍵相同的記錄,看看Oracle是如何處理這樣的情況。這兩條資料就是相關資料,因為正常條件下,兩條資料是無法並存的。
//session1(sid=158)中
SQL> insert into t values (1,'ddd');
已建立 1 行。
//session2(sid=141)中
SQL> insert into t values (1,'ddddfsf');
(session2被阻塞)
發生了阻塞!session2因為插入了id=1的資料,但是之前已經存在id=1的記錄,即使這條記錄還沒有被commit。
//檢視現象
SQL> select * from v$locked_object;
XIDUSN XIDSLOT XIDSQN OBJECT_ID SESSION_ID ORACLE_USERNAME OS_USER_NAME PROCESS LOCKED_MODE
---------- ---------- ---------- ---------- ---------- ------------------------------ ------------------------------ ------------ -----------
8 19 891 53606 141 SCOTT IBM-VS2A1BHCNS0\ibm 772:3932 3
6 17 840 53606 158 SCOTT IBM-VS2A1BHCNS0\ibm 636:1036 3
SQL> select * from v$lock where sid in (141,158);
ADDR KADDR SID TYPE ID1 ID2 LMODE REQUEST CTIME BLOCK
-------- -------- ---------- ---- -------------------
6C8344A8 6C8344BC 141 TX 393233 840 0 4 96 0
6BDC4074 6BDC408C 158 TM 53606 0 3 0 129 0
6BDC4138 6BDC4150 141 TM 53606 0 3 0 96 0
6BE185A8 6BE186C4 158 TX 393233 840 6 0 129 1
6BE29A54 6BE29B70 141 TX 524307 891 6 0 96 0
SQL> select sid, serial#, lockwait, sql_id, blocking_session_status,EVENT#, EVENT
2 from v$session where sid in (141,158);
SID SERIAL# LOCKWAIT SQL_ID BLOCKING_SESSION_STATUS EVENT# EVENT
---------- ---------- -------- ------------- ----------------------- ---------- ----------------------------------------------------------------
158 47 NO HOLDER 256 SQL*Net message from client
141 122 6C8344BC 515n1g3av68fc VALID 183 enq: TX - row lock contention
首先,我們分析一下v$locked_object檢視。兩個會話session分別在undo表空間分配了相應的空間,準備存放undo資料映象。並且給這兩個段加入了共享鎖(Lmode=3)。
v$lock檢視變得略有複雜。首先,我們觀察session1(sid=158)的情況。session1的情況和上面沒有多少區別。現在資料表T上加一個共享物件鎖(TM鎖,Lmode=3)。之後,在Undo區(393233/840)上分配空間,儲存資料映象,並且加入了一個排他鎖(TX Lmode=6)。當session1(sid=158)完成之後,session2(sid=141)嘗試將相同id的資料插入到資料表中。首先,先給物件T加入一個共享鎖物件(TM鎖,LMODE=3)。之後,session2嘗試給已經為session1排他(lmode=6)的undo空間(393233/840),加一個TX鎖,型別為lmode=4(共享鎖型別),要求共享undo空間(393233/840)。這樣,session1和session2在這個undo空間上存在了blocking,因為lmode4和6之間不能並存。於是,session2被blocking。
此外,session2為了進行insert操作,還分配了一個新的undo空間(53606 0),實行lmode=3的事務鎖。
從會話v$session等待情況看,會話2在等待事件“enq: TX - row lock contention”,等待session1釋放資料行鎖。
結論:當兩個會話在同時新增加一個記錄的時候,如果輸入的主鍵相同,一個會話會發生blocking。此時,Oracle是難以做決定,前一個會話如果被rollback,第二個事務不存在問題。如果前一個會話提交,第二個事務對應資料行就是非法的資料。在這種情況下,Oracle只能是blocking一個會話了。
3、同時修改相同一條記錄
當我們嘗試修改一條相同的記錄時,會發生什麼呢?
//session1(sid=158)
SQL> update t set name='dfs' where id=1;
已更新 1 行。
SQL>
//session2(sid=141)
SQL> update t set name='fs' where id=1;
(阻塞)
出現了阻塞blocking。我們觀察一下鎖的情況。
SQL> select * from v$locked_object;
XIDUSN XIDSLOT XIDSQN OBJECT_ID SESSION_ID PROCESS LOCKED_MODE
---------- ---------- ---------- ---------- ---------- ------------ -----------
0 0 0 53606 141 772:3932 3
6 16 840 53606 158 636:1036 3
SQL> select * from v$lock where sid in (141,158);
ADDR KADDR SID TYPE ID1 ID2 LMODE REQUEST CTIME BLOCK
-------- -------- ---------- ---- -------------------
6C8344A8 6C8344BC 141 TX 393232 840 0 6 42 0
6BDC4074 6BDC408C 158 TM 53606 0 3 0 87 0
6BDC4138 6BDC4150 141 TM 53606 0 3 0 42 0
6BE185A8 6BE186C4 158 TX 393232 840 6 0 87 1
SQL> select sid, serial#, lockwait, sql_id, blocking_session_status,EVENT#, EVENT
2 from v$session where sid in (141,158);
SID SERIAL# LOCKWAIT SQL_ID BLOCKING_SESSION_STATUS EVENT# EVENT
---------- ------ -------------------------------------
141 47 6C8344BC fgjfccu4as8xv VALID 83 enq: TX - row lock contention
158 122 NO HOLDER 256 SQL*Net message from client
從檢視情況下,雖然在修改相同資料行的時候,都是後一個session2被阻塞住。但是,在加鎖方式上存在一些差異。這點從v$lock檢視上可以分析出。
先看v$locked_object,session2(sid=141)的undo空間鎖是沒有建立的,前三個資料列為0。
v$lock檢視中,session2發起了兩個鎖,一個是對資料表的共享鎖TM。另一個鎖是對session1所開啟的undo段進行行排他(Lmode=6)要求。因為其上已經存在session1的排他,兩者不能並存。於是,session2被阻塞住。
結論:當兩個會話在同時修改一個資料時。對共享資源的佔用就是第一個會話undo段空間物件。後一個session會被blocking。
4、刪除相同的資料
最後我們看看刪除資料時候的情況。
//session1(sid=149)
SQL> conn scott/tiger@orcl;
已連線。
SQL> delete t where id=1;
已刪除 1 行。
SQL> select sid from v$mystat where rownum<2;
SID
----------
149
//session2(Sid=156)
SQL> conn scott/tiger@orcl
已連線。
SQL> select sid from v$mystat where rownum<2;
SID
----------
156
SQL> delete t where id=1;
刪除相同的資料時,被blocking。
SQL> select * from v$locked_object;
XIDUSN XIDSLOT XIDSQN OBJECT_ID SESSION_ID ORACLE_USERNAME OS_USER_NAME PROCESS LOCKED_MODE
---------- ---------- ---------- ---------- --------- -----------
8 22 896 53606 149 SCOTT IBM-VS2A1BHCNS0\ibm 3752:588 3
0 0 0 53606 156 SCOTT IBM-VS2A1BHCNS0\ibm 1428:3376 3
SQL> select * from v$lock where sid in (149,156);
ADDR KADDR SID TYPE ID1 ID2 LMODE REQUEST CTIME BLOCK
-------- -------- ---------- ---- ----------
6C8344A8 6C8344BC 156 TX 524310 896 0 6 130 0
6BDC4074 6BDC408C 149 TM 53606 0 3 0 309 0
6BDC4138 6BDC4150 156 TM 53606 0 3 0 130 0
6BE23C64 6BE23D80 149 TX 524310 896 6 0 309 1
SQL> select sid, serial#, lockwait, sql_id, blocking_session_status,EVENT#, EVENT
2 from v$session where sid in (149,156);
SID SERIAL# LOCKWAIT SQL_ID BLOCKING_SESSION_STATUS EVENT# EVENT
---------- ---------- -------- ------------- ----------------------- ---------- ----------------------------------------------------------------
149 381 NO HOLDER 256 SQL*Net message from client
156 493 6C8344BC g2pvqwhq0pwjc VALID 183 enq: TX - row lock contention
刪除的特徵和修改相同,都是兩個會話爭用這個資料行對應的鎖,之後發生鎖互斥現象,引發blocking。
結論:在刪除兩條相同資料行的情況下,是可能發生blocking的。
綜合上面的研究,我們可以發現。Oracle採用的多版本一致度和事務行鎖機制,最大限度的保證了並行特性發揮。但是,存在並行、存在資源獨佔使用,就存在鎖機制,有鎖機制就意味著總會有訪問被序列化。但是,不得不承認,Oracle在鎖機制上,已經做到了相當小的範圍。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/17203031/viewspace-687571/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- DML操作引起的blocking(一)BloC
- ORACLE 分割槽索引UNUSABLE導致的DML操作失敗引起的血案Oracle索引
- 閃回 錯誤的DML 操作
- Oracle並行操作——並行DML操作Oracle並行
- 並行dml操作所需的TM鎖並行
- MySQL的DDL和DML操作語法MySql
- DML操作 DDL觸發器觸發器
- dml操作重做日誌分析
- Oracle 檢視可以DML操作的條件Oracle
- 日誌挖掘-對於DML操作的挖掘
- DML, DDL操作的自動提交問題
- DML操作涉及到的系統表
- Oracle連線檢視DML操作的限制Oracle
- DDL、DML、DCL、DQL相關操作
- Sysbench-0.5改成只有DML操作
- 使用for迴圈操作DML語句
- Mysql 基礎操作 DDL DML DCLMySql
- 從底向上瞭解DML操作
- 如何查詢DML操作的詳細記錄
- 配置支援DML和DDL操作同步的GoldenGateGo
- Flashback Query 針對DML誤操作的恢復
- Blocking ElementsBloC
- SQLServer DML操作阻塞SELECT查詢SQLServer
- MySQL全面瓦解5:資料操作-DMLMySql
- 使用loop迴圈操作DML語句OOP
- 使用while迴圈操作DML語句While
- OGG雙向DML複製操作
- 哪種DML操作產生undo多
- oracle點陣圖索引對DML操作的影響Oracle索引
- 基於LOGMINER 的表DML誤操作恢復
- 表的建立修改及增刪改查-DML操作
- DDL,DML操作對結果快取的影響快取
- Oracle DBLINK 抽數以及DDL、DML操作Oracle
- 使用Logminer工具分析DML和DDL操作
- NBIO 第二彈 —— 支援 Non-Blocking HTTP 1.xBloCHTTP
- 使用Logminer來分析具體的DML操作日誌
- AIX中快速定位引起大量磁碟IO操作的程式AI
- DB2 DDL操作引起的GoldenGate錯誤DB2Go