InnoDB 鎖

1.  Shared and Exclusive Lockshtml

shared lock (譯:共享鎖)mysql

exclusive lock (譯:排它鎖、獨佔鎖)sql

InnoDB實現了標準的行級鎖,其中有兩種類型的鎖,共享鎖(shared locks)和排他鎖(exclusive locks)。併發

A shared (S) lock permits the transaction that holds the lock to read a row.性能

An exclusive (X) lock permits the transaction that holds the lock to update or delete a row.spa

共享鎖容許持有該鎖的事務讀取一行。code

排它鎖容許持有該鎖的事務更新或刪除行。orm

若是事務T1持有行 r 上的共享鎖(S),那麼來自不一樣事務T2的請求將按照如下方式處理: htm

  • T2對S鎖的請求能夠當即被授予。結果就是,T1和T2在行r上都持有S鎖。
  • T2對X鎖的請求不能當即被授予。

若是事務T1持有行 r 上的排它鎖(X),那麼來自不一樣事務T2的請求不能當即被授予 r 上任何一種類型的鎖。相反,事務T2必須等待事務T1釋放其在行 r 上的鎖。blog

2.  Intention Locks

Intention Locks(譯:意向鎖)

InnoDB支持多粒度鎖,容許行鎖和表鎖共存。 例如,諸如LOCK TABLES ... WRITE之類的語句對指定表採用排它鎖(X鎖)。爲了在多個粒度級別上實現鎖,InnoDB使用了意向鎖。意向鎖是表級鎖,它指示事務稍後須要對錶中的一行使用哪一種類型的鎖(共享鎖或者排它鎖)。 

有兩種類型的意向鎖:

  • 意向共享鎖(IS)表示事務打算在表中的單個行上設置共享鎖。
  • 意向排他鎖(IX)表示事務打算在表中的單個行上設置排它鎖。

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

意向鎖的協定是這樣的:

  • 在事務得到表中某一行的共享鎖以前,它必須首先得到表上的IS鎖或更強鎖。
  • 在事務得到表中某一行的排它鎖以前,它必須首先得到表上的IX鎖。 

表級鎖類型兼容性以下圖:

 

若是一個鎖與現有鎖兼容,則將其授予請求的事務,但若是與現有鎖衝突,則不授予該鎖。事務等待,直到衝突的現有鎖被釋放。若是一個鎖請求與一個現有的鎖衝突,而且由於它會致使死鎖而不能被授予,那麼就會發生錯誤。

意向鎖除了全表請求(例如LOCK TABLES ... WRITE)外,不阻止任何其餘內容。意圖鎖定的主要目的是代表某人正在鎖定表中的行或要鎖定表中的行。

3.  Record Locks

Record Locks(譯:記錄鎖)

A record lock is a lock on an index record. 

記錄鎖是索引記錄上的鎖。例如,SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE;  防止任何其餘事務插入、更新或刪除t.c1值爲10的行。

記錄鎖老是鎖定索引記錄,即便一個表沒有定義索引也是如此。若是表沒有索引,InnoDB建立一個隱藏的彙集索引,並將該索引用於記錄鎖。

4.  Gap Locks

Gap Locks(譯:間隙鎖)

A gap lock is a lock on a gap between index records, or a lock on the gap before the first or after the last index record.  

間隙鎖是在索引記錄之間的間隙上的鎖,或者是在第一個索引記錄以前或最後一個索引記錄以後的間隙上的鎖。

例如,SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE;  防止其餘事務將值15插入到t.c1列中,不管該列中是否已經有這樣的值,由於範圍內全部現有值之間的間隙都被鎖定了。

間隙可能跨越單個索引值、多個索引值,甚至是空的。

間隙鎖是性能和併發性之間權衡的一部分,在某些事務隔離級別中使用,而在其餘級別中則不使用。

對於使用惟一索引鎖定行以搜索惟一行的語句,不須要間隙鎖定。

例如,若是id列有一個惟一的索引,下面的語句只對id值爲100的行使用index-record鎖,而無論其餘會話是否在前面的間隙插入行:

SELECT * FROM child WHERE id = 100;

若是id列沒有索引或者有一個非惟一索引,則該語句會鎖定前面的間隙。

這裏還值得注意的是,不一樣的事務能夠在一個間隙上持有衝突的鎖。

例如,事務A能夠在一個間隙上持有一個共享間隙鎖(gap S-lock),而事務B在同一個間隙上持有一個排他間隙鎖(gap X-lock)。容許衝突間隙鎖的緣由是,若是一條記錄從一個索引中被清除,那麼記錄上由不一樣事務持有的間隙鎖必須被合併。

InnoDB中間隙鎖的惟一目的是防止其餘事務插入間隙。間隙鎖能夠共存。一個事務取得的間隙鎖並不會阻止另外一個事務取得同一間隙上的間隙鎖。共享和獨佔間隔鎖之間沒有區別。它們彼此之間不衝突,而且執行相同的功能。

5.  Next-Key Locks

 A next-key lock is a combination of a record lock on the index record and a gap lock on the gap before the index record.

next-key鎖是索引記錄上的記錄鎖和索引記錄以前的間隙鎖的組合。

InnoDB執行行級鎖的方式是這樣的:當它搜索或掃描一個表索引時,它會在遇到的索引記錄上設置共享鎖或排他鎖。所以,行級鎖其實是索引記錄鎖。索引記錄上的next-key鎖也會影響該索引記錄以前的「間隙」。也就是說,next-key鎖是索引記錄鎖加上索引記錄以前的間隙鎖。若是一個會話在一個索引中的記錄R上有一個共享鎖或排他鎖,則另外一會話沒法按照索引順序在R以前的間隙中插入新的索引記錄。

假設一個索引包含值十、十一、13和20。該索引可能的next-key鎖覆蓋如下區間:

(negative infinity, 10]
(10, 11]
(11, 13]
(13, 20]
(20, positive infinity)

默認狀況下,InnoDB使用REPEATABLE READ事務隔離級別。在這種狀況下,InnoDB使用next-key鎖進行搜索和索引掃描,以阻止幻象行。

6.  Insert Intention Locks

Insert Intention Locks(譯:插入意向鎖)

插入意向鎖是一種間隙鎖,是由INSERT操做在行插入以前設置的。這個鎖表示,若是多個事務插入到同一個索引間隙中,若是它們沒有插入到這個間隙中的同一位置,那麼它們就不須要等待對方。假設有值爲4和7的索引記錄。嘗試插入值分別爲5和6的獨立事務,在得到插入行的排他鎖以前,每一個事務都用插入意向鎖鎖住4和7之間的間隙,但不會阻塞彼此,由於行是不衝突的。

7.  AUTO-INC Locks

AUTO-INC鎖是一種特殊的表級鎖,由插入到帶有AUTO_INCREMENT列的表中的事務得到。在最簡單的狀況下,若是一個事務正在向表中插入值,那麼任何其餘事務都必須等待本身對該表的插入,以便由第一個事務插入的行接收連續的主鍵值。

 

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

相關文章
相關標籤/搜索