MySQL InnoDB鎖定的那些事


Shared and Exclusive Locks

InnoDB標準是使用row-level鎖定,其中又有分2種鎖定類別
shared(S) locks和exclusive(X) locks

  • shared(S) lock允許交易持有讀取行的鎖
  • exclusive(X) lock允許交易持有更新或刪除行的鎖
如果今天有筆交易T1持有s鎖在資料行r,此時有另一個交易T2也要對資料行r進行鎖定時,情況如下:

  • 如果T2也是使用S鎖定則可立即執行,此時T1和T2對資料行r同時擁有s鎖定。
  • 如果T2是使用X鎖定,則無法立即執行
另外,如果今天T1持有X鎖在資料行r,此時T2要對資料行r進行S鎖或X鎖時,則無法立即執行,須等到T1解除鎖定行T2才能對資料行r進行鎖定。

Intention Locks

InnoDB支援多粒度鎖定允許row-level鎖定和整表鎖定共存於同張資料表中,為實現多粒度鎖定會額外使用一稱為intention locks的鎖定,此意圖鎖在InnoDB資料表中為table-level lock,用來指示此交易在資料表中的某行之後會使用哪種類型的鎖定(Shared或Exclusive),它也有兩種鎖定類型:

  • Intention shared (IS):交易T意圖在資料表a各別資料行上持有S鎖
  • Intention exclusive (IX):交易T意圖在某些資料行上持有X鎖
例如:SELECT ... LOCK IN SHARE MODE會設定IS鎖,SELECT ... FOR UPDATE設定IX鎖。
Intention Lock的協議如下:

  • 一個交易在資料表a中的一資料行獲得S鎖之前,必須先取得a資料表的IS鎖或更強的鎖
  • 一個交易在獲得一資料行的X鎖之前,必須先取得a資料表的IX鎖
總結如下表:
XIXSIS
X衝突衝突衝突衝突
IX衝突相容衝突相容
S衝突衝突相容相容
IS衝突相容相容相容
在相容的情況下允許在現有的鎖中被授予其他的鎖定,而衝突的情況下則需等待前一個鎖定釋放後,才能對此進行鎖定,否則會發生死鎖或錯誤。

因此,意圖鎖定不會阻止除全表請求任何東西(例如,LOCK TABLES... WRITE),其主要目的是在顯示某人正在鎖定資料行,或是即將對資料表中的資料行進行鎖定。

Record Locks

它是一個索引記錄的鎖,例如:select c1 for update from t where c1 = 10;防止任何其它交易從t.c1=10的行中插入,更新或刪除。
Record lock即使表中並未定議任何索引,它始終會鎖定索引記錄,像這種情況,InnoDB創建一個隱藏的聚集索引並使用該索引記錄鎖定。

Gap Locks

它是一個索引記錄間隔的鎖或是索引記錄最前面或最後面間隔的鎖,例否:SELECT c1 FOR UPDATE FROM t WHERE c1 BETWEEN 10 AND 20;如果有一個交易要插入c1=15的話會被限制住,不論這個值是否已存在於欄位之中,因為在這範圍內所有的值都被gap lock給鎖定了。

待續…

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

留言

這個網誌中的熱門文章

【工作筆記】SQL Timeout追蹤

MySQL監控軟體MEM及PMM介紹

MySQL Router 設定檔說明