1. Shared and Exclusive Locks
shared lock (譯:共享鎖)
exclusive lock (譯:排它鎖、獨占鎖)
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.
共享鎖允許持有該鎖的事務讀取一行,
排它鎖允許持有該鎖的事務更新或洗掉行,
如果事務T1持有行 r 上的共享鎖(S),那么來自不同事務T2的請求將按照以下方式處理:
- T2對S鎖的請求可以立即被授予,結果就是,T1和T2在行r上都持有S鎖,
- T2對X鎖的請求不能立即被授予,
如果事務T1持有行 r 上的排它鎖(X),那么來自不同事務T2的請求不能立即被授予 r 上任何一種型別的鎖,相反,事務T2必須等待事務T1釋放其在行 r 上的鎖,
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之前的間隙中插入新的索引記錄,
假設一個索引包含值10、11、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
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/253938.html
標籤:其他
