InnoDB Record, Gap, and Next-Key Locks

InnoDB has several types of record-level locks including record locks, gap locks, and next-key locks. For information about shared locks, exclusive locks, and intention locks, see Section 14.3.5.3, 「InnoDB Lock Modes」.html

InnoDB有幾種行級鎖類型, 包括 record 鎖, gap 鎖, next-key鎖. mysql

  • Record lock: This is a lock on an index record.sql

  • Record lock: 這是一個索引上的鎖
  • Gap lock: This is a lock on a gap between index records, or a lock on the gap before the first or after the last index record.session

  • Gap lock: 這是一個索引記錄區間上的鎖, 或者一個在第一條索引記錄以前或最後一條索引記錄以後的間隙上的鎖
  • Next-key lock: This is a combination of a record lock on the index record and a gap lock on the gap before the index record.this

  • Next-key lock: 這是一個index的record lock和在這個index以前的間隙的gap lock的組合
Record Locks

Record locks always lock index records, even if a table is defined with no indexes. For such cases, InnoDB creates a hidden clustered index and uses this index for record locking. See Section 14.3.5.13.2, 「Clustered and Secondary Indexes」.lua

record locks 老是鎖定索引記錄, 即便一個表並無定義索引.這種狀況下, InnoDB建立了一個隱藏的clustered索引, 並用這個索引來進行record locking.spa

Next-key Locks

By default, InnoDB operates in REPEATABLE READ transaction isolation level and with theinnodb_locks_unsafe_for_binlog system variable disabled. In this case, InnoDB uses next-key locks for searches and index scans, which prevents phantom rows (see Section 14.3.5.7, 「Avoiding the Phantom Problem Using Next-Key Locking」).code

默認的, InnoDB工做於REPEATABLE READ事務隔離級別而且innodb_locks_unsafe_for_binlog系統變量是disabled的.在這種狀況下, InnoDB使用next-key locks來查找和索引掃描, 這阻止了幻讀的產生.orm

Next-key locking combines index-row locking with gap locking. InnoDB performs row-level locking in such a way that when it searches or scans a table index, it sets shared or exclusive locks on the index records it encounters. Thus, the row-level locks are actually index-record locks. In addition, a next-key lock on an index record also affects the gap before that index record. That is, a next-key lock is an index-record lock plus a gap lock on the gap preceding the index record. If one session has a shared or exclusive lock on record R in an index, another session cannot insert a new index record in the gap immediately before R in the index order.htm

Next-key locking 組合了 index-row locking 和 gap locking. InnoDB在搜索或者掃描表索引時使用了行級鎖定, 他在遇到的索引記錄上設置共享或排他鎖. 所以, 行級鎖其實是索引記錄鎖.另外, 一個索引上的next-key鎖也會影響index記錄以前的"gap", 那就是, 一個 next-key鎖是一個index-record lock 加上一個 gap lock, 它位於指定索引及索引以前的間隙, 形如 (a, b]. 若是一次護花擁有一個記錄行R的索引的共享或排他鎖, 另一個會話將不能插入新索引行到間隙之間.

Suppose that an index contains the values 10, 11, 13, and 20. The possible next-key locks for this index cover the following intervals, where ( or ) denote exclusion of the interval endpoint and [ or ] denote inclusion of the endpoint:

假設索引包含10,11,13,20. 可能的next-key locks覆蓋以下間隔, ()表示排除, []表示包含

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

For the last interval, the next-key lock locks the gap above the largest value in the index and the supremumpseudo-record having a value higher than any value actually in the index. The supremum is not a real index record, so, in effect, this next-key lock locks only the gap following the largest index value.

對於最後一個間隔, next-key lock 鎖定了大於最大值的全部間隙, 而且上界是一個假的大於任何已有值的值. 上界並非一個真的索引記錄, 因此, next-key lock只鎖定了最大值以上的值.

Gap Locks

The next-key locking example in the previous section shows that a gap might span a single index value, multiple index values, or even be empty.

上面的next-key locking 例子展現了一個gap可能會跨越單個索引值, 多個索引值, 或者是空

Gap locking is not needed for statements that lock rows using a unique index to search for a unique row. (This does not include the case that the search condition includes only some columns of a multiple-column unique index; in that case, gap locking does occur.) For example, if the id column has a unique index, the following statement uses only an index-record lock for the row having id value 100 and it does not matter whether other sessions insert rows in the preceding gap:

Gap locking在使用惟一索引來查找一個惟一行是不須要的.(這不包括查找中僅僅包含一些多列惟一索引的列的狀況, 這種狀況下, 間隙鎖會發揮做用.) 例如, 若是id列有一個惟一索引, 下面的語句僅僅會使用index-record lock, 使用的範圍是id值100, 並不會阻止其餘會話在100以前插入記錄

SELECT * FROM child WHERE id = 100;

If id is not indexed or has a nonunique index, the statement does lock the preceding gap.

若是id不是索引, 或者只有一個非惟一索引, 那麼語句就會使用間隙鎖.

A type of gap lock called an insertion intention gap lock is set by INSERT operations prior to row insertion. This lock signals the intent to insert in such a way that multiple transactions inserting into the same index gap need not wait for each other if they are not inserting at the same position within the gap. Suppose that there are index records with values of 4 and 7. Separate transactions that attempt to insert values of 5 and 6 each lock the gap between 4 and 7 with insert intention locks prior to obtaining the exclusive lock on the inserted row, but do not block each other because the rows are nonconflicting. For more information about intention locks, seeSection 14.3.5.3, 「InnoDB Lock Modes」.

有一種間隙鎖叫插入意向間隙鎖, 他是由INSERT語句對行的插入產生的. 這個鎖表示了若是有多個事務打算插入記錄到同一個索引間隙, 他們不須要彼此等待, 只要他們插入的位置不是同一個位置. 想象有索引記錄4,7.有兩個事務試圖插入5,6, 他們都使用插入意向鎖鎖住了4,7之間的間隙來獲取插入行的排他鎖,可是他們並不會相互阻塞, 由於行之間並不會衝突.

It is also worth noting here that conflicting locks can be held on a gap by different transactions. For example, transaction A can hold a shared gap lock (gap S-lock) on a gap while transaction B holds an exclusive gap lock (gap X-lock) on the same gap. The reason conflicting gap locks are allowed is that if a record is purged from an index, the gap locks held on the record by different transactions must be merged.

值得一提的是衝突的鎖能夠被不一樣的事務在同一個間隙中持有. 例如, 事務A能夠在一個間隙上持有一個共享間隙鎖, 同時事務B能夠也能夠在該間隙上持有一個排他間隙鎖. 這種情形被容許的緣由是若是一條記錄從索引中清除了, 不一樣事務持有的這條記錄上的gap鎖必須被合併

Gap locks in InnoDB are purely inhibitive, which means they only stop other transactions from inserting to the gap. Thus, a gap X-lock has the same effect as a gap S-lock.

gap locks 在innodb中是"徹底被抑制的", 這意味着他們僅僅阻止其餘事務在間隙中執行插入操做.所以, 一個gap X-lock的效果和一個gap S-lock是同樣的.

Disabling Gap Locking

Gap locking can be disabled explicitly. This occurs if you change the transaction isolation level to READ COMMITTED or enable the innodb_locks_unsafe_for_binlog system variable. Under these circumstances, gap locking is disabled for searches and index scans and is used only for foreign-key constraint checking and duplicate-key checking.

Gap locking是能夠被顯式禁用的. 你講事務隔離級別設置爲READ_COMMITTED或者啓用innodb_locks_unsafe_for_binlog系統變量時就能夠禁用它.在這種狀況下, gap locking在查找和索引掃描的時候會被禁用, 僅僅在外鍵約束檢查和重複鍵檢查時被使用.

There are also other effects of using the READ COMMITTED isolation level or enablinginnodb_locks_unsafe_for_binlog: Record locks for nonmatching rows are released after MySQL has evaluated the WHERE condition. For UPDATE statements, InnoDB does a semi-consistent read, such that it returns the latest committed version to MySQL so that MySQL can determine whether the row matches the WHEREcondition of the UPDATE.

還有些別的反作用: 沒有匹配行的Record locks在MYSQL評估完WHERE語句後會被釋放.對於UPDATE, innodb作了一次"半一致"讀, 它返回最後提交的版本給MYSQL, 這樣MSYQL能夠判斷這一行是否匹配UPDATE的WHERE條件.

相關文章
相關標籤/搜索