前言
本文介紹 MySQL InnoDB 的加鎖規則,以及一些需要注意的點,
總結
兩個原則,兩個優化,一個 bug:
原則1:加鎖的基本單位是 next-key 鎖,是一個前開后閉區間
原則2:查找程序中訪問到的記錄才會加鎖
優化1:索引的等值查詢,唯一索引加鎖時,next-key 會退化為行鎖
優化2:索引的等值查詢,向右遍歷時且最后一個值不符合時,最后一個 next-key 會退化為間隙鎖
一個bug:唯一索引上的范圍查詢會訪問到第一個不滿足條件的值為止,
注意,以上的加鎖規基于版本 MySQL 5.x <= 5.7.24,8.x <= 8.0.13
注意
1、lock in share mode 和 for update 的區別
使用 lock in share mode 上鎖讀時,可以進行索引覆寫,那么只會對覆寫索引樹上鎖,而不會對主鍵索引樹上鎖,使用 for update 上鎖讀時,系統認為接下來需要進行更新操作,所以會給符合條件的記錄加上行鎖,
這個指導我們,如果想用 lock in share mode 加讀鎖來避免記錄被更新,那么需要避免索引覆寫的情況,否則通過主鍵索引還是可以修改記錄,
2、使用 limit 可以減小加鎖范圍
當對 limit 數量的記錄執行完操作后,將不再掃描后續的記錄,也就不會再加鎖,
3、雖然分析加鎖區間用 next-key,但注意 next-key 是行鎖和間隙鎖的組合
看下圖的事務流程:

你或許會疑問,session B 不是沒有申請到 next-key 么,
是這樣的,申請 next-key 分為兩步,session B 首先申請 (5,10)的間隙鎖,申請成功;然后申請 c=10 的行鎖,阻塞,即申請 next-key 阻塞是阻塞在申請行鎖的時候,因為 session B 申請了(5,10)的間隙鎖,所以 session A 插入(8,8,8)阻塞,
參考
- [1] 為什么我只改一行的陳述句,鎖這么多
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/302155.html
標籤:MySQL
