InnoDB鎖演示
阿新 • • 發佈:2017-09-14
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:
例子2:
例子3:
例子4:
例子5:
例子6:
例子7:
例子8:
例子9:
例子10:
例子11:
例子12:
例子13:
例子14:
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是共享鎖,排它鎖和共享鎖是互斥的。 |
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是排它鎖,排它鎖和共享鎖是互斥的。 |
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是一次性非鎖定讀。 |
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無索引,所以會升級為表級鎖。 |
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無索引,會造成表級鎖。 |
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沒有索引,所以不能判斷是不是同一個記錄,他只有將所有記錄都加上鎖。 |
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並不是同一條數據。 |
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上也加鎖。 |
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。 |
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,所以會被阻塞。 |
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都不在範圍內,所以不會被阻塞。 |
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。 |
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都不在同一個位置上面 |
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鎖演示