MYSQL(04)-間隙鎖詳解

間隙鎖(Gap Lock)是Innodb在\color{red}{可重復(fù)讀}提交下為了解決幻讀問題時(shí)引入的鎖機(jī)制,(下面的所有案例沒有特意強(qiáng)調(diào)都使用可重復(fù)讀隔離級(jí)別)幻讀的問題存在是因?yàn)樾略龌蛘吒虏僮餮坠Γ@時(shí)如果進(jìn)行范圍查詢的時(shí)候(加鎖查詢)衔瓮,會(huì)出現(xiàn)不一致的問題,這時(shí)使用不同的行鎖已經(jīng)沒有辦法滿足要求移袍,需要對(duì)一定范圍內(nèi)的數(shù)據(jù)進(jìn)行加鎖爷绘,間隙鎖就是解決這類問題的书劝。在可重復(fù)讀隔離級(jí)別下,數(shù)據(jù)庫是通過行鎖和間隙鎖共同組成的(next-key lock)土至,來實(shí)現(xiàn)的

加鎖規(guī)則有以下特性购对,我們會(huì)在后面的案例中逐一解釋:

  • 1.加鎖的基本單位是(next-key lock),他是前開后閉原則
  • 2.插敘過程中訪問的對(duì)象會(huì)增加鎖
  • 3.索引上的等值查詢--給唯一索引加鎖的時(shí)候,next-key lock升級(jí)為行鎖
  • 4.索引上的等值查詢--向右遍歷時(shí)最后一個(gè)值不滿足查詢需求時(shí)陶因,next-key lock 退化為間隙鎖
  • 5.唯一索引上的范圍查詢會(huì)訪問到不滿足條件的第一個(gè)值為止

案例數(shù)據(jù)

id(主鍵) c(普通索引) d(無索引)
5 5 5
10 10 10
15 15 15
20 20 20
25 25 25

以上數(shù)據(jù)為了解決幻讀問題骡苞,更新的時(shí)候不只是對(duì)上述的五條數(shù)據(jù)增加行鎖,還對(duì)于中間的取值范圍增加了6間隙鎖楷扬,(-∞解幽,5](5,10](10烘苹,15](15躲株,20](20,25](25镣衡,+supernum] (其中supernum是數(shù)據(jù)庫維護(hù)的最大的值霜定。為了保證間隙鎖都是左開右閉原則。)

案例一:間隙鎖簡(jiǎn)單案例

步驟 事務(wù)A 事務(wù)B
1 begin;
select * from t where id = 11 for update;
-
2 - insert into user value(12,12,12)
\color{red}{blocked}
3 commit; -

當(dāng)有如下事務(wù)A和事務(wù)B時(shí)廊鸥,事務(wù)A會(huì)對(duì)數(shù)據(jù)庫表增加(10望浩,15]這個(gè)區(qū)間鎖,這時(shí)insert id = 12 的數(shù)據(jù)的時(shí)候就會(huì)因?yàn)閰^(qū)間鎖(10惰说,15]而被鎖住無法執(zhí)行磨德。

案例二: 間隙鎖死鎖問題

步驟 事務(wù)A 事務(wù)B
1 begin;
select * from t where id = 9 for update;
-
2 - begin;
select * from t where id = 6 for update;
3 - insert into user value(7,7,7)
\color{red}{blocked}
4 insert into user value(7,7,7)
\color{red}{blocked}
-

不同于寫鎖相互之間是互斥的原則,間隙鎖之間不是互斥的助被,如果一個(gè)事務(wù)A獲取到了(5,10]之間的間隙鎖剖张,另一個(gè)事務(wù)B也可以獲取到(5,10]之間的間隙鎖切诀。這時(shí)就可能會(huì)發(fā)生死鎖問題揩环,如下案例。
事務(wù)A獲取到(5,10]之間的間隙鎖不允許其他的DDL操作幅虑,在事務(wù)提交丰滑,間隙鎖釋放之前,事務(wù)B也獲取到了間隙鎖(5,10],這時(shí)兩個(gè)事務(wù)就處于死鎖狀態(tài)

案例三: 等值查詢—唯一索引

步驟 事務(wù)A 事務(wù)B 事務(wù)C
1 begin;
update u set d= d+ 1 where id = 7;
- -
2 - insert into u (8,8,8);
\color{red}{blocked}
-
4 - - update set d = d+ 1 where id = 10

1.加鎖的范圍是(5,10]的范圍鎖
2.由于數(shù)據(jù)是等值查詢褒墨,并且表中最后數(shù)據(jù)id = 10 不滿足id= 7的查詢要求炫刷,故id=10 的行級(jí)鎖退化為間隙鎖,(5,10)
3.所以事務(wù)B中id=8會(huì)被鎖住郁妈,而id=10的時(shí)候不會(huì)被鎖住

案例四: 等值查詢—普通索引

步驟 事務(wù)A 事務(wù)B 事務(wù)C
1 begin;
select id form t where c = 5 lock in share mode;
- -
2 - update t set d = d + 1 where id = 5 -
4 - - insert into values (7,7,7)\color{red}{blocked}

1.加鎖的范圍是(0,5]浑玛,(5,10]的范圍鎖
2.由于c是普通索引,根據(jù)原則4噩咪,搜索到5后繼續(xù)向后遍歷直到搜索到10才放棄顾彰,故加鎖范圍為(5,10]
3.由于查詢是等值查詢,并且最后一個(gè)值不滿足查詢要求胃碾,故間隙鎖退化為(5,10)
4.因?yàn)榧渔i是對(duì)普通索引c加鎖涨享,而且因?yàn)樗饕采w,沒有對(duì)主鍵進(jìn)行加鎖仆百,所以事務(wù)B執(zhí)行正常
5.因?yàn)榧渔i范圍(5,10)故事務(wù)C執(zhí)行阻塞
6.需要注意的是厕隧,lock in share mode 因?yàn)楦采w索引故沒有鎖主鍵索引,如果使用for update 程序會(huì)覺得之后會(huì)執(zhí)行更新操作故會(huì)將主鍵索引一同鎖住

案例五: 范圍查詢—唯一索引

步驟 事務(wù)A 事務(wù)B 事務(wù)C
1 begin;
select * form t where id >= 10 and id <11 for update
- -
2 - insert into values(8,8,8)
insert into values(13,13,13) \color{red}{blocked}
-
4 - - update t set d = d+ 1 where id = 15 \color{red}{blocked}
  1. next-key lock 增加范圍鎖(5,10]
  2. 根據(jù)原則5俄周,唯一索引的范圍查詢會(huì)到第一個(gè)不符合的值位置吁讨,故增加(10,15]
    3.因?yàn)榈戎挡樵冇衖d =10 根據(jù)原則3間隙鎖升級(jí)為行鎖峦朗,故剩余鎖[10,15]
    4.因?yàn)椴樵儾⒉皇堑戎挡樵兊簿簦蔥10,15]不會(huì)退化成[10,15)
    5.故事務(wù)B(13,13,13)阻塞,事務(wù)C阻塞

案例六: 范圍查詢—普通索引

步驟 事務(wù)A 事務(wù)B 事務(wù)C
1 begin;
select * form t where c >= 10 and c <11 for update
- -
2 - insert into values(8,8,8)
\color{red}{blocked}
-
4 - - update t set d = d+ 1 where c = 15 \color{red}{blocked}
  1. next-key lock 增加范圍鎖(5,10]甚垦,(10茶鹃,15]
    2.因?yàn)閏是非唯一索引,故(5,10]不會(huì)退化為10
    3.因?yàn)椴樵儾⒉皇堑戎挡樵兗枇粒蔥10,15]不會(huì)退化成[10,15)
    4.所以事務(wù)B和事務(wù)C全部堵塞

案例八: 普通索引-等值問題

上面的數(shù)據(jù)增加一行(30,10,30)闭翩,這樣在數(shù)據(jù)庫中存在的c=10的就有兩條記錄

步驟 事務(wù)A 事務(wù)B 事務(wù)C
1 begin;
delete from t where c = 10
- -
2 - insert into values(12,12,12)
\color{red}{blocked}
-
4 - - update t set d = d+ 1 where c = 15 \color{red}{ok}
  1. next-key lock 增加范圍鎖(5,10],(10迄埃,15]
    2.因?yàn)槭堑戎挡樵児释嘶癁椋?,10]疗韵,(10,15)侄非,故事務(wù)B阻塞蕉汪,事務(wù)C執(zhí)行成功
    加鎖的范圍如下圖

案例九: 普通索引-等值Limit問題

步驟 事務(wù)A 事務(wù)B 事務(wù)C
1 begin;
delete from t where c = 10 limit 2
- -
2 - insert into values(12,12,12)
\color{red}{OK}
-
4 - - update t set d = d+ 1 where c = 15 \color{red}{ok}

1.根據(jù)上面案例8改造,將delete增加limit操作2的操作
2.因?yàn)橹懒藬?shù)據(jù)加鎖值加2條逞怨,故在加鎖(5者疤,10]之后發(fā)現(xiàn)已經(jīng)有兩條數(shù)據(jù),故后面不在向后匹配加鎖叠赦。所以事務(wù)B執(zhí)行成功驹马,加鎖范圍如下

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子糯累,更是在濱河造成了極大的恐慌算利,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件泳姐,死亡現(xiàn)場(chǎng)離奇詭異效拭,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)胖秒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門允耿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人扒怖,你說我怎么就攤上這事较锡。” “怎么了盗痒?”我有些...
    開封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵蚂蕴,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我俯邓,道長(zhǎng)骡楼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任稽鞭,我火速辦了婚禮鸟整,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘朦蕴。我一直安慰自己篮条,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開白布吩抓。 她就那樣靜靜地躺著涉茧,像睡著了一般。 火紅的嫁衣襯著肌膚如雪疹娶。 梳的紋絲不亂的頭發(fā)上伴栓,一...
    開封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音雨饺,去河邊找鬼钳垮。 笑死,一個(gè)胖子當(dāng)著我的面吹牛额港,可吹牛的內(nèi)容都是我干的饺窿。 我是一名探鬼主播,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼锹安,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼短荐!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起叹哭,我...
    開封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤忍宋,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后风罩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體糠排,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年超升,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了入宦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡室琢,死狀恐怖乾闰,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情盈滴,我是刑警寧澤涯肩,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站巢钓,受9級(jí)特大地震影響病苗,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜症汹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一硫朦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧背镇,春花似錦咬展、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至济瓢,卻和暖如春荠割,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背旺矾。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工蔑鹦, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人箕宙。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓嚎朽,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親柬帕。 傳聞我的和親對(duì)象是個(gè)殘疾皇子哟忍,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 1. mysql鎖知多少 我們進(jìn)行insert狡门,update,delete锅很,select會(huì)加鎖嗎其馏,如果加鎖,加鎖步...
    liwsh閱讀 4,989評(píng)論 0 4
  • MySQL 加鎖處理分析 轉(zhuǎn)載2013年12月13日 16:43:55 7598 原文地址:http://hede...
    初來的雨天閱讀 448評(píng)論 0 2
  • 表和數(shù)據(jù) 規(guī)則總結(jié)(這個(gè)規(guī)則只限于截止到現(xiàn)在的最新版本爆安,即 5.x 系列 <=5.7.24叛复,8.0 系列 <=8....
    劍客kb閱讀 3,135評(píng)論 0 1
  • 月下三問 文∕晴于秋 燈 把滿街的影子撿起來 是否就能度過漫長(zhǎng)冬季? 把寂寞的憂傷的疼痛的 醉酒的...
    晴于秋閱讀 169評(píng)論 0 1