間隙鎖鎖的是索引葉子節點的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級別下的鎖 我先建立乙個表,並插入幾行資料,如下圖 插...