關於唯一性索引造成堵塞和非唯一性索引造成堵塞的區別
論壇的問題帖子:
http://www.itpub.net/thread-1523814-1-1.html
首先我們要理解TX鎖中是透過訪問塊頭的ITL然後來確定事物的,如果事物已經提交則完成,如果事物沒有提交則等待.
我們可以檢視ID1 ID2來確定事物的資訊。
truncate(id1/power(2,16))
bitand(id1,to_number('ffff','xxxx'))+0
id2
分別對應v$transaction中的 XIDUSN,XIDSLOT,XIDSQN,當遭到堵塞的TX時候這裡記錄的是等待的相關事務。
透過實驗發現:在日常的環境堵塞INSERT的情況不多,它不像DELETE UPTDAE,當修改同樣的行的時候就會由於TX(X)堵塞,除非加入了唯一性索引,這裡你使用的是主鍵,保證唯一性的實際是一個唯一
性索引。沿用你實驗如下:
CREATE TABLE supplier
( supplier_id number(10) not null,
supplier_name varchar2(50) not null,
contact_name varchar2(50),
CONSTRAINT supplier_pk PRIMARY KEY (supplier_id)
);
然後開啟一個會話
INSERT INTO supplier VALUES (5, 'Supplier 5', 'Contact 5');
然後再開啟一個會話
INSERT INTO supplier VALUES (5, 'Supplier 5', 'Contact 5');
當然在唯一性索引的作用下這個造成了堵塞
ADDR KADDR SID TYPE ID1 ID2 LMODE REQUEST CTIME BLOCK
-------- -------- ---------- ---- ---------- ---------- ---------- ---------- ---------- ----------
676E1298 676E12B0 130 TM 56010 0 3 0 1357 0
6773C9C4 6773CAE0 130 TX 196633 1456 6 0 1357 0
694531DC 694531F0 130 TX 65544 1088 0 4 1357 0
677309E8 67730B04 152 TX 65544 1088 6 0 1657 1
676E1344 676E135C 152 TM 56010 0 3 0 1657 0
可以發現152堵塞了130會話。這裡第三行需要以共享模式(4)訪問行資料,而第四行正在以獨佔模式(6)訪問這個資料行。為什麼要以共享模式訪問資料行?
我個人認為是因為為了保證唯一性索引的唯一性必須要訪問這行同時又不願意別人以獨佔模式來或者這行,因為獨佔模式常常意味著要修改資料,如果別的會話正在修改這行,而當前會話卻在以null模
式訪問的話,那還能保證唯一性索引的唯一性嗎?共享模式相容共享模式,但是肯定是不相容獨佔(6)的。同時我們這裡還看到第而行,實際上這裡修改資料的事物已經獲得了行獨佔的TX鎖(6),但
是隻是為了保證唯一性索引還在等待中。。這個時候事物檢視v$transaction已經開啟了2個事物,分別用於2個會話的插入操作,但是130 SESSION的 以共享模式獲得行資料的事物還在等待。
SQL> select ADDR,XIDUSN, XIDSLOT , XIDSQN from v$transaction;
ADDR XIDUSN XIDSLOT XIDSQN
-------- ---------- ---------- ----------
677309E8 1 8 1088
6773C9C4 3 25 1456
大家可以換算一下
196633 1456 就是6773C9C4 3 25 1456
65544 1088 就是677309E8 1 8 1088
下面可以看看DELETE和UPDATE本身由於不再唯一性約束情況下更改相同行的情況。
SQL> create table ooo
2 as
3 select * from dba_users;
DELETE:
會話1啟動delete ooo where USERNAME='DIP';
會話2啟動delete ooo where USERNAME='DIP';
會話2堵塞
ADDR KADDR SID TYPE ID1 ID2 LMODE REQUEST CTIME BLOCK
-------- -------- ---------- ---- ---------- ---------- ---------- ---------- ---------- ----------
676E1298 676E12B0 131 TM 56021 0 3 0 24 0
67726E00 67726F1C 131 TX 196655 1457 6 0 24 1
694531DC 694531F0 133 TX 196655 1457 0 6 15 0
676E1344 676E135C 133 TM 56021 0 3 0 15 0
可以看到這裡就少了一個TX鎖。133會話的TX鎖只是在等待131TX鎖的事物完成,因為要刪除相同的行。透過塊頭的ITL發現131事物還沒有提交。只有等待並且模式都是6.並且此時的事物只有一個,
不像上面的INSERT 事物有2個,因為上面堵塞實際上不是堵塞行的插入,實際上是堵塞唯一性約束的檢查,所以2個修改的事物都已經啟動。但是這裡就是堵塞事物了。所以事物只有一個。
update:
會話1啟動update ooo set PASSWORD='' where USERNAME='TEST';
會話1啟動update ooo set PASSWORD='' where USERNAME='TEST';
會話2堵塞
ADDR KADDR SID TYPE ID1 ID2 LMODE REQUEST CTIME BLOCK
-------- -------- ---------- ---- ---------- ---------- ---------- ---------- ---------- ----------
676E1298 676E12B0 131 TM 56021 0 3 0 12 0
67726E00 67726F1C 131 TX 589829 1515 6 0 12 1
694531DC 694531F0 133 TX 589829 1515 0 6 3 0
676E1344 676E135C 133 TM 56021 0 3 0 3 0
檢視事物:
SQL> select ADDR,XIDUSN, XIDSLOT , XIDSQN from v$transaction;
ADDR XIDUSN XIDSLOT XIDSQN
-------- ---------- ---------- ----------
67726E00 9 5 1515
和預想的一樣
最後測試一下如果UPDATE遇到唯一性索引堵塞的情況。
CREATE TABLE supplier
( supplier_id number(10) not null,
supplier_name varchar2(50) not null,
contact_name varchar2(50),
CONSTRAINT supplier_pk PRIMARY KEY (supplier_id)
);
INSERT INTO supplier VALUES (5, 'Supplier 5', 'Contact 5');
INSERT INTO supplier VALUES (6, 'Supplier 6', 'Contact 6');
commit;
會話1: update supplier set supplier_id='1' where contact_name='Contact 5';
會話2:update supplier set supplier_id='1' where contact_name='Contact 6';
會話2堵塞
ADDR KADDR SID TYPE ID1 ID2 LMODE REQUEST CTIME BLOCK
-------- -------- ---------- ---- ---------- ---------- ---------- ---------- ---------- ----------
676E1298 676E12B0 131 TM 56022 0 3 0 63 0
6774DCC8 6774DDE4 131 TX 589848 1514 6 0 63 1
6774E1E4 6774E300 133 TX 327707 1491 6 0 57 0
694531DC 694531F0 133 TX 589848 1514 0 4 57 0
676E1344 676E135C 133 TM 56022 0 3 0 57 0
事物2個:
SQL> select ADDR,XIDUSN, XIDSLOT , XIDSQN from v$transaction;
ADDR XIDUSN XIDSLOT XIDSQN
-------- ---------- ---------- ----------
6774DCC8 9 24 1514
6774E1E4 5 27 1491
這也證明了我們的猜測。只是要涉及到唯一性索引的堵塞實際上不是堵塞行的操作,實際上是堵塞唯一性約束的檢查,所以2個修改的事物都已經啟動。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7728585/viewspace-713029/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 唯一性約束和唯一性索引的區別索引
- 轉載-treedump索引讀取索引儲存的資料值--非唯一性索引索引
- mysql 大事物commit慢造成全庫堵塞問題MySqlMIT
- [轉]聚集索引和非聚集索引的區別索引
- 使用聚集索引和非聚集索引的區別索引
- mysql innodb新建索引堵塞update ,insert,deleteMySql索引delete
- 唯一性索引優化實踐索引優化
- SQL Server 聚集索引和非聚集索引的區別SQLServer索引
- 表上建立唯一性索引,SQL*Loader用或不用dirdect的區別索引SQL
- MySQL:FLTWL的堵塞和被堵塞總結MySql
- 索引唯一性掃描(INDEX UNIQUE SCAN)索引Index
- PostgreSQLCREATEINDEXCONCURRENTLY的原理以及哪些操作可能堵塞索引的建立SQLIndex索引
- 關於insert操作造成索引葉節點分裂的驗證索引
- 唯一性索引(Unique Index)與普通索引(Normal Index)差異(上)索引IndexORM
- 唯一性索引(Unique Index)與普通索引(Normal Index)差異(中)索引IndexORM
- 唯一性索引(Unique Index)與普通索引(Normal Index)差異(下)索引IndexORM
- 唯一索引和非唯一索引ROWID儲存的區別索引
- mysql關於聚集索引、非聚集索引的總結MySql索引
- MySQL:FTWRL一個奇怪的堵塞現象和堵塞總結MySql
- 查詢(看)表的主鍵、外來鍵、唯一性約束和索引索引
- 主鍵索引 (聚集索引) 和普通索引 (輔助索引) 的區別索引
- MySQL的btree索引和hash索引的區別MySql索引
- 聚簇索引和非聚簇索引到底有什麼區別?索引
- ORACLE: 查詢(看)表的主鍵、外來鍵、唯一性約束和索引Oracle索引
- 索引分裂造成的index contention等待事件的診斷索引Index事件
- 安全通道堵塞識別系統
- MySQL單列索引和組合索引的區別MySql索引
- MySQL Hash索引和B-Tree索引的區別MySql索引
- 如何解決區域網堵塞故障
- 出料口堵塞識別系統
- MySQL單列索引和組合索引的區別介紹MySql索引
- 索引全掃描和索引快速全掃描的區別索引
- 煤塊堵塞監測識別系統
- 資料檔案offline後unusable索引造成的問題索引
- MySQL中的聚簇索引和非聚簇索引MySql索引
- sqlserver索引重建和索引重組的區別和操作方法SQLServer索引
- 主鍵和唯一索引的區別索引
- 本地索引、全域性索引、字首索引、非字首索引索引