MySQL InnoDB鎖機制之Gap Lock、Next-Key Lock、Record Lock解析
MySQL InnoDB支持三種行鎖定方式:
l 行鎖(Record Lock):鎖直接加在索引記錄上面,鎖住的是key。
l 間隙鎖(Gap Lock):鎖定索引記錄間隙,確保索引記錄的間隙不變。間隙鎖是針對事務隔離級別為可重復讀或以上級別而已的。
l Next-Key Lock :行鎖和間隙鎖組合起來就叫Next-Key Lock。
默認情況下,InnoDB工作在可重復讀隔離級別下,並且會以Next-Key Lock的方式對數據行進行加鎖,這樣可以有效防止幻讀的發生。Next-Key Lock是行鎖和間隙鎖的組合,當InnoDB掃描索引記錄的時候,會首先對索引記錄加上行鎖(Record Lock),再對索引記錄兩邊的間隙加上間隙鎖(Gap Lock)。加上間隙鎖之後,其他事務就不能在這個間隙修改或者插入記錄。
Gap Lock在InnoDB的唯一作用就是防止其他事務的插入操作,以此防止幻讀的發生。
1、 行鎖(Record Lock)
行鎖鎖定的是索引記錄,而不是行數據,也就是說鎖定的是key。
2、 間隙鎖(Gap Lock)
例如:
create table test(id int,v1 int,v2 int,primary key(id),key `idx_v1`(`v1`))Engine=InnoDB DEFAULT CHARSET=UTF8;
該表的記錄如下:
+----+------+------+
| id | v1 | v2 |
+----+------+------+
| 1 | 1 | 0 |
| 2 | 3 | 1 |
| 3 | 4 | 2 |
| 5 | 5 | 3 |
| 7 | 7 | 4 |
| 10 | 9 | 5 |
間隙鎖(Gap Lock)一般是針對非唯一索引而言的,test表中的v1(非唯一索引)字段值可以劃分的區間為:
(-∞,1)
(1,3)
(3,4)
(4,5)
(5,7)
(7,9)
(9, +∞)
假如要更新v1=7的數據行,那麽此時會在索引idx_v1對應的值,也就是v1的值上加間隙鎖,鎖定的區間是(5,7)和(7,9)。同時找到v1=7的數據行的主鍵索引和非唯一索引,對key加上鎖。
3、 後碼鎖(Next-Key Lock)
記錄鎖和間隙鎖的結合,對於InnoDB中,更新非唯一索引對應的記錄(在這裏來說是更新v1字段的值),會加上Next-Key Lock。如果更新記錄為空,就不能加記錄鎖,只能加間隙鎖。
舉個例子(事務隔離級別為MySQL默認的可重復讀)
為什麽TRANSACTION 2的insert操作會被阻塞,產生等待呢?這是因為TRANSACTION 2插入的v1值為6在TRANSACTION 1的鎖定區間(5,9)內。而TRANSACTION 1插入的v1值不在TRANSACTION 2的鎖定區間(5,7)內,故可以成功插入。不僅僅insert操作, update操作也一樣會被鎖住,從而鎖等待超時。
4、 鎖選擇
1)、如果更新條件沒有走索引,例如執行”update from t1 set v2=0 where v2=5;” ,此時會進行全表掃描,掃表的時候,要阻止其他任何的更新操作,所以上升為表鎖。
2)、如果更新條件為索引字段,但是並非唯一索引(包括主鍵索引),例如執行“update from t1 set v2=0 where v1=9;” 那麽此時更新會使用Next-Key Lock。使用Next-Key Lock的原因:
a)、首先要保證在符合條件的記錄上加上排他鎖,會鎖定當前非唯一索引和對應的主鍵索引的值;
b)、還要保證鎖定的區間不能插入新的數據。
3)、如果更新條件為唯一索引,則使用Record Lock(記錄鎖)。
InnoDB根據唯一索引,找到相應記錄,將主鍵索引值和唯一索引值加上記錄鎖。但不使用Gap Lock(間隙鎖)。
5、 間隙鎖(Gap Lock)
加後碼鎖的時候,並沒有鎖住間隙兩端的記錄(這裏的兩端分別是5,9和5,7),那麽兩端的記錄是可以更新的,但是如果更新兩端的記錄會影響到間隙鎖,那麽操作會被掛起,等待間隙鎖釋放。
看以下演示:
為什麽在左側值為4,右側值為7的時候,有時候操作會被掛起,有時候操作不會掛起呢?解釋如下:
當插入左側值的時候,即插入v1=4的時候,要求插入的id值小於id=3的範圍。當v1=4的記錄有多條的時候,插入的id值要小於其中的最大id值。則可以成功插入;
當插入右側值的時候,即插入v1=7的時候,要求插入的id值要大於id=7的範圍。當v1=7的記錄有多條的時候,插入的id值要大於其中的最小id值。則可以成功插入。
MySQL InnoDB鎖機制之Gap Lock、Next-Key Lock、Record Lock解析