[譯] MySQL InnoDB 鎖類型介紹

原文地址:https://docs.oracle.com/cd/E17952_01/mysql-5.5-en/innodb-locking.html

本節(jié)介紹 InnoDB 的鎖類型:

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

InnoDB 實現(xiàn)了標準的行級鎖,分為兩種類型:共享(S)鎖排他(X)鎖

如果事務T1在行 r 上持有共享(S)鎖,則其他事務T2對行 r 的鎖的請求按如下方式處理:

  • 可以立即授予T2對S鎖的請求。 結果,T1和T2都在r上持有S鎖。
  • T2的X鎖定請求不能立即授予。

如果事務T1在行r上持有排他(X)鎖,則不能立即授予其他事務T2對r上任何類型的鎖請求。相反,T2必須等待T1釋放其對行r的鎖定。

意向鎖(Intention Locks)

InnoDB支持多種粒度的鎖,允許行鎖和表鎖共存。 例如 LOCK TABLES ... WRITE
等語句在指定的表上持有排他鎖(X 鎖)。 InnoDB用意向鎖來實現(xiàn)多粒度級別的鎖。意向鎖是表級鎖,表示事務稍后對表中的行進行加相關類型的鎖(共享或排他)。意向鎖有兩種類型:

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

意向鎖的規(guī)則如下:

  • 事務在獲取表中某行的共享鎖之前,必須先獲取表上的 IS 鎖或類似的鎖。
  • 事務在獲取表中某行的排他鎖之前,必須先獲取表上的 IX 鎖。

下面是表級鎖類型兼容性總結:

當前事務現(xiàn)有的鎖 / 其他事務的鎖請求 X IX S IS
X 沖突 沖突 沖突 沖突
IX 沖突 兼容 沖突 兼容
S 沖突 沖突 兼容 兼容
IS 沖突 兼容 兼容 兼容

如果事務請求的鎖與現(xiàn)有鎖兼容就授予鎖,如果沖突則不會。 事務會一直等到現(xiàn)有的鎖釋放。如果因為事務請求的鎖與現(xiàn)有的鎖沖突而無法授予,則可能會導致發(fā)生死鎖(deadlock)錯誤。
除全表請求之外,意向鎖不會阻塞任何事務(例如 LOCK TABLES ... WRITE)。意向鎖的主要目的是表示某人正在鎖定行,或將要鎖定表中的行。
意向鎖的事務數據與 SHOW ENGINE INNODB STATUSInnoDB monitor 輸出中的以下內容類似:

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

記錄鎖(Record Locks)

記錄鎖是對索引記錄的鎖定。 例如,SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE; 防止任何其他事務插入,更新或刪除 t.c1 的值為 10 的行。

即使表沒有定義索引,記錄鎖也能鎖定索引記錄。因為 InnoDB創(chuàng)建了一個隱藏的聚簇索引并使用此索引做記錄鎖。 請參見 第14.11.2.1節(jié)“聚簇和二級索引”

記錄鎖的事務數據在SHOW ENGINE INNODB STATUS和InnoDB監(jiān)視器輸出中顯示類似于以下內容:

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        ;;

區(qū)間鎖 / 間隙鎖(Gap Locks)

區(qū)間鎖是鎖定索引記錄之間的區(qū)間,或鎖定在第一個或最后一個索引記錄之前的區(qū)間上。 例如,SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE; 阻止其他事務將值15插入到列 t.c1 中,無論列中是否存在任何此類值,因為該范圍內所有現(xiàn)有值之間的區(qū)間都被鎖定。

區(qū)間可能跨越單個索引值,多個索引值,甚至可能為空。
區(qū)間鎖是性能和并發(fā)之間權衡的一部分,用于某些事務隔離級別而不是其他級別。

使用唯一索引(unique index )鎖定行以搜索唯一行的語句不需要區(qū)間鎖。(這不包括搜索條件僅包括多列唯一索引的一些列的情況; 在這種情況下,確實會發(fā)生區(qū)間鎖定。)例如,如果id列具有唯一索引,則以下語句僅對id值為100的行使用索引記錄鎖,并且其他會話是否在前一個間隙中插入行無關緊要:

SELECT * FROM child WHERE id = 100;

如果id未編入索引或具有非唯一索引,則該語句會鎖定前一個區(qū)間。

這里還值得注意的是,不同的事務在相同區(qū)間上可以存在相互沖突的鎖類型。 例如,事務A可以在區(qū)間上持有共享區(qū)間鎖(區(qū)間S鎖),而事務B在同一區(qū)間上持有排他區(qū)間鎖(區(qū)間X鎖)。 允許區(qū)間鎖沖突的原因是,如果從索引中清除記錄,則必須合并由不同事務保留在記錄上的區(qū)間鎖。

在InnoDB中區(qū)間鎖被“抑制”了,這意味著它們的唯一目的是防止其他事務插入區(qū)間。區(qū)間鎖可以共存。一個事務占用的區(qū)間鎖定不會阻止另一個事務在同一個區(qū)間上進行區(qū)間鎖定。 共享和排他區(qū)間鎖之間沒有區(qū)別。它們彼此不沖突,它們執(zhí)行相同的功能。

如果將事務隔離級別更改為READ COMMITTED或啟用系統(tǒng)變量innodb_locks_unsafe_for_binlog,就可以明確禁用區(qū)間鎖。此時,搜索和索引掃描會禁用區(qū)間鎖定,只能用于外鍵約束檢查和重復鍵檢查。

使用 READ COMMITTED 隔離級別或啟用 innodb_locks_unsafe_for_binlog 還有其他影響。 MySQL評估 WHERE 條件后,將釋放非匹配行的記錄鎖。對于UPDATE 語句,InnoDB 執(zhí)行“半一致(semi-consistent)”讀取,以便將最新提交的版本返回給MySQL,以便MySQL可以確定該行是否與 UPDATEWHERE 條件匹配。

Next-Key Locks

Next-Key鎖是索引記錄上的記錄鎖和索引記錄之前的區(qū)間上的區(qū)間鎖的組合。

InnoDB用以下方式執(zhí)行行級鎖定:當它搜索或掃描表索引時,它會在遇到的索引記錄上設置共享鎖或排它鎖。 因此,行級鎖實際上是索引記錄鎖。索引記錄上的Next-Key鎖也會影響該索引記錄之前的“區(qū)間”。也就是說,Next-Key鎖是索引記錄鎖加上索引記錄之前的區(qū)間上的區(qū)間鎖。如果一個會話在索引記錄R上具有共享鎖或排他鎖,則另一個會話不能在索引順序中的R之前的區(qū)間中插入新的索引記錄。

假設索引包含值10,11,13和20。此索引的可能的Next-Key鎖定包括以下間隔,其中圓括號表示排除區(qū)間端點,方括號表示包含端點:

(-∞, 10]
(10, 11]
(11, 13]
(13, 20]
(20, +∞)

對于最后一個區(qū)間,Next-Key 鎖將區(qū)間鎖定在索引中最大值之上,而“supremum”偽記錄的值高于索引中實際的任何值。supremum不是真正的索引記錄,因此,實際上,此Next-Key鎖僅鎖定最大索引值之后的間隙。

默認情況下,InnoDB 在 REPEATABLE READ (RR) 事務隔離級別運行,并禁用系統(tǒng)變量innodb_locks_unsafe_for_binlog 。在這種情況下,InnoDB 使用 Next-Key 鎖進行搜索和索引掃描,從而防止幻像行(參見 Section 14.8.4, “Phantom Rows”)。

Next-Key 鎖的事務數據與 SHOW ENGINE INNODB STATUSInnoDB監(jiān)視器 輸出中的以下內容類似:

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

待翻譯

AUTO-INC Locks

AUTO-INC 鎖是由插入到具有 AUTO_INCREMENT 列的表中的事務所采用的特殊表級鎖。在最簡單的情況下,如果一個事務正在向表中插入值,則任何其他事務必須等待對該表執(zhí)行自己的插入,以便第一個事務插入的行接收連續(xù)的主鍵值。

可以通過配置項 innodb_autoinc_lock_mode 調整自增鎖算法,例如:調整自增序列和插入操作的最大并發(fā)。

請參見:Section 14.11.1.5, “AUTO_INCREMENT Handling in InnoDB”.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,247評論 6 543
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,520評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,362評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,805評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,541評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,896評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,887評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,062評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 49,608評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,356評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,555評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,077評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,769評論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,175評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,489評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,289評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,516評論 2 379

推薦閱讀更多精彩內容

  • Mysql概述 數據庫是一個易于訪問和修改的信息集合。它允許使用事務來確保數據的安全性和一致性,并能快速處理百萬條...
    彥幀閱讀 13,700評論 10 460
  • MySQL技術內幕:InnoDB存儲引擎(第2版) 姜承堯 第1章 MySQL體系結構和存儲引擎 >> 在上述例子...
    沉默劍士閱讀 7,454評論 0 16
  • 一、概述 數據庫鎖定機制簡單來說,就是數據庫為了保證數據的一致性,而使各種共享資源在被并發(fā)訪問變得有序所設計的一種...
    忘憂谷主閱讀 602評論 0 3
  • 當一個系統(tǒng)訪問量上來的時候,不只是數據庫性能瓶頸問題了,數據庫數據安全也會浮現(xiàn),這時候合理使用數據庫鎖機制就顯得異...
    初來的雨天閱讀 3,592評論 0 22
  • 有的人生是永遠掙不脫的枷鎖 有的人生是永遠滅不了的火種 有些人的生活似霜敲打著枯茄 有些人的生活似光指引著心靈 他...
    流年飄雪閱讀 296評論 1 4