什麼是間隙鎖

2021-10-19 01:17:40 字數 2136 閱讀 6578

間隙鎖鎖的是索引葉子節點的next指標。

解決了mysql rr級別下是幻讀的問題。

在rr隔離級別下:快照讀有可能讀到資料的歷史版本,也有可能讀到資料的當前版本。所以快照讀無需用鎖也不會發生幻讀的情況。

當前讀:select…lock in share mode,select…for update

當前讀:update,delete,insert

讀取的是記錄的最新版本,所以所以就需要通過加鎖(行鎖 間隙鎖 表鎖)的方式,使得被當前讀讀過的資料不能被新增修改或者刪除,換句話說再來一次當前讀要返回相同的資料。

這條sql語句之後看看我們 需要做什麼才能保證不發生幻讀。

1不能插入b為6的資料

2不能刪除b為6的資料

3不能修改b為6的資料

4不能把別的資料修改為b為6

突然一看挺複雜的,這個鎖要怎麼加呢,mysql大牛靈機一動,給葉子節點5的next指標加鎖,給葉子節點3加行鎖,給葉子節點3的next指標加鎖。如下圖所示

這樣不就能把上述四個問題解決了麼,兩個next指標鎖解決了插入b為6或者把別的資料修改為b為6,行鎖解決了修改b為6的行,但是呢也帶來一些明顯的***。

例如insert into `study`.`z` (`id`, `b`, `c`) values ('6', '4', '0'); 

會bolck因為按照索引結構這條資料會插入到葉子結點5和3之間,會修改葉子節點5的next指標,雖然這條sql沒有破壞上述的4個紅色條件但是依然被阻塞了所以我叫它為***。

insert into `study`.`z` (`id`, `b`, `c`) values ('4', '4', '0'); 

插入成功因為這條資料會插入在1的後面5的前面。

現在大家是不是能理解間隙鎖的怪異行為了呢。

begin; 

select * from z where id=4 for update;

會鎖住主鍵索引葉子節點的3的next指標。(為啥呢,需要你自己畫主鍵索引的圖)

begin; 

select * from z where id=3 for update;

間隙鎖會退化為行鎖只鎖葉子節點3 ,為什麼因為沒必要。不加間隙鎖也不會打破上述的紅色4個條件。

begin; 

select * from z where id>4 for update;

葉子節點3及之後所有節點會加行鎖並且他們的next指標會加鎖,

begin; 

select * from z where c=2 for update;

會發生鎖表,因為c沒有索引結構能儲存行鎖或者間隙鎖。

mysql間隙鎖 mysql間隙鎖

前面一文 mysql鎖 介紹了mysql innodb儲存引擎的各種鎖,本文介紹一下innodb儲存引擎的間隙鎖,就以下問題展開討論 1.什麼是間隙鎖?間隙鎖是怎樣產生的?2.間隙鎖有什麼作用?3.使用間隙鎖有什麼隱患?一 間隙鎖的基本概念 1.什麼叫間隙鎖 當我們用範圍條件而不是相等條件檢索資料,...

mysql 間隙鎖 mysql間隙鎖 轉

前面一文 mysql鎖 介紹了mysql innodb儲存引擎的各種鎖,本文介紹一下innodb儲存引擎的間隙鎖,就以下問題展開討論 1.什麼是間隙鎖?間隙鎖是怎樣產生的?2.間隙鎖有什麼作用?3.使用間隙鎖有什麼隱患?一 間隙鎖的基本概念 1.什麼叫間隙鎖 當我們用範圍條件而不是相等條件檢索資料,...

mysql間隙鎖 mysql的間隙鎖

最近學習了mysql的各種鎖,有點暈,打算通過文章的方式捋一捋。在學習了mvcc後,我就想,他已經很好的解決了併發讀寫了,但我也知道innodb提供了多種型別的鎖,所以很好奇這些鎖有什麼用,為什麼這些鎖的功能是mvcc做不到的?本文討論的都是rr級別下的鎖 我先建立乙個表,並插入幾行資料,如下圖 插...