MySQL InnoDB 鎖的相關(guān)總結(jié)
1. Shared and Exclusive Locks
shared lock (譯:共享鎖)
exclusive lock (譯:排它鎖、獨(dú)占鎖)
InnoDB實(shí)現(xiàn)了標(biāo)準(zhǔn)的行級(jí)鎖,其中有兩種類(lèi)型的鎖,共享鎖(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.
共享鎖允許持有該鎖的事務(wù)讀取一行。
排它鎖允許持有該鎖的事務(wù)更新或刪除行。
如果事務(wù)T1持有行 r 上的共享鎖(S),那么來(lái)自不同事務(wù)T2的請(qǐng)求將按照以下方式處理:
- T2對(duì)S鎖的請(qǐng)求可以立即被授予。結(jié)果就是,T1和T2在行r上都持有S鎖。
- T2對(duì)X鎖的請(qǐng)求不能立即被授予。
如果事務(wù)T1持有行 r 上的排它鎖(X),那么來(lái)自不同事務(wù)T2的請(qǐng)求不能立即被授予 r 上任何一種類(lèi)型的鎖。相反,事務(wù)T2必須等待事務(wù)T1釋放其在行 r 上的鎖。
2. Intention Locks
Intention Locks(譯:意向鎖)
InnoDB支持多粒度鎖,允許行鎖和表鎖共存。 例如,諸如LOCK TABLES ... WRITE之類(lèi)的語(yǔ)句對(duì)指定表采用排它鎖(X鎖)。為了在多個(gè)粒度級(jí)別上實(shí)現(xiàn)鎖,InnoDB使用了意向鎖。意向鎖是表級(jí)鎖,它指示事務(wù)稍后需要對(duì)表中的一行使用哪種類(lèi)型的鎖(共享鎖或者排它鎖)。
有兩種類(lèi)型的意向鎖:
- 意向共享鎖(IS)表示事務(wù)打算在表中的單個(gè)行上設(shè)置共享鎖。
- 意向排他鎖(IX)表示事務(wù)打算在表中的單個(gè)行上設(shè)置排它鎖。
例如,SELECT ... LOCK IN SHARE MODE 設(shè)置一個(gè)IS鎖,SELECT ... FOR UPDATE 設(shè)置一個(gè)IX鎖。
意向鎖的協(xié)定是這樣的:
在事務(wù)獲得表中某一行的共享鎖之前,它必須首先獲得表上的IS鎖或更強(qiáng)鎖。
在事務(wù)獲得表中某一行的排它鎖之前,它必須首先獲得表上的IX鎖。
表級(jí)鎖類(lèi)型兼容性如下圖:

如果一個(gè)鎖與現(xiàn)有鎖兼容,則將其授予請(qǐng)求的事務(wù),但如果與現(xiàn)有鎖沖突,則不授予該鎖。事務(wù)等待,直到?jīng)_突的現(xiàn)有鎖被釋放。如果一個(gè)鎖請(qǐng)求與一個(gè)現(xiàn)有的鎖沖突,并且因?yàn)樗鼤?huì)導(dǎo)致死鎖而不能被授予,那么就會(huì)發(fā)生錯(cuò)誤。
意向鎖除了全表請(qǐng)求(例如LOCK TABLES ... WRITE)外,不阻止任何其他內(nèi)容。意圖鎖定的主要目的是表明某人正在鎖定表中的行或要鎖定表中的行。
3. Record Locks
Record Locks(譯:記錄鎖)
A record lock is a lock on an index record.
記錄鎖是索引記錄上的鎖。例如,SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE; 防止任何其他事務(wù)插入、更新或刪除t.c1值為10的行。
記錄鎖總是鎖定索引記錄,即使一個(gè)表沒(méi)有定義索引也是如此。如果表沒(méi)有索引,InnoDB創(chuàng)建一個(gè)隱藏的聚集索引,并將該索引用于記錄鎖。
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.
間隙鎖是在索引記錄之間的間隙上的鎖,或者是在第一個(gè)索引記錄之前或最后一個(gè)索引記錄之后的間隙上的鎖。
例如,SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE; 防止其他事務(wù)將值15插入到t.c1列中,無(wú)論該列中是否已經(jīng)有這樣的值,因?yàn)榉秶鷥?nèi)所有現(xiàn)有值之間的間隙都被鎖定了。
間隙可能跨越單個(gè)索引值、多個(gè)索引值,甚至是空的。
間隙鎖是性能和并發(fā)性之間權(quán)衡的一部分,在某些事務(wù)隔離級(jí)別中使用,而在其他級(jí)別中則不使用。
對(duì)于使用唯一索引鎖定行以搜索唯一行的語(yǔ)句,不需要間隙鎖定。
例如,如果id列有一個(gè)唯一的索引,下面的語(yǔ)句只對(duì)id值為100的行使用index-record鎖,而不管其他會(huì)話(huà)是否在前面的間隙插入行:
SELECT * FROM child WHERE id = 100;
如果id列沒(méi)有索引或者有一個(gè)非唯一索引,則該語(yǔ)句會(huì)鎖定前面的間隙。
這里還值得注意的是,不同的事務(wù)可以在一個(gè)間隙上持有沖突的鎖。
例如,事務(wù)A可以在一個(gè)間隙上持有一個(gè)共享間隙鎖(gap S-lock),而事務(wù)B在同一個(gè)間隙上持有一個(gè)排他間隙鎖(gap X-lock)。允許沖突間隙鎖的原因是,如果一條記錄從一個(gè)索引中被清除,那么記錄上由不同事務(wù)持有的間隙鎖必須被合并。
InnoDB中間隙鎖的唯一目的是防止其他事務(wù)插入間隙。間隙鎖可以共存。一個(gè)事務(wù)取得的間隙鎖并不會(huì)阻止另一個(gè)事務(wù)取得同一間隙上的間隙鎖。共享和獨(dú)占間隔鎖之間沒(méi)有區(qū)別。它們彼此之間不沖突,并且執(zhí)行相同的功能。
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執(zhí)行行級(jí)鎖的方式是這樣的:當(dāng)它搜索或掃描一個(gè)表索引時(shí),它會(huì)在遇到的索引記錄上設(shè)置共享鎖或排他鎖。因此,行級(jí)鎖實(shí)際上是索引記錄鎖。索引記錄上的next-key鎖也會(huì)影響該索引記錄之前的“間隙”。也就是說(shuō),next-key鎖是索引記錄鎖加上索引記錄之前的間隙鎖。如果一個(gè)會(huì)話(huà)在一個(gè)索引中的記錄R上有一個(gè)共享鎖或排他鎖,則另一會(huì)話(huà)無(wú)法按照索引順序在R之前的間隙中插入新的索引記錄。
假設(shè)一個(gè)索引包含值10、11、13和20。該索引可能的next-key鎖覆蓋以下區(qū)間:
(negative infinity, 10] (10, 11] (11, 13] (13, 20] (20, positive infinity)
默認(rèn)情況下,InnoDB使用REPEATABLE READ事務(wù)隔離級(jí)別。在這種情況下,InnoDB使用next-key鎖進(jìn)行搜索和索引掃描,以阻止幻象行。
6. Insert Intention Locks
Insert Intention Locks(譯:插入意向鎖)
插入意向鎖是一種間隙鎖,是由INSERT操作在行插入之前設(shè)置的。這個(gè)鎖表示,如果多個(gè)事務(wù)插入到同一個(gè)索引間隙中,如果它們沒(méi)有插入到這個(gè)間隙中的同一位置,那么它們就不需要等待對(duì)方。假設(shè)有值為4和7的索引記錄。嘗試插入值分別為5和6的獨(dú)立事務(wù),在獲得插入行的排他鎖之前,每個(gè)事務(wù)都用插入意向鎖鎖住4和7之間的間隙,但不會(huì)阻塞彼此,因?yàn)樾惺遣粵_突的。
7. AUTO-INC Locks
AUTO-INC鎖是一種特殊的表級(jí)鎖,由插入到帶有AUTO_INCREMENT列的表中的事務(wù)獲得。在最簡(jiǎn)單的情況下,如果一個(gè)事務(wù)正在向表中插入值,那么任何其他事務(wù)都必須等待自己對(duì)該表的插入,以便由第一個(gè)事務(wù)插入的行接收連續(xù)的主鍵值。
https://dev.mysql.com/doc/refman/5.7/en/innodb-locking.html
以上就是MySQL InnoDB 鎖的相關(guān)總結(jié)的詳細(xì)內(nèi)容,更多關(guān)于MySQL InnoDB 鎖的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
MYSQL拒絕訪(fǎng)問(wèn)報(bào)錯(cuò)not allowed to connect
MYSQL拒絕訪(fǎng)問(wèn)報(bào)錯(cuò)not allowed to connect,下面有個(gè)可行的方法,可以在其它任何的主機(jī)上以root身份登錄2014-07-07
mysql中使用replace替換某字段的部分內(nèi)容
這篇文章主要介紹了mysql中使用replace替換某字段的部分內(nèi)容的方法,需要的朋友可以參考下2014-11-11
MySQL多表聯(lián)查的實(shí)現(xiàn)思路
數(shù)據(jù)庫(kù)應(yīng)用在我們的生活中是很常見(jiàn)的,在編輯一些應(yīng)用以及軟件的時(shí)候都需要用到數(shù)據(jù)庫(kù)來(lái)存儲(chǔ)數(shù)據(jù),下面這篇文章主要給大家介紹了關(guān)于MongoDB中實(shí)現(xiàn)多表聯(lián)查的相關(guān)資料,需要的朋友可以參考下2023-02-02
MySql分頁(yè)時(shí)使用limit+order by會(huì)出現(xiàn)數(shù)據(jù)重復(fù)問(wèn)題解決
在MySQL中我們通常會(huì)采用limit來(lái)進(jìn)行翻頁(yè)查詢(xún),當(dāng)limit遇到 order by的時(shí)候會(huì)出現(xiàn)數(shù)據(jù)重復(fù)問(wèn)題,本文就來(lái)記錄一下,感興趣的可以了解一下2021-08-08
mysql Buffer Pool的存儲(chǔ)結(jié)構(gòu)和內(nèi)存淘汰機(jī)制詳解
這篇文章主要介紹了mysql Buffer Pool的存儲(chǔ)結(jié)構(gòu)和內(nèi)存淘汰機(jī)制詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-03-03
用VirtualBox構(gòu)建MySQL測(cè)試環(huán)境的筆記
這篇文章主要介紹了如何用VirtualBox構(gòu)建MySQL測(cè)試環(huán)境,特分享下,方便需要的朋友2013-08-08

