InnoDB鎖

共享鎖和排它鎖

InnoDB實現了標準的行級鎖,包括兩種類型:共享鎖(S)和排它鎖(X)html

  • 一個共享鎖(S)容許事務持有這種鎖來讀取一行
  • 一個排它鎖(X)容許事務持有這種鎖來修改或刪除一行

若是事務T1對行r持有一個共享鎖(S),那麼來自其它事務T的對於行r的鎖的請求處理以下:mysql

  • 若是T2請求的是共享鎖(S),那麼將當即被授予共享鎖。這樣的話,T1和T2都持有r的共享鎖(S)
  • 若是T2請求的是排它鎖,則不能被當即授予

若是事務T1持有行r的排它鎖,那麼來自其它事務T2對r的任何鎖請求都不能被當即授予。此時,T2必須等待T1釋放對r鎖持有的鎖。sql

意向鎖

InnoDB支持多種粒度的鎖,它容許行級別的鎖和表級別的鎖共存。爲了支持多種粒度級別的鎖,須要用到另一種鎖,叫意向鎖。在InnoDB中,意向鎖是表級別的鎖,它表示稍後會鎖定表中的一行。有兩種類型的意向鎖:性能

  • 意向共享鎖(IS):事務T打算在表t中的某個行上設置共享鎖(S)
  • 共享排它鎖(IX):事務T打算在這些行上設置排它鎖(X)

例如,SELECT ... LOCK IN SHARE MODE將設置一個IS鎖,而SELECT ... FOR UPDATE將設置一個IX鎖spa

意向鎖協議以下:htm

  • 一個事務在得到表t上的某一行的共享鎖(S)以前,它必須先在表t上得到意向共享鎖(IS)或者更高級別的鎖
  • 一個事務在得到表t上的某一行的排它鎖(X)以前,它必須如今表t上得到意向排它鎖(IX)

一個鎖被授予一個事務請求必須保證和已經存在的鎖兼容,若是衝突的話將不能被授予。一個事務必須等待知道和它想得到的鎖衝突的存在的鎖被釋放。blog

記錄鎖

一個記錄鎖是一種在索引記錄上的鎖。例如,SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE;阻止其它事務對t.c1=10的行的添加修改刪除操做。索引

記錄鎖老是鎖定索引記錄,即便表沒有定義索引。對這種狀況,InnoDB會建立隱藏的索引,而且用這個索引來加鎖。事務

間隙鎖

一個間隙鎖是加在索引記錄之間的間隙的鎖,或者在第一個索引記錄以前或者在最後一個索引記錄以後的鎖。例如,SELECT c1 FROM t WHERE c1 BETWEEN 10 AND 20 FOR UPDATE;阻止其它事務插入一個值15在t.c1列上,由於在這個範圍內的全部存在的值的間隙之間已經被鎖定。innodb

一個間隙可能跨過一個單個的索引值,也可能跨過是多個索引值,甚至是空。

間隙鎖是在性能和一致性上的一個折中的方式,它被用在某些事物隔離級別上。

Next-Key鎖

一個next-key鎖是一個在索引記錄上的記錄鎖和一個在索引記錄以前的間隙的間隙鎖的一個結合。

InnoDB容許行級別的鎖以這樣的方式,當它搜索或者掃描一個表的索引時,會給它掃描到的索引記錄設置共享或排它鎖。所以,行級別的鎖其實是索引記錄鎖,一個next-key鎖是一個索引記錄鎖加上一個在索引記錄以前的間隙的間隙鎖。若是一個會話持有一個索引記錄R的共享或者排它鎖,那麼另一個會話不能在這個記錄R以前插入新的索引值。

假設一個索引包含的值有:十、十一、1三、20,那麼對這個索引的next-key鎖會包含下面這樣幾個間隔,也就是說鎖定範圍覆蓋這些區間:

 

這是前開後閉區間

默認狀況下,InnoDB的默認隔離級別是REPEATABLE_READ。在這種狀況下,對於檢索和索引掃描,InnoDB使用next-key鎖。

 

總結:

一、記錄鎖是索引記錄上的鎖

二、間隙鎖是索引記錄之間的間隙的鎖

三、next-key鎖是記錄鎖加上間隙鎖

四、行級別鎖其實是記錄鎖

五、意向鎖是表級別的鎖

 

參考 https://dev.mysql.com/doc/refman/5.7/en/innodb-locking.html

相關文章
相關標籤/搜索