最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL InnoDB鎖機制之從Record到Next-Key的使用解讀

 更新時間:2025年12月26日 09:42:13   作者:kkkkkkkkl24  
這篇文章詳細(xì)介紹了InnoDB的鎖機制,包括記錄鎖(RecordLock)、間隙鎖(GapLock)和Next-KeyLock,以及它們的觸發(fā)條件和作用,通過理解這些鎖的機制,讀者可以更好地解決MySQL中的性能問題、死鎖問題和幻讀問題

在真實業(yè)務(wù)中,你遇到的大多數(shù) MySQL 性能問題、死鎖問題,幾乎都與“鎖”有關(guān)。但很多工程師對鎖的理解停留在碎片層面:

知道“行鎖”“間隙鎖”“next-key-lock”,但不知道 SQL 是如何觸發(fā)這些鎖的、鎖到底鎖在哪里、為什么會鎖這么多。

這一篇文章,我會用工程化思維,帶你一次性理解 InnoDB 鎖機制的全景圖。

看完以后,你將具備:

  • ? 能看懂鎖的真實作用
  • ? 能從 SQL 推斷出鎖范圍
  • ? 能解釋死鎖發(fā)生原因
  • ? 能在面試中條理清晰地講出鎖機制

一、為什么 InnoDB 的鎖機制這么復(fù)雜?

MySQL 采用 MVCC + 鎖 實現(xiàn)事務(wù)隔離,其中最關(guān)鍵的隔離級別是:

  • RC:讀已提交
  • RR:可重復(fù)讀(默認(rèn))

RR 是企業(yè)最常見的隔離級別,它要解決“幻讀”問題。

于是有了三個鎖:

  • 記錄鎖(Record Lock)
  • 間隙鎖(Gap Lock)
  • Next-Key Lock(Record + Gap)

所有復(fù)雜問題都來自這個組合。

二、InnoDB 的三種核心鎖(理解它們的作用和觸發(fā)條件)

Record Lock:真實行上的鎖

  • 鎖的對象:一條真實存在的記錄
  • 觸發(fā)場景:精確命中唯一索引

例如:

SELECT * FROM user WHERE id = 10 FOR UPDATE;

只鎖 (10] —— 單條記錄。

特點:不會鎖間隙,因此不會阻止插入。

Gap Lock:只鎖“間隙”,不鎖數(shù)據(jù)

作用:阻止“間隙內(nèi)插入新數(shù)據(jù)”,防止幻讀。

例如:

索引中已有值:

10 --- 20 --- 30

SQL:

SELECT * FROM user WHERE age > 20 FOR UPDATE;

Gap Lock 會鎖?。?/p>

(20, 30)
(30, +∞)

重點:Gap Lock 不鎖記錄,只鎖區(qū)間。

Next-Key Lock:Record + Gap 的組合鎖

RR 下范圍查詢的默認(rèn)鎖模式:

(prev_key, record_key]

例如:(假設(shè)索引有 10、20、30)

SELECT * FROM t WHERE age BETWEEN 15 AND 25 FOR UPDATE;

鎖住的區(qū)間:

(10,20]
(20,30]

作用:

  • ? 鎖住命中的記錄
  • ? 鎖住記錄前的 gap → 阻止插入

這就是為什么 RR 隔離級別能規(guī)避幻讀。

三、鎖到底由哪些 SQL 觸發(fā)?

“ SQL → 鎖類型” 映射表:

SQL 場景索引情況鎖類型原因
WHERE id = ?(唯一鍵)精確命中Record Lock不需要鎖 gap
WHERE id = ?(普通索引)精確匹配,但非唯一Next-Key Lock防止幻讀
WHERE age > ? / < ?范圍掃描Next-Key Lock必須鎖 gap
BETWEEN 范圍查詢范圍掃描Next-Key Lock防止插入
無索引過濾全表掃描大量 Record Lock每條記錄都會被鎖
LIKE '%abc'無法走索引表鎖風(fēng)險全表掃描

一句話總結(jié):

  • 能精確鎖住記錄 → Record Lock
  • 需要范圍掃描 → Next-Key Lock
  • 范圍掃描一定會鎖 gap → Gap Lock

四、鎖具體加在什么區(qū)間?

假設(shè)索引中有如下值:

10 ---- 20 ---- 30 ---- 40

來看不同 SQL 加的鎖??

WHERE id = 20 FOR UPDATE

鎖:

(10, 20]

但如果字段是主鍵/唯一鍵,會優(yōu)化成:

[20]

WHERE id > 20 FOR UPDATE

鎖:

(20,30)
(30,40)
(40,+∞)

WHERE id BETWEEN 15 AND 35 FOR UPDATE

鎖:

(10,20]
(20,30]
(30,40]

無索引條件

SELECT * FROM user WHERE name='xxx' FOR UPDATE;

鎖住所有記錄:

[10], [20], [30], [40]

→ 大量鎖沖突發(fā)生的根源。

五、總結(jié)

  • InnoDB 的鎖永遠(yuǎn)基于索引。
  • 無法精確匹配記錄,就會使用 Next-Key Lock。
  • 范圍查詢一定會帶 gap 鎖。

掌握這三點后,死鎖、鎖等待、幻讀問題都能一眼看穿。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論

乐昌市| 广饶县| 高平市| 井研县| 瓮安县| 左贡县| 常宁市| 东兰县| 竹溪县| 睢宁县| 唐海县| 杂多县| 临沧市| 茂名市| 苗栗市| 壤塘县| 汉寿县| 喀喇沁旗| 天镇县| 普定县| 漳浦县| 崇信县| 衡山县| 巍山| 五家渠市| 姚安县| 金华市| 夹江县| 太保市| 鄂温| 汝州市| 定西市| 漳浦县| 恩施市| 沿河| 阳高县| 沂水县| 紫阳县| 清徐县| 大邑县| 汉寿县|