1. 程式人生 > 實用技巧 >mysql鎖官方文件與理解之InnoDB鎖

mysql鎖官方文件與理解之InnoDB鎖

This section describes lock types used byInnoDB.

翻譯:本節描述了InnoDB使用的鎖型別。

Shared and Exclusive Locks(共享鎖和排他鎖)

InnoDBimplements standard row-level locking where there are two types of locks,shared (S) locksandexclusive (X) locks.

翻譯:InnoDB實現了標準的行級鎖,其中有兩種鎖,共享鎖和獨佔鎖。

  • Ashared (S) lockpermits the transaction that holds the lock to read a row.(共享(S)鎖允許持有鎖的事務讀取一行)

  • An

    exclusive (X) lockpermits the transaction that holds the lock to update or delete a row.(獨佔(X)鎖允許持有鎖的事務更新或刪除一行。)

If transactionT1holds a shared (S) lock on rowr, then requests from some distinct transactionT2for a lock on rowrare handled as follows:

翻譯:如果事務T1在r行上持有一個共享的(S)鎖,那麼從某個不同的事務T2請求在r行上持有一個鎖的處理如下:

  • A request byT2for anSlock can be granted immediately. As a result, bothT1andT2hold anSlock onr.(T2對S鎖的請求可以立即被授予。因此,T1和T2都對r持有S鎖。)

  • A request byT2for anXlock cannot be granted immediately.(T2對X鎖的請求不能立即被授予。)

If a transactionT1holds an exclusive (X) lock on rowr, a request from some distinct transactionT2for a lock of either type onrcannot be granted immediately. Instead, transactionT2has to wait for transactionT1to release its lock on rowr.

翻譯:如果事務T1在r行上持有排他(X)鎖,則不能立即授予來自不同事務T2對r上任何一種型別的鎖的請求。相反,事務T2必須等待事務T1釋放它在行r上的鎖。

Intention Locks(意向鎖)

InnoDBsupportsmultiple granularity lockingwhich permits coexistence of row locks and table locks. For example, a statement such asLOCK TABLES ... WRITEtakes an exclusive lock (anXlock) on the specified table. To make locking at multiple granularity levels practical,InnoDBusesintention locks. Intention locks are table-level locks that indicate which type of lock (shared or exclusive) a transaction requires later for a row in a table. There are two types of intention locks:

翻譯:InnoDB支援多粒度鎖,允許行鎖和表鎖共存。例如,像LOCK TABLES ... WRITE這樣的語句接受指定表上的獨佔鎖(X鎖)。為了實現多粒度級別的鎖,InnoDB使用意向鎖。意圖鎖是表級鎖,指示事務稍後需要哪種型別的鎖(共享的或排他的)來鎖定表中的某一行。意圖鎖有兩種型別:

  • Anintention shared lock(IS) indicates that a transaction intends to set asharedlock on individual rows in a table.(意圖共享鎖(IS)表示事務打算對錶中的各個行設定共享鎖。)

  • Anintention exclusive lock(IX) indicates that a transaction intends to set an exclusive lock on individual rows in a table.(意圖排他鎖(IX)表示事務打算對錶中的各個行設定排他鎖。)

For example,SELECT ... LOCK IN SHARE MODEsets anISlock, andSELECT ... FOR UPDATEsets anIXlock.

翻譯:例如,SELECT ... LOCK IN SHARE MODE設定IS鎖,SELECT ... FOR UPDATE設定IX鎖。

The intention locking protocol is as follows:

翻譯:意向鎖協議如下:

  • Before a transaction can acquire a shared lock on a row in a table, it must first acquire anISlock or stronger on the table.(事務在獲得表中某行上的共享鎖之前,必須先獲得表上的IS鎖或更強的鎖。)

  • Before a transaction can acquire an exclusive lock on a row in a table, it must first acquire anIXlock on the table.(在事務可以獲得表中某一行上的排他鎖之前,它必須首先獲得表上的IX鎖。)

Table-level lock type compatibility is summarized in the following matrix.

翻譯:表級鎖型別相容性在下面的矩陣中進行了總結。

XIXSIS
X Conflict Conflict Conflict Conflict
IX Conflict Compatible Conflict Compatible
S Conflict Conflict Compatible Compatible
IS Conflict Compatible Compatible Compatible

A lock is granted to a requesting transaction if it is compatible with existing locks, but not if it conflicts with existing locks. A transaction waits until the conflicting existing lock is released. If a lock request conflicts with an existing lock and cannot be granted because it would causedeadlock, an error occurs.

翻譯:如果與現有鎖相容,則將鎖授予請求事務,但如果與現有鎖衝突則不授予。事務將一直等待,直到有衝突的現有鎖被釋放。如果一個鎖請求與一個現有的鎖衝突,並且不能被授予,因為這會導致死鎖,那麼就會發生錯誤。

Intention locks do not block anything except full table requests (for example,LOCK TABLES ... WRITE). The main purpose of intention locks is to show that someone is locking a row, or going to lock a row in the table.

翻譯:意向鎖不阻塞任何東西,除了全表請求(例如,LOCK TABLES ... WRITE)。意圖鎖的主要目的是顯示某人正在鎖定或準備鎖定表中的一行。

Transaction data for an intention lock appears similar to the following inSHOW ENGINE INNODB STATUSandInnoDB monitoroutput:

翻譯:意圖鎖的事務資料在SHOW ENGINE INNODB STATUSInnoDB monitor輸出中類似如下:

TABLE LOCK table `test`.`t` trx id 10080 lock mode IX

Record Locks(記錄鎖)

A record lock is a lock on an index record. For example,SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE;prevents any other transaction from inserting, updating, or deleting rows where the value oft.c1is10.

Record locks always lock index records, even if a table is defined with no indexes. For such cases,InnoDBcreates a hidden clustered index and uses this index for record locking. SeeSection14.6.2.1, “Clustered and Secondary Indexes”.

翻譯:記錄鎖是在一個索引記錄上加的鎖。例如,SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE;防止任何其他事務插入、更新或刪除t.c1值為10的行。記錄鎖總是鎖定索引記錄,即使表沒有定義索引。

對於這種情況,InnoDB建立一個隱藏的聚集索引並使用這個索引來鎖定記錄。參見14.6.2.1節“聚集和二級索引”。

Transaction data for a record lock appears similar to the following inSHOW ENGINE INNODB STATUSandInnoDB monitoroutput:

翻譯:記錄鎖的事務資料在SHOW ENGINE INNODB STATUSInnoDB monitor輸出中類似如下

RECORD LOCKS space id 58 page no 3 n bits 72 index `PRIMARY` of table `test`.`t`
trx id 10078 lock_mode X locks rec but not gap
Record lock, heap no 2 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 4; hex 8000000a; asc     ;;
 1: len 6; hex 00000000274f; asc     'O;;
 2: len 7; hex b60000019d0110; asc        ;;

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. For example,SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE;prevents other transactions from inserting a value of15into columnt.c1, whether or not there was already any such value in the column, because the gaps between all existing values in the range are locked.

翻譯:間隙鎖是在索引記錄之間間隙的鎖,或者對第一個索引記錄之前或最後一個索引記錄之後的間隙的鎖。例如,SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE;防止其他事務在列t.c1中插入15的值,無論列中是否已經有這樣的值,因為範圍內所有現有值之間的間隙都被鎖定。

A gap might span a single index value, multiple index values, or even be empty.

翻譯:一個間隙可能跨越一個索引值、多個索引值,甚至是空的。

Gap locks are part of the tradeoff between performance and concurrency, and are used in some transaction isolation levels and not others.

翻譯:間隙鎖是效能和併發性折衷的一部分,在某些事務隔離級別中使用,而在其他級別中不使用。

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 theidcolumn has a unique index, the following statement uses only an index-record lock for the row havingidvalue 100 and it does not matter whether other sessions insert rows in the preceding gap:

翻譯:對於使用惟一索引來搜尋惟一行來鎖定行的語句,則不需要間隙鎖定。(這不包括搜尋條件只包括多列唯一索引的一些列;在這種情況下,間隙鎖定確實會發生。) 例如,如果id列有一個唯一的索引,下面的語句只對id值為100的行使用索引-記錄鎖,其他會話是否在前面的間隙插入行並不重要:

SELECT * FROM child WHERE id = 100;

Ifidis not indexed or has a nonunique index, the statement does lock the preceding gap.

翻譯:如果id沒有索引或具有非惟一索引,該語句會鎖定前面的間隙。

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可以在一個間隙上持有一個共享的間隙鎖(間隙S-lock),同時事務B可以在同一個間隙上持有一個排他的間隙鎖(間隙X-lock)。允許存在衝突間隙鎖的原因是,如果從索引中清除一條記錄,則必須合併記錄上由不同事務持有的間隙鎖。

Gap locks inInnoDBarepurely inhibitive”, which means that their only purpose is to prevent other transactions from inserting to the gap. Gap locks can co-exist. A gap lock taken by one transaction does not prevent another transaction from taking a gap lock on the same gap. There is no difference between shared and exclusive gap locks. They do not conflict with each other, and they perform the same function.

翻譯:InnoDB中的間隙鎖是“純粹的禁忌”,這意味著它們的唯一目的是防止其他事務插入到間隙中。間隙鎖可以共存。一個事務所獲取的間隙鎖不會阻止另一個事務在同一間隙上獲取間隙鎖。共享間隙鎖和獨佔間隙鎖之間沒有區別。它們彼此不衝突,並且執行相同的功能。

Gap locking can be disabled explicitly. This occurs if you change the transaction isolation level toREAD COMMITTEDor enable theinnodb_locks_unsafe_for_binlogsystem variable (which is now deprecated). 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.

翻譯:可以顯式禁用間隙鎖定。如果您更改事務隔離級別為READ COMMITTED或啟用innodb_locks_unsafe_for_binlog系統變數(該變數現在不贊成使用),就會發生這種情況。在這些情況下,間隙鎖定對於搜尋和索引掃描是禁用的,只用於外來鍵約束檢查和重複鍵檢查。

There are also other effects of using theREAD COMMITTEDisolation level or enablinginnodb_locks_unsafe_for_binlog. Record locks for nonmatching rows are released after MySQL has evaluated theWHEREcondition. ForUPDATEstatements,InnoDBdoes asemi-consistent”read, such that it returns the latest committed version to MySQL so that MySQL can determine whether the row matches theWHEREcondition of theUPDATE.

翻譯:使用READ COMMITTED隔離級別或啟用innodb_locks_unsafe_for_binlog還有其他影響。在MySQL評估了WHERE條件後,將釋放非匹配行的記錄鎖。對於UPDATE語句,InnoDB執行“半一致”讀取,這樣它就會返回最新提交的版本給MySQL,這樣MySQL就可以確定行是否與UPDATE的WHERE條件匹配。

Next-Key Locks(next-key鎖)

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鎖是索引記錄上的記錄鎖和索引記錄前間隙上的間隙鎖的組合。

InnoDBperforms 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. A next-key lock on an index record also affects thegap”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 recordRin an index, another session cannot insert a new index record in the gap immediately beforeRin the index order.

翻譯:InnoDB執行行級鎖的方式是,當它搜尋或掃描一個表索引時,它會對遇到的索引記錄設定共享鎖或排他鎖。因此,行級鎖實際上是索引記錄鎖。索引記錄上的next-key鎖還會影響該索引記錄之前的“間隙”。也就是說,next-key鎖是索引記錄鎖加上索引記錄之前的間隙鎖。如果一個會話對索引中的記錄R有共享或排他鎖,則另一個會話不能在索引順序中緊靠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 a round bracket denotes exclusion of the interval endpoint and a square bracket denotes inclusion of the endpoint:

翻譯:假設索引包含值10、11、13和20。這個索引可能的next-key鎖包括以下的時間間隔,其中圓括號表示間隔端點的排除,方括號表示端點的包含:

(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 thesupremum”pseudo-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鎖鎖定索引中最大值和“上極”偽記錄(其值比實際索引中的任何值都高)之間的間隙。上限值並不是一個真正的索引記錄,因此,這個next-key鎖實際上只鎖定了最大索引值之後的間隙。

By default,InnoDBoperates inREPEATABLE READtransaction isolation level. In this case,InnoDBuses next-key locks for searches and index scans, which prevents phantom rows (seeSection14.7.4, “Phantom Rows”).

翻譯:預設情況下,InnoDB操作在可重複讀事務隔離級別。在這種情況下,InnoDB使用next-key鎖進行搜尋和索引掃描,這可以防止幻像行(見14.7.4節“幻像行”)。

Transaction data for a next-key lock appears similar to the following inSHOW ENGINE INNODB STATUSandInnoDB monitoroutput:

翻譯:下一鍵鎖定的事務資料在SHOW ENGINE INNODB STATUSInnoDB monitor輸出中類似如下:

RECORD LOCKS space id 58 page no 3 n bits 72 index `PRIMARY` of table `test`.`t`
trx id 10080 lock_mode X
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
 0: len 8; hex 73757072656d756d; asc supremum;;

Record lock, heap no 2 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 4; hex 8000000a; asc     ;;
 1: len 6; hex 00000000274f; asc     'O;;
 2: len 7; hex b60000019d0110; asc        ;;

Insert Intention Locks(插入意向鎖)

An insert intention lock is a type of gap lock set byINSERToperations 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, respectively, 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.

翻譯:插入意圖鎖是一種間隙鎖,由行插入之前的插入操作設定。如果多個插入到同一個索引間隙的事務沒有在間隙內的相同位置插入,則該鎖將以這樣的方式表示插入的意圖:多個插入到同一個索引間隙的事務不需要相互等待。假設有值為4和7的索引記錄。分別嘗試插入值為5和6的獨立事務,在獲得插入行的排他鎖之前,都使用插入意圖鎖鎖住4和7之間的間隙,但不會相互阻塞,因為這兩行不衝突。

The following example demonstrates a transaction taking an insert intention lock prior to obtaining an exclusive lock on the inserted record. The example involves two clients, A and B.

Client A creates a table containing two index records (90 and 102) and then starts a transaction that places an exclusive lock on index records with an ID greater than 100. The exclusive lock includes a gap lock before record 102:

mysql> CREATE TABLE child (id int(11) NOT NULL, PRIMARY KEY(id)) ENGINE=InnoDB;
mysql> INSERT INTO child (id) values (90),(102);

mysql> START TRANSACTION;
mysql> SELECT * FROM child WHERE id > 100 FOR UPDATE;
+-----+
| id  |
+-----+
| 102 |
+-----+

Client B begins a transaction to insert a record into the gap. The transaction takes an insert intention lock while it waits to obtain an exclusive lock.

mysql> START TRANSACTION;
mysql> INSERT INTO child (id) VALUES (101);

Transaction data for an insert intention lock appears similar to the following inSHOW ENGINE INNODB STATUSandInnoDB monitoroutput:

RECORD LOCKS space id 31 page no 3 n bits 72 index `PRIMARY` of table `test`.`child`
trx id 8731 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 3 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 4; hex 80000066; asc    f;;
 1: len 6; hex 000000002215; asc     " ;;
 2: len 7; hex 9000000172011c; asc     r  ;;...