Mysql鎖機制原理innodb

前言:

唏噓唏噓,提前批投了一手字節,簡歷就被篩選掉了,無時無刻不在提醒我是個小菜雞=。=,老老實實更新了。

鎖的粒度

  • 行鎖
    只針對操作的當前行進行加鎖。併發情況下,產生鎖等待的概率較低,支持較大的併發數,但開銷大,加鎖慢,而且會出現死鎖。
    (在InnoDB中使用行鎖有一個前提條件:檢索數據時需要通過索引!因爲InnoDB是通過給索引的索引項加鎖來實現行鎖的。)
  • 表鎖:
    表鎖的鎖定顆粒度在MySQL中是最粗的,InnoDB、MyISAM引擎中都有應用,對當前整張表加鎖。不適合高併發的場景,但開銷小,加鎖快,不會出現死鎖,發生鎖衝突的概率最大。

鎖的類型

行級鎖
  • 共享鎖:允許事務讀取一行數據
  • 排他鎖:允許事務刪除或者更新一行數據
表級別的鎖
  • 意向排他鎖:事務想要獲得一張表中某幾行的共享鎖
  • 意向共享鎖:事務想要獲取一張表中某幾行的排他鎖
  • 共享鎖:允許事務讀取整張表數據
  • 排他鎖:允許事務刪除或者更新整張表數據

表級別的鎖兼容性

這裏只是列出了表級別鎖的兼容性噢。

IS IX S X
IS T T T F
IX T T F F
S T F T F
X F F F F

結合意向鎖來分析,意向鎖的作用:
innoDB支持多力度鎖定,允許事務在行級上的鎖和表級上的鎖同時存在。
用於查詢某個表中是否存在某行被鎖的問題,
1)某個事務對某條記錄上了個排他鎖X之前需要先獲取這個表的意向排他鎖IX,最後再對記錄上排他鎖X。
2)然後某個事務也要獲取這個表中某條記錄的排他鎖,先獲取這個表的IX鎖,IX與IX之間不衝突,所以可以獲取
3)若某個事務是要對整個表操作,那麼就是要獲取這整個表的X鎖(表級別的)此時就與IX鎖衝突了,當知道該表存在IX鎖被獲取的時候,就知道表中有記錄正在被修改,所以此時等待。
其實就是減免了當要獲取整個表級別的排他鎖時,需要遍歷整個表中的行記錄確認沒有一條記錄正在被鎖。

鎖的算法

Record Lock: 單個行記錄上的鎖
Gap Lock:間隙鎖,鎖定一個範圍,但不包含記錄本身
Next-Key Lock:Gap Lock+Record Lock,鎖定一個範圍,並且鎖定記錄本身。

InnoDb對於行的鎖無論是X鎖還是S鎖都是採用了Next-Key Lock算法,但是對於有唯一性的索引則採用的是Record Lock行級鎖。

MVCC多版本控制併發

MVCC只是工作在兩種事務級別底下:
(a) Read Committed ;
(b) Repeatable Read;

Read Committed隔離級別: 當前讀

像select lock in share mode(共享鎖), select for update ; update, insert ,delete(排他鎖)這些操作都是一種當前讀,爲什麼叫當前讀?就是它讀取的是記錄的最新版本,讀取時還要保證其他併發事務不能修改當前記錄,會對讀取的記錄進行加鎖

Repeatable Read隔離界別:快照讀

像不加鎖的select操作就是快照讀,即不加鎖的非阻塞讀;快照讀的前提是隔離級別不是串行級別,串行級別下的快照讀會退化成當前讀;之所以出現快照讀的情況,是基於提高併發性能的考慮,快照讀的實現是基於多版本併發控制,即MVCC,可以認爲MVCC是行鎖的一個變種,但它在很多情況下,避免了加鎖操作,降低了開銷;既然是基於多版本,即快照讀可能讀到的並不一定是數據的最新版本,而有可能是之前的歷史版本

MVCC多版本控制併發實現原理:

https://blog.csdn.net/SnailMann/article/details/94724197

總結:

本來想一次過寫完,發現整理的原理就滿多的了,分開兩篇來寫吧=。=,下一篇放大招了。

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