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值。則可以成功插入。
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的InnoDB锁机制之Gap Lock、Next-Key Lock、Record Lock解析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: XtraBackup原理解读
- 下一篇: 系统级性能分析工具 — Perf