MySQL鎖與間隙鎖

2021-10-05 23:18:52 字數 2691 閱讀 3588

首先mysql引入間隙鎖是為了解決幻讀的問題。間隙鎖之間並不產生衝突,但間隙鎖與插入資料之間會產生衝突。間隙鎖的引入,可能會導致同樣的語句鎖住更大的範圍,影響併發度。mysql加鎖的規則十分複雜並且隨著版本更新進行變動,整體的加鎖規則如下,包含了兩個「原則」、兩個「優化」和乙個「bug」(所有都是在可重複讀的隔離級別)

原則1:加鎖的基本單位是next-key lock,next-key lock是前開後閉區間。

原則2:查詢過程中訪問到的物件才會加鎖。

優化1:索引上的等值查詢,給唯一索引加鎖的時候,next-key lock退化為行鎖。

優化2:索引上的等值查詢,向右遍歷時且最後乙個值不滿足等值條件的時候,next-key lock退化為間隙鎖。

乙個bug:唯一索引上的範圍查詢會訪問到不滿足條件的第乙個值為止。

下面以這個表為例:

案例一:事務a事務b事務c

begin;update t set d = d+1 where id = 7

insert into t values(8,8,8);(blocked)

update t set d = d+1 where id = 10;

分析:首先事務a,進行update,where使用的是主鍵索引,加鎖應該加(5,10],然後發現是唯一索引,且是等值查詢,所以根據優化2向右遍歷,到第乙個不滿足的10,所以加鎖為(5,10);

事務b插入資料在間隙鎖之間,所以blocked;

事務c成功執行;

案例二:

事務a事務b事務c

begin;select id from t where c=5 lock in share mode;

update t set d = d+1 where id = 5;(blocked)

insert into t values(7,7,7);(blocked)

分析:首先事務a使用普通索引c,且為覆蓋索引,應該鎖(0,5],(5,10],根據優化2,變成(0,5],(5,10),但是由於是lock in share mode只鎖覆蓋索引,所以主鍵索引並沒有用到,所以也沒有加鎖。但是如果是執行for update時系統會認為你接下來要更新資料,因此會順便給主鍵索引上滿足條件的行加上行鎖。

事務b使用主鍵索引,所以正常更新

事務c插入資料時收到間隙鎖的限制,被鎖。

案例三

事務a事務b事務c

begin;select * from t where id>=10 and id<11 for update;

insert into t values(8,8,8);(ok)insert into t values(13,13,13);(blocked)

update t set d = d+1 where id = 15;(blocked)

分析:事務a採用主鍵索引,應該加上間隙鎖(5,10],(10,15],由於存在10這一行,根據優化1,等值查詢,所以變為10這一行行鎖+(10,15]。

事務b第一條語句成功,第二條語句被間隙鎖鎖住

事務c被間隙鎖鎖住。

案例四

事務a事務b事務c

begin;select * from t where c>=10 and c<11 for update;

insert into t values(8,8,8);(blocked)

update t set d = d+1 where c=15;(blocked)

分析:事務a在c上不是唯一索引,所以鎖住(5,10],(10,15]

事務b被鎖

事務c被鎖

注意:在刪除資料的時候盡量加limit。這樣不僅可以控制刪除資料的條數,讓操作更安全,還可以減小加鎖的範圍

mysql實戰45講

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級別下的鎖 我先建立乙個表,並插入幾行資料,如下圖 插...