MySQL的加鎖規則

2022-02-26 16:32:31 字數 2365 閱讀 4576

首先是課程中的總結的加鎖規則,兩個「原則」、兩個「優化」和乙個「bug」(可重複讀的事務隔離級別下)。

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

原則 2

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

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

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

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

然後是這次用到的表和資料

create

table

`t` (

`id`

int(11) not

null

, `c`

int(11) default

null

, `d`

int(11) default

null,

primary

key(`id`),

key`c` (`c`)

) engine

=innodb;

insert

into t values(0,0,0),(5,5,5),(

10,10,10),(15,15,15),(20,20,20),(25,25,25);

再然後就是實際例子了

根據原則1加的next-key lock鎖是id(5,10],因為id等於7的資料並不存在,所以不滿足優化1,根據優化2將會退化為間隙鎖id(5,10),從上面的實際例子中也能看出來,只有插入id=6的資料在等待鎖,id=4、11、10、5的資料在插入和更新的時候都正常。

這個和上乙個例子類似區別是滿足優化1所以就從next-key lock鎖id(5,10],退化為id=5的行鎖,所以id=6,4的資料可以插入進去,只有id=5的資料在更新的時候等待鎖。

這種情況就是

所以id=4、11的資料可以插入,而id=6、10的資料的更新和插入的時候需要等待鎖

分析:但是實際情況上id=11的資料插入也需要等待鎖,這就是上面規則說的bug唯一索引上的範圍查詢會訪問到不滿足條件的第乙個值為止,這裡的id<=10,會一直掃瞄到id=15,所以會加上(10,15]的next-key lock鎖

這其實是兩個例子,因為只有乙個區別就放一起了,先按照規則來分析

這兩個加鎖的區別就是對於id=5的鎖的問題,lock in share mode沒有對id=5加鎖,所以可以得到的資訊是,lock in share mode只鎖覆蓋索引,但是如果是 for update 就不一樣了。 執行 for update 時,系統會認為你接下來要更新資料,因此會順便給主鍵索引上滿足條件的行加上行鎖。

這個和例3類似,區別是這裡不是主鍵,也就是說不是唯一索引,所以這裡的分析過程就是

這個例子和例5類似,區別就是limit的問題,因為規則中總結的bug可以解釋,limit 1只需要掃瞄一行,所以c(5,10)的間隙鎖就沒加上,而limit 2就再次證明了,如果需要返回兩條資料需要再掃瞄就加上了c(5,10)的間隙鎖

先來分析沒有order by的情況:

然後是有order by desc的情況:

這上面總結的規則,其實沒啥道理可言,mysql**就是這樣寫的,加鎖的意義是實際上為了保持資料的一致性和語義的正確,從例子4我們就能看到明明我們想鎖的是5-10,但是因為bug(10,15]也加上了鎖。所以考慮mysql的這個加鎖問題的時候,最好還是根據掃瞄的情況來考慮

然後是一些細節的記錄:

MySQL加鎖規則

鎖是加在索引上的 加鎖規則裡面,包含了兩個 原則 兩個 優化 和乙個 bug 原則 1 加鎖的基本單位是 next key lock。next key lock 是前開後閉區間。原則 2 查詢過程中訪問到的物件才會加鎖。優化 1 索引上的等值查詢,給唯一索引加鎖的時候,next key lock 退...

mysql自定義加鎖 為MySQL加鎖?

在日常操作中,update insert delete innodb會自動給涉及的資料集加排他鎖,一般的 select 一般是不加任何鎖的。我們可以使用以下方式顯示的為 select 加鎖。共享鎖 select from table name where id 10 lock in share mo...

MySQL加鎖分析

參考 mysql 加鎖處理分析。該文已經講的很詳盡了,也易懂,下面僅僅是個人做的總結。逐條處理,逐條加鎖。gap鎖是間隙鎖,即相鄰兩條有效記錄間隙的鎖 鎖的是間隙 它是針對insert的,用來解決幻讀的發生。它會阻塞insert,但不會阻塞delete update等 記錄本來也不存在 rc與rr的...