MySQL間隙鎖、Next-Key Lock主要知識點(diǎn)

總體來說,就是MySQL innoDB引擎要在RR隔離級別之下解決幻讀的問題,所以引入了間隙鎖。

在進(jìn)行當(dāng)前讀的情況下,對讀出的數(shù)據(jù)的附近的一整個(gè)范圍(“間隙”)進(jìn)行加鎖,保證滿足查詢條件的記錄不能被插入。

1、幻讀與innoDB的隔離級別(為什么會出現(xiàn)間隙鎖這個(gè)概念)

根據(jù) ISO/ANSI SQL92 所定義的標(biāo)準(zhǔn),四級隔離級別中,只有在可串行化的級別之下,才可以防止幻讀的出現(xiàn)。

隔離級別

所謂幻讀,指的是事務(wù)A執(zhí)行過程中,由于事務(wù)B并發(fā)插入了一條新數(shù)據(jù),事務(wù)A兩次讀數(shù)據(jù)的內(nèi)容不一樣,出現(xiàn)了“虛幻”的新紀(jì)錄(phantom,幽靈)。

但實(shí)際上各廠商的數(shù)據(jù)庫產(chǎn)品并沒有嚴(yán)格遵守SQL92標(biāo)準(zhǔn),比如Oracle只有 RC 和 Serializable 兩級隔離級別。

MySQL的innoDB引擎雖然擁有標(biāo)準(zhǔn)的四級隔離級別(其實(shí)也是MVCC等手段模擬出來的),不過它有一點(diǎn)顯著的不同,就是在 RR 級別下面已經(jīng)可以防止幻讀的發(fā)生。

  • 在快照讀(snapshot read)的情況下,MySQL通過MVCC(多版本并發(fā)控制)來避免幻讀。

    快照讀,讀取的是記錄的可見版本 (有可能是歷史版本),不用加鎖。主要應(yīng)用于無需加鎖的普通查詢(select)操作。

  • 在當(dāng)前讀(current read)的情況下,MySQL通過next-key lock來避免幻讀。

    當(dāng)前讀,讀取的是記錄的最新版本,并且會對當(dāng)前記錄加鎖,防止其他事務(wù)發(fā)修改這條記錄。加行共享鎖(SELECT ... LOCK IN SHARE MODE )、加行排他鎖(SELECT ... FOR UPDATE / INSERT / UPDATE / DELETE)的操作都會用到當(dāng)前度。行鎖可參看 MySQL行鎖。

下面主要說明跟間隙鎖相關(guān)的當(dāng)前讀。

2、innoDB的間隙鎖/Next-Key Lock

2-1、明確前提條件
  • innoDB的間隙鎖只存在于 RR 隔離級別

所以希望禁用間隙鎖,提升系統(tǒng)性能的時(shí)候,可以考慮將隔離級別降為 RC。

2-2、間隙鎖/Next-Key Lock

間隙鎖在innoDB中的唯一作用就是在一定的“間隙”內(nèi)防止其他事務(wù)的插入操作,以此防止幻讀的發(fā)生:

  • 防止間隙內(nèi)有新數(shù)據(jù)被插入。
  • 防止已存在的數(shù)據(jù),更新成間隙內(nèi)的數(shù)據(jù)。

innoDB支持三種行鎖定方式:

  • 行鎖(Record Lock):鎖直接加在索引記錄上面(無索引項(xiàng)時(shí)演變成表鎖)。

  • 間隙鎖(Gap Lock):鎖定索引記錄間隙,確保索引記錄的間隙不變。間隙鎖是針對事務(wù)隔離級別為可重復(fù)讀或以上級別的。

  • Next-Key Lock :行鎖和間隙鎖組合起來就是 Next-Key Lock。

innoDB默認(rèn)的隔離級別是可重復(fù)讀(Repeatable Read),并且會以Next-Key Lock的方式對數(shù)據(jù)行進(jìn)行加鎖。Next-Key Lock是行鎖和間隙鎖的組合,當(dāng)InnoDB掃描索引記錄的時(shí)候,會首先對索引記錄加上行鎖(Record Lock),再對索引記錄兩邊的間隙加上間隙鎖(Gap Lock)。加上間隙鎖之后,其他事務(wù)就不能在這個(gè)間隙修改或者插入記錄。

當(dāng)查詢的索引含有唯一屬性(唯一索引,主鍵索引)時(shí),Innodb存儲引擎會對next-key lock進(jìn)行優(yōu)化,將其降為record lock,即僅鎖住索引本身,而不是范圍。

2-3、何時(shí)使用行鎖,何時(shí)產(chǎn)生間隙鎖

對上一節(jié)的最后一句做個(gè)擴(kuò)展說明。

  1. 只使用唯一索引查詢,并且只鎖定一條記錄時(shí),innoDB會使用行鎖。
  2. 只使用唯一索引查詢,但是檢索條件是范圍檢索,或者是唯一檢索然而檢索結(jié)果不存在(試圖鎖住不存在的數(shù)據(jù))時(shí),會產(chǎn)生 Next-Key Lock。
  3. 使用普通索引檢索時(shí),不管是何種查詢,只要加鎖,都會產(chǎn)生間隙鎖。
  4. 同時(shí)使用唯一索引和普通索引時(shí),由于數(shù)據(jù)行是優(yōu)先根據(jù)普通索引排序,再根據(jù)唯一索引排序,所以也會產(chǎn)生間隙鎖。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 1. mysql鎖知多少 我們進(jìn)行insert,update,delete,select會加鎖嗎,如果加鎖,加鎖步...
    liwsh閱讀 5,036評論 0 4
  • 一、概述 數(shù)據(jù)庫鎖定機(jī)制簡單來說,就是數(shù)據(jù)庫為了保證數(shù)據(jù)的一致性,而使各種共享資源在被并發(fā)訪問變得有序所設(shè)計(jì)的一種...
    不變甄心閱讀 2,743評論 0 3
  • 有時(shí)候,放下自己曾經(jīng)傾盡心血的人,或者事,不是很容易!就像自己含辛茹苦養(yǎng)大的孩子突然夭折一般!抑或像自己努力培養(yǎng)的...
    angel妖姐閱讀 344評論 0 0
  • [ 轉(zhuǎn)自 ]基于區(qū)塊鏈的智能合約安全(二)——已知的漏洞和陷阱博客新地址 私鑰泄露 使用不安全的私鑰確實(shí)是一個(gè)常見...
    CapybaraJ閱讀 1,435評論 0 0