1. 程式人生 > >InnoDB鎖演示

InnoDB鎖演示

rec 記錄 阻塞 表級鎖 for middle 判斷 索引 ble

create table t1( c1 int(10) unsigned not null default ‘0‘, c2 int(10) unsigned not null default ‘0‘, c3 int(10) unsigned not null default ‘0‘, c4 int(10) unsigned not null default ‘0‘, primary key(c1), key c2(c2) ) engine=innodb | c1 | c2 | c3 | c4 | +-----+-----+-----+-----+ | 0 | 0 | 0 | 0 | | 1 | 1 | 1 | 0 | | 3 | 3 | 3 | 0 | | 4 | 2 | 2 | 0 | | 6 | 2 | 2 | 0 | | 8 | 6 | 6 | 0 | | 10 | 4 | 4 | 0 | 隔離級別為RR 例子1:
T1 T2
begin begin
select * from t1 where c1=3 for update
| c1 | c2 | c3 | c4 | +-----+-----+-----+-----+ | 3 | 3 | 3 | 0 |
select * from t1 where c1=3 lock in share mode
這種情況會被阻塞,因為T1是排它鎖,T2是共享鎖,排它鎖和共享鎖是互斥的。

例子2:
T1 T2
begin begin
select * from t1 where c1=3 lock in share mode
| c1 | c2 | c3 | c4 | +-----+-----+-----+-----+ | 3 | 3 | 3 | 0 |
select * from t1 where c1=3 for update
這種情況會被阻塞,因為T1是共享鎖,T2是排它鎖,排它鎖和共享鎖是互斥的。

例子3:
T1 T2
begin begin
select * from t1 where c1=3 for update
| c1 | c2 | c3 | c4 | +-----+-----+-----+-----+ | 3 | 3 | 3 | 0 |
select * from t1 where c1=3
這種情況不會被阻塞,因為T2是一次性非鎖定讀。

例子4:
T1 T2
begin begin
select * from t1 where c3=7 lock in share mode
select * from t1 where c3=10 for update
備註:c3無索引
這種情況會被阻塞,因為T2中,C3無索引,所以會升級為表級鎖。

例子5:
T1 T2
begin begin
select * from t1 where c3=7 lock in share mode
select * from t1 where c1=6 for update
備註:c1是主鍵
這種情況會被阻塞,因為T1中c3無索引,會造成表級鎖。

例子6:
T1 T2
begin begin
select * from t1 where c2=2 and c3=5 for update
select * from t1 where c2=2 and c3=7 for update
備註:c2列上有索引,c3列上無索引,c3=7不存在
這種情況會被阻塞,因為c2=2,此列上有索引,這個記錄上會加一個排它鎖。T1和T2中的C3沒有索引,所以不能判斷是不是同一個記錄,他只有將所有記錄都加上鎖。
例子7:
T1 T2
begin begin
select * from t1 where c2=2 and c3=5 for update
select * from t1 where c2=3 and c3=7 for update
備註:c2列上有索引,c3列上無索引,c3=7不存在
這種情況不會被阻塞,鎖是基於索引的,T1中c2=2和 T2中c2=3並不是同一條數據。
例子8:
T1 T2
begin begin
select * from t1 where c2=2 and c3=2 for update
select * from t1 where c1=4 and c3=10 for update
備註:c1是主鍵,c2是普通索引,c3列上無索引
這種情況會被阻塞,因為在c2=2上加鎖,最終會回溯到主鍵c1=4上也加鎖。
例子9:
T1 T2
begin begin
update t1 set c4=20 where c2>=4
select * from t1 where c2>=4 select * from t1 where c1=7 for update
備註:c1列是主鍵,c2列是普通索引,T1影響了兩行。
這種情況不會被阻塞,T1鎖定的範圍是c2>=4的所有記錄,且是next lock,以及c1=8 & c1=10的record lock,T2鎖定的範圍是c1=7的 record lock。
例子10:
T1 T2
begin begin
update t1 set c4=20 where c2>=4
select * from t1 where c2>=4 insert into t1 select 7,5,10,10
備註:c1列是主鍵,c2列是普通索引,T1影響了兩行。
這種情況會被阻塞,T1鎖定的範圍是c2>=4的所有記錄,且是next lock,以及c1=8 & c1=10的record lock,
在T2中 5>4,所以會被阻塞。
例子11:
T1 T2
begin begin
update t1 set c4=20 where c2>=4
select * from t1 where c2>=4 insert into t1 select 7,2,10,10
備註:c1列是主鍵,c2列是普通索引,T1影響了兩行。
這種情況不會被阻塞,T1鎖定的範圍是c2>=4的所有記錄,且是next lock,以及c1=8 & c1=10的record lock,
在T2中 2<4,不管T1還是T2都不在範圍內,所以不會被阻塞。
例子12:
T1 T2
begin begin
update t1 set c4=20 where c1>=6
insert into t1 select 9,9,9,9
備註:c1列是主鍵,c1=6已經存在
這種情況會被阻塞,因為T1鎖定的是所有c1>=6的範圍record lock。
例子13:
T1 T2
begin begin
insert into t1 select 9,9,9,9
insert into t1 select 7,7,7,7
備註:c1列是主鍵,c1=7和c1=9的記錄都不存在
這種情況不會被阻塞,因為C1和C2都不在同一個位置上面
例子14:
T1 T2
begin begin
insert into t1 select 9,9,9,9
insert into t1 select 9,9,9,9
備註:c1列是主鍵,c1=9的記錄不存在
這種情況會被阻塞,因為C1和C2都在同一個位置上面

InnoDB鎖演示