next-key鎖


next-key鎖

  1. 對記錄加鎖時,加鎖的基本單位是 next-key lock,它是由記錄鎖和間隙鎖組合而成的,next-key lock 是前開后閉區間,而間隙鎖是前開后開區間。但是,next-key lock 在一些場景下會退化成記錄鎖或間隙鎖。

實驗用的表:

其中,id 是主鍵索引(唯一索引),b 是普通索引(非唯一索引),a 是普通的列。

唯一索引等值查詢

當我們用唯一索引進行等值查詢的時候,查詢的記錄存不存在,加鎖的規則也會不同:

  • 當查詢的記錄是存在的,在用「唯一索引進行等值查詢」時,next-key lock 會退化成「記錄鎖」
  • 當查詢的記錄是不存在的,在用「唯一索引進行等值查詢」時,next-key lock 會退化成「間隙鎖」
  1. 先看看記錄是存在的。

    會話1加鎖變化過程如下:

    • 加鎖的基本單位是 next-key lock,因此會話1的加鎖范圍是(8, 16];
    • 但是由於是用唯一索引進行等值查詢,且查詢的記錄存在,所以 next-key lock 退化成記錄鎖,因此最終加鎖的范圍是 id = 16 這一行
  2. 接下來,看看記錄不存在的情況

會話1加鎖變化過程如下:

  • 加鎖的基本單位是 next-key lock,因此主鍵索引 id 的加鎖范圍是(8, 16];
  • 但是由於查詢記錄不存在,next-key lock 退化成間隙鎖,因此最終加鎖的范圍是 (8,16)。

唯一索引范圍查詢

范圍查詢和等值查詢的加鎖規則是不同的。

會話 1 加鎖變化過程如下:

  • 最開始要找的第一行是 id = 8,因此 next-key lock(4,8],但是由於 id 是唯一索引,且該記錄是存在的,因此會退化成記錄鎖,也就是只會對 id = 8 這一行加鎖;
  • 由於是范圍查找,就會繼續往后找存在的記錄,也就是會找到 id = 16 這一行停下來,然后加 next-key lock (8, 16],但由於 id = 16 不滿足 id < 9,所以會退化成間隙鎖,加鎖范圍變為 (8, 16)。

所以,會話 1 這時候主鍵索引的鎖是記錄鎖 id=8 和間隙鎖(8, 16)。

非唯一索引等值查詢

當我們用非唯一索引進行等值查詢的時候,查詢的記錄存不存在,加鎖的規則也會不同:

  • 當查詢的記錄存在時,除了會加 next-key lock 外,還額外加間隙鎖,也就是會加兩把鎖
  • 當查詢的記錄不存在時,只會加 next-key lock,然后會退化為間隙鎖,也就是只會加一把鎖。
  1. 我們先來看看查詢的值存在的情況。

    會話 1 加鎖變化過程如下:

    • 先會對普通索引 b 加上 next-key lock,范圍是(4,8];
    • 然后因為是非唯一索引,且查詢的記錄是存在的,所以還會加上間隙鎖,規則是向下遍歷到第一個不符合條件的值才能停止,因此間隙鎖的范圍是(8,16)。

    所以,會話1的普通索引 b 上共有兩個鎖,分別是 next-key lock (4,8] 和間隙鎖 (8,16) 。

  2. 接下來,我們看看查詢的值不存在的情況

會話 1 加鎖變化過程如下:

  • 先會對普通索引 b 加上 next-key lock,范圍是(8,16];
  • 但是由於查詢的記錄是不存在的,所以不會再額外加個間隙鎖,但是 next-key lock 會退化為間隙鎖,最終加鎖范圍是 (8,16)。

非唯一索引范圍查詢

非唯一索引和主鍵索引的范圍查詢的加鎖也有所不同,不同之處在於普通索引范圍查詢,next-key lock 不會退化為間隙鎖和記錄鎖

會話 1 加鎖變化過程如下:

  • 最開始要找的第一行是 b = 8,因此 next-key lock(4,8],但是由於 b 不是唯一索引,並不會退化成記錄鎖。
  • 但是由於是范圍查找,就會繼續往后找存在的記錄,也就是會找到 b = 16 這一行停下來,然后加 next-key lock (8, 16],因為是普通索引查詢,所以並不會退化成間隙鎖。

所以,會話 1 的普通索引 b 有兩個 next-key lock,分別是 (4,8] 和(8, 16]。

以上內容參考自小林coding公眾號


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM