自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

MySQL的行級(jí)鎖鎖的到底是什么?

數(shù)據(jù)庫
往期在文章《介紹Innodb的鎖機(jī)制》中提到過關(guān)于記錄鎖,但是沒有詳細(xì)展開描述,本片文章簡(jiǎn)單聊一聊。

往期在文章《介紹Innodb的鎖機(jī)制》中提到過關(guān)于記錄鎖,但是沒有詳細(xì)展開描述。本片文章簡(jiǎn)單聊一聊。

數(shù)據(jù)庫的行級(jí)鎖,隨著鎖的細(xì)粒度不同,擁有不同的命名。

  • 記錄鎖(Record Lock)指的是對(duì)索引記錄的鎖定。
  • 間隙鎖(Gap Lock)則是對(duì)索引記錄之間的間隙進(jìn)行鎖定。

而Next-Key Lock則是記錄鎖和間隙鎖的融合,同時(shí)鎖定索引記錄和間隙。其范圍為左開右閉。

什么是Record Lock

記錄鎖,即Record Lock,是針對(duì)索引記錄而言的鎖定。例如,執(zhí)行以下語句:SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE; 會(huì)對(duì)滿足條件c1=10的記錄進(jìn)行鎖定,以防止其他任何事務(wù)插入、更新或刪除具有相同c1值的行。

什么是Gap Lock

間隙鎖,即Gap Lock,指的是針對(duì)索引記錄之間的間隙,或者是在第一個(gè)索引記錄之前或最后一個(gè)索引記錄之后的空隙上的鎖定。

在這里,所謂的“間隙”是指InnoDB索引數(shù)據(jù)結(jié)構(gòu)中可供插入新值的位置。

當(dāng)你使用SELECT…FOR UPDATE語句鎖定一組行時(shí),InnoDB可以創(chuàng)建鎖,應(yīng)用于索引中的實(shí)際值以及它們之間的間隙。例如,如果你選擇更新所有大于10的值,間隙鎖將阻止另一個(gè)事務(wù)插入新的大于10的值。

(實(shí)際會(huì)鎖到+∞,這里為了演示什么是gap簡(jiǎn)化了一下)

由于鎖的存在可能影響數(shù)據(jù)庫的并發(fā)性,因此間隙鎖只在Repeatable Reads(可重復(fù)讀)這種隔離級(jí)別下才會(huì)發(fā)揮作用。

在Repeatable Reads隔離級(jí)別下,針對(duì)鎖定的讀操作(例如select ... for update、lock in share mode)、update操作和delete操作,會(huì)執(zhí)行以下加鎖操作:

  • 對(duì)于具有唯一搜索條件的唯一索引,InnoDB僅鎖定找到的索引記錄,而不鎖定間隙。
  • 對(duì)于其他搜索條件,InnoDB會(huì)鎖定掃描的索引范圍,并使用間隙鎖或next-key鎖來阻止其他事務(wù)插入范圍內(nèi)的間隙。

換句話說,在處理**SELECT FOR UPDATE、LOCK IN SHARE MODE、UPDATE和DELETE**等語句時(shí),除了對(duì)具有唯一搜索條件的唯一索引外,還會(huì)獲取間隙鎖或next-key鎖,即鎖定其掃描的范圍。

什么是Next-Key Lock

Next-Key鎖是指索引記錄上的記錄鎖和索引記錄之間間隙上的間隙鎖的結(jié)合。

假設(shè)一個(gè)索引包含值10、11、13和20。此索引可能的next-key鎖包括以下區(qū)間:

(-∞, 10]
(10, 11]
(11, 13]
(13, 20]
(20, ∞ ]

對(duì)于最后一個(gè)間隙,∞并不是一個(gè)真正的索引記錄,因此,實(shí)際上,這個(gè)next-key鎖只鎖定最大索引值之后的間隙。

因此,Next-Key鎖的范圍都是左開右閉的。

與Gap Lock一樣,Next-Key Lock只有在InnoDB的可重復(fù)讀(RR)隔離級(jí)別中才會(huì)生效。

談?wù)凪ySQL加鎖機(jī)制

根據(jù)丁奇大佬《MySQL實(shí)戰(zhàn)45講》中的總結(jié),加鎖規(guī)則可以歸納為兩個(gè)“原則”、兩個(gè)“優(yōu)化”和一個(gè)“bug”:

  • 原則 1:加鎖的基本單位是next-key lock,形成一個(gè)前開后閉的區(qū)間。
  • 原則 2:只有查找過程中訪問到的對(duì)象才會(huì)被加鎖。
  • 優(yōu)化 1:對(duì)于索引上的等值查詢,當(dāng)給唯一索引加鎖時(shí),next-key lock會(huì)退化為行鎖。
  • 優(yōu)化 2:對(duì)于索引上的等值查詢,在向右遍歷時(shí),且最后一個(gè)值不滿足等值條件時(shí),next-key lock會(huì)退化為間隙鎖。
  • 一個(gè)bug:唯一索引上的范圍查詢會(huì)一直訪問到不滿足條件的第一個(gè)值為止。

當(dāng)我們執(zhí)行update t set d=d+1 where id = 7的時(shí)候,由于表 t 中沒有 id=7 的記錄,所以:

  • 根據(jù)原則 1,加鎖單位是 next-key lock,session A 加鎖范圍就是 (5,10];
  • 根據(jù)優(yōu)化 2,這是一個(gè)等值查詢 (id=7),而 id=10 不滿足查詢條件,next-key lock 退化成間隙鎖,因此最終加鎖的范圍是 (5,10)。

當(dāng)我們執(zhí)行select * from t where id>=10 and id<11 for update的時(shí)候:

  • 根據(jù)原則 1,加鎖單位是 next-key lock,會(huì)給 (5,10]加上 next-key lock,范圍查找就往后繼續(xù)找,找到 id=15 這一行停下來
  • 根據(jù)優(yōu)化 1,主鍵 id 上的等值條件,退化成行鎖,只加了 id=10 這一行的行鎖。
  • 根據(jù)原則 2,訪問到的都要加鎖,因此需要加 next-key lock(10,15]。因此最終加的是行鎖 id=10 和 next-key lock(10,15]。

當(dāng)執(zhí)行 select * from t where id>10 and id<=15 for update 時(shí):

  • 根據(jù)原則 1,加鎖單位是 next-key lock,會(huì)給 (10,15] 加上 next-key lock,并且由于 id 是唯一鍵,所以應(yīng)該循環(huán)判斷到 id=15 這一行就停止。
  • 但是,InnoDB 實(shí)際上會(huì)往前掃描到第一個(gè)不滿足條件的行,即 id=20。由于這是一個(gè)范圍掃描,因此索引 id 上的 (15,20] 這個(gè) next-key lock 也會(huì)被鎖上。

假如,數(shù)據(jù)庫表中當(dāng)前有以下記錄:

當(dāng)執(zhí)行 select id from t where c=5 lock in share mode 時(shí):

  • 根據(jù)原則 1,加鎖單位是 next-key lock,因此會(huì)給 (0,5] 加上 next-key lock。需要注意的是,c 是普通索引,因此不能立即停止于 c=5 這一條記錄,需要向右遍歷,直到找到 c=10 才放棄。
  • 根據(jù)原則 2,訪問到的都要加鎖,因此要給 (5,10] 加上 next-key lock。
  • 根據(jù)優(yōu)化 2:等值判斷,向右遍歷,最后一個(gè)值不滿足 c=5 這個(gè)等值條件,因此退化成間隙鎖 (5,10)。
  • 根據(jù)原則 2,只有訪問到的對(duì)象才會(huì)加鎖。由于這個(gè)查詢使用了覆蓋索引,不需要訪問主鍵索引,所以在主鍵索引上沒有加任何鎖。

當(dāng)執(zhí)行 select * from t where c>=10 and c<11 for update 時(shí):

  • 根據(jù)原則 1,加鎖單位是 next-key lock,會(huì)給 (5,10] 加上 next-key lock,并繼續(xù)向后查找,直到找到 id=15 這一行停止。
  • 根據(jù)原則 2,訪問到的都要加鎖,因此需要加 next-key lock (10,15]。
  • 由于索引 c 是非唯一索引,沒有優(yōu)化規(guī)則,也就是說不會(huì)退化為行鎖,因此最終 session A 加的鎖是,索引 c 上的 (5,10] 和 (10,15] 這兩個(gè) next-key lock。

結(jié)語

以上,我們介紹了InnoDB中的鎖機(jī)制,一共有三種鎖,分別是Record Lock、Gap Lock和Next-Key Lock。

Record Lock表示記錄鎖,鎖的是索引記錄。Gap Lock是間隙鎖,說的是索引記錄之間的間隙。Next-Key Lock是Record Lock和Gap Lock的組合,同時(shí)鎖索引記錄和間隙。他的范圍是左開右閉的。

InnoDB的RR級(jí)別中,加鎖的基本單位是 next-key lock,只要掃描到的數(shù)據(jù)都會(huì)加鎖。唯一索引上的范圍查詢會(huì)訪問到不滿足條件的第一個(gè)值為止。

同時(shí),為了提升性能和并發(fā)度,也有兩個(gè)優(yōu)化點(diǎn):

  • 索引上的等值查詢,給唯一索引加鎖的時(shí)候,next-key lock 退化為行鎖。
  • 索引上的等值查詢,向右遍歷時(shí)且最后一個(gè)值不滿足等值條件的時(shí)候,next-key lock 退化為間隙鎖。

關(guān)于鎖的介紹,就是這么多了,但是其實(shí),RR的隔離級(jí)別引入的這些鎖,雖然一定程度上可解決很多如幻讀這樣的問題,但是也會(huì)帶來一些副作用,比如并發(fā)度降低、容易導(dǎo)致死鎖等。

責(zé)任編輯:趙寧寧 來源: 碼上遇見你
相關(guān)推薦

2024-11-29 07:38:12

MySQL數(shù)據(jù)庫

2010-05-24 12:50:59

MySQL表級(jí)鎖

2020-03-05 10:28:19

MySQLMRR磁盤讀

2020-02-06 10:02:45

MySQL數(shù)據(jù)庫全局鎖

2010-11-22 14:42:13

MySQL行級(jí)鎖

2022-10-24 00:33:59

MySQL全局鎖行級(jí)鎖

2010-10-15 14:10:56

Mysql行級(jí)鎖

2022-10-08 00:00:00

Spring數(shù)據(jù)庫項(xiàng)目

2021-05-06 16:15:12

Java代碼

2023-02-02 11:53:44

nolock關(guān)鍵詞SQLserver

2022-05-11 08:53:13

MySQL鎖機(jī)制

2009-06-09 22:11:44

JavaScriptObject

2023-10-11 08:29:54

volatileJava原子性

2010-04-19 09:52:24

Oracle行級(jí)鎖

2018-07-31 10:10:06

MySQLInnoDB死鎖

2020-10-14 06:22:14

UWB技術(shù)感知

2010-11-01 01:25:36

Windows NT

2020-09-22 08:22:28

快充

2020-09-27 06:53:57

MavenCDNwrapper

2011-04-27 09:30:48

企業(yè)架構(gòu)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)