mysql innodb sql語句加鎖分析及鎖兼容矩陣

閱讀本文可能需要先了解下innodb的基礎知識 mysql 存儲引擎 innodb(一) 簡單介紹

官方文檔中對於sql語句的加鎖描述

  • SLELCT … FROM
    前三種級別不加鎖,SERIALIZABLE級別下,會對SELECT 默認帶上LOCK IN SHARE MODE,S鎖

  • SELECT…FOR UPDATE / SELECT … LOCK IN SHARE MODE
    掃描到的行都會加上鎖(不符合where子句條件的記錄鎖會被釋放)

  • SELECT … LOCK IN SHARE MODE
    在搜索遇到的所有索引記錄上加 next-key lock(S)。對於使用唯一索引搜索唯一行的語句,只需在對應的索引上加鎖(行鎖S)

  • SELECT … FOR UPDATE
    在搜索遇到的所有索引記錄上加 next-key lock (X)。對於使用唯一索引搜索唯一行的語句,只需在對應的索引上加鎖(行鎖X)。

  • UPDATE … WHERE
    在搜索遇到的所有索引記錄上加 next-key lock (X)。對於使用唯一索引搜索唯一行的語句,只需在對應的索引上加鎖(行鎖X)。
    當UPDATE修改聚集索引記錄時,對受影響的輔助索引記錄進行隱式鎖定。在插入新的二級索引記錄之前執行 duplicate check掃描時,以及在插入新的二級索引記錄時,UPDATE操作還會在受影響的二級索引記錄上獲得共享鎖。

  • DELETE FROM … WHERE …
    在搜索遇到的所有索引記錄上加 next-key lock (X)。對於使用唯一索引搜索唯一行的語句,只需在對應的索引上加鎖(行鎖X)。

  • INSERT
    在插入的行上設置行鎖(X)。
    在插入之前,會先設置一個gap鎖,稱爲insert intention gap lock。(insert intention gap lock和insert intention gap lock是兼容的,例如現在有索引4,7;事務A,B分別要插入5,6;事務A,B在獲取X鎖之前,會獲取這個i gap,鎖定4和7的間隙,A,B彼此不會阻塞,因爲行沒有衝突。)
    如果insert 的事務出現了duplicate-key error ,事務會對duplicate index record加共享鎖。這個共享鎖在併發的情況下是會產生死鎖的。

session A session B session C
START TRANSACTION;
INSERT INTO t1 VALUES(1);
insert成功,並X鎖 START TRANSACTION;
· INSERT INTO t1 VALUES(1); START TRANSACTION;
` wait INSERT INTO t1 VALUES(1);
` wait
rollback, 釋放X鎖
` 獲取S鎖 獲取S鎖
` 獲取X鎖沒有成功,等待session C釋放S鎖 獲取X鎖沒有成功,等待session B釋放S鎖
`
  • INSERT … ON DUPLICATE KEY UPDATE
    和INSERT的區別是,在發生duplicate key error 時,加的是X鎖,而不是S鎖。
    主鍵衝突時,加的行鎖(X);唯一鍵衝突時,加的是next-key lock(X)。【前面描述出自官方文檔,但是有網上有博客說官方文檔有bug,主鍵衝突也加的是next-key lock】

  • REPLACE …

replace into 跟 insert 功能類似,不同點在於:replace into 首先嚐試插入數據到表中, 1. 如果發現表中已經有此行數據(根據主鍵或者唯一索引判斷)則先刪除此行數據,然後插入新的數據。 2. 否則,直接插入新數據。

如果插入沒有衝突,和insert一樣,否則,加next-key lock (X)

鎖的兼容矩陣

` Gap Insert Intention Record Next-Key
Gap 兼容 兼容 兼容 兼容
Insert Intention 衝突 兼容 兼容 衝突
Record 兼容 兼容 衝突 衝突
Next-Key 兼容 兼容 衝突 衝突

注:橫向是已經持有的鎖,縱向是正在請求的鎖

type IS IX S X
IS 兼容 兼容 兼容 不兼容
IX 兼容 兼容 不兼容 不兼容
S 兼容 不兼容 兼容 不兼容
X 不兼容 不兼容 不兼容 不兼容

參考:
[1] mysql官方文檔 https://dev.mysql.com/doc/refman/5.7/en/innodb-locks-set.html
[2] MySQL技術內幕:InnoDB存儲引擎
[3] http://m.elecfans.com/article/872770.html
[4] https://www.jianshu.com/p/7004f7571427

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章