最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解MySql中InnoDB存儲引擎中的各種鎖

 更新時(shí)間:2022年02月11日 09:36:30   作者:果子爸聊技術(shù)  
本文主要介紹了詳解MySql中InnoDB存儲引擎中的各種鎖,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

什么是鎖

現(xiàn)實(shí)生活中的鎖是為了保護(hù)你的私有物品,在數(shù)據(jù)庫中鎖是為了解決資源爭搶的問題,鎖是數(shù)據(jù)庫系統(tǒng)區(qū)別于文件系統(tǒng)的一個(gè)關(guān)鍵特性。鎖機(jī)制用于管理對共享資源的并發(fā)訪。

數(shù)據(jù)庫系統(tǒng)使用鎖是為了支持對共享資源進(jìn)行并發(fā)訪問,提供數(shù)據(jù)的完整性和一致性

InnoDB存儲引擎區(qū)別于MyISAM的兩個(gè)重要特征就是:InnoDB存儲引擎支持事務(wù)和行級別的鎖,MyISAM只支持表級別的鎖

InnoDB存儲引擎中的鎖

InnoDB存儲引擎實(shí)現(xiàn)了如下兩種標(biāo)準(zhǔn)的行級鎖:

共享鎖(S Lock),允許事務(wù)讀一行數(shù)據(jù)排他鎖(X Lock),允許事務(wù)刪除或更新一行數(shù)據(jù)

鎖的兼容性

-XS
X不兼容不兼容
S不兼容兼容

可以看到,X排他鎖不與其他鎖兼容,S共享鎖只與S兼容

此外,InnoDB存儲引擎支持多粒度(granular)鎖定,這種鎖定允許事務(wù)在行級上的鎖和表級上的鎖同時(shí)存在

為了支持在不同粒度上進(jìn)行加鎖操作,InnoDB存儲引擎支持一種額外的鎖方式,稱之為意向鎖(Intention Lock)。

意向鎖是將鎖定的對象分為多個(gè)層次,意向鎖意味著事務(wù)希望在更細(xì)粒度(fine granularity)上進(jìn)行加鎖

在這里插入圖片描述

如上圖,數(shù)據(jù)庫從上到下可以分為數(shù)據(jù)庫、表、頁、記錄四個(gè)層次,行記錄是最細(xì)粒度的鎖,我們在獲取行鎖的時(shí)候,需要從上到下各個(gè)級別分別進(jìn)行鎖定,最后才能獲取到行鎖。比如,你要獲取行記錄x的鎖,需要先在數(shù)據(jù)庫、表、頁上加意向鎖IX,其中任何一方需要等待鎖,會造成行鎖的等待

InnoDB存儲引擎支持的意向鎖即為表級別的鎖。支持兩種意向鎖

  • 意向共享鎖(IS Lock),事務(wù)想要獲得一張表中某幾行的共享鎖
  • 意向排他鎖(IX Lock),事務(wù)想要獲得一張表中某幾行的排他鎖

由于InnoDB存儲引擎支持的是行級別的鎖,因此意向鎖其實(shí)不會阻塞除全表掃以外的任何請求。故表級意向鎖與行級鎖的兼容性如表所示

-ISIXSX
IS兼容兼容兼容不兼容
IX兼容兼容不兼容不兼容
S兼容不兼容兼容不兼容
X不兼容不兼容不兼容不兼容

一致性非鎖定讀

一致性的非鎖定讀(consistent nonlocking read)是指InnoDB存儲引擎通過行多版本控制(multi versioning)的方式來讀取當(dāng)前執(zhí)行時(shí)間數(shù)據(jù)庫中行的數(shù)據(jù)。

如果讀取的行正在執(zhí)行DELETE或UPDATE操作,這時(shí)讀取操作不會因此去等待行上鎖的釋放。

相反地,InnoDB存儲引擎會去讀取行的一個(gè)快照數(shù)據(jù)

快照數(shù)據(jù)是指該行的之前版本的數(shù)據(jù),該實(shí)現(xiàn)是通過undo段來完成。而undo用來在事務(wù)中回滾數(shù)據(jù),因此快照數(shù)據(jù)本身是沒有額外的開銷。此外,讀取快照數(shù)據(jù)是不需要上鎖的,因?yàn)闆]有事務(wù)需要對歷史的數(shù)據(jù)進(jìn)行修改操作

在這里插入圖片描述

快照數(shù)據(jù)其實(shí)就是當(dāng)前行數(shù)據(jù)之前的歷史版本,每行記錄可能有多個(gè)版本。如上圖,記錄B就有多個(gè)歷史的快照版本
這就是大名鼎鼎的MVCC

多版本并發(fā)控制(Multi Version Concurrency Control,MVCC)是指一個(gè)行記錄有多個(gè)快照版本,由多個(gè)快照版本引發(fā)的并發(fā)控制,叫做多版本并發(fā)控制

那這么多歷史的快速版本,訪問的時(shí)候該用哪一個(gè)呢?

  • 在READ COMMITTED事務(wù)隔離級別下,非一致性讀總是讀取被鎖定行的最新一份快照數(shù)據(jù)
  • 在REPEATABLE READ事務(wù)隔離級別下,非一致性讀總是讀取事務(wù)開始時(shí)的行數(shù)據(jù)版本

由此可見,不同的事務(wù)隔離級別在MVCC的處理上還不一樣

一致性鎖定讀

在默認(rèn)配置下,即事務(wù)的隔離級別為REPEATABLE READ模式下,InnoDB存儲引擎的SELECT操作使用一致性非鎖定讀

但是在某些情況下,用戶需要顯式地對數(shù)據(jù)庫讀取操作進(jìn)行加鎖以保證數(shù)據(jù)邏輯的一致性

InnoDB存儲引擎對于SELECT語句支持兩種一致性的鎖定讀(locking read)操作:

  • SELECT…FOR UPDATE 對讀取的行記錄加一個(gè)X鎖,其他事務(wù)不能對已鎖定的行加上任何鎖
  • SELECT…LOCK IN SHARE MODE對讀取的行記錄加一個(gè)S鎖,其他事務(wù)可以向被鎖定的行加S鎖,但是如果加X鎖,則會被阻塞

對于一致性非鎖定讀,即使讀取的行已被執(zhí)行了SELECT…FOR UPDATE,也是可以進(jìn)行讀取的

一致性鎖定讀則需要檢查被讀取的行上有沒有互斥的鎖,假如有互斥的鎖存在就需要等待鎖的釋放

鎖的算法

行鎖的3種算法

  • Record Lock:單個(gè)行記錄上的鎖
  • Gap Lock:間隙鎖,鎖定一個(gè)范圍,但不包含記錄本身
  • Next-Key Lock∶Gap Lock+Record Lock,鎖定一個(gè)范圍,并且鎖定記錄本身

Record Lock總是會去鎖住索引記錄,如果InnoDB存儲引擎表在建立的時(shí)候沒有設(shè)置任何一個(gè)索引,那么這時(shí)InnoDB存儲引擎會使用隱式的主鍵來進(jìn)行鎖定

Gap Lock的作用是為了阻止多個(gè)事務(wù)將記錄插入到同一范圍內(nèi),而這會導(dǎo)致幻讀問題的產(chǎn)生

用戶可以通過以下兩種方式來顯式地關(guān)閉Gap Lock:

  • 將事務(wù)的隔離級別設(shè)置為READ COMMITTED
  • 將參數(shù)innodb_locks_unsafe_for_binlog設(shè)置為1

在上述的配置下,除了外鍵約束和唯一性檢查依然需要的Gap Lock,其余情況僅使用RecordLock進(jìn)行鎖定。

但需要牢記的是,上述設(shè)置破壞了事務(wù)的隔離性,并且對于replication,可能會導(dǎo)致主從數(shù)據(jù)的不一致。

Next-Key Lock是結(jié)合了Gap Lock和Record Lock的一種鎖定算法,在Next-Key Lock算法下,InnoDB對于行的查詢都是采用這種鎖定算法

當(dāng)查詢的索引含有唯一屬性時(shí),InnoDB存儲引擎會對Next-Key Lock進(jìn)行優(yōu)化,將其降級為Record Lock,即僅鎖住索引本身,而不是范圍

幻像問題

幻像問題(Phantom Problem)是指在同一事務(wù)下,連續(xù)執(zhí)行兩次同樣的SQL語句可能導(dǎo)致不同的結(jié)果,第二次的SQL語句可能會返回之前不存在的行

看下面的場景:

  • 表t由1、2、5這三個(gè)值組成
  • 執(zhí)行select * from t where a > 2 for update;
  • 上述事務(wù)T1并沒有提交,那么此時(shí)另一個(gè)事務(wù)T2插入4這個(gè)值,并且數(shù)據(jù)庫允許這個(gè)操作
  • 那么事務(wù)T1再執(zhí)行上述查詢,就得到4、5兩筆記錄,跟第一次得到的結(jié)果不一樣,違反了事務(wù)的隔離性

InnoDB存儲引擎采用Next-Key Locking的算法避免幻像問題。對于上述的SQL語句select * from t where a > 2 for update,其鎖住的不是5這單個(gè)值,而是對(2,+∞)這個(gè)范圍加了X鎖。因此任何對于這個(gè)范圍的插入都是不被允許的,從而避免幻像問題

InnoDB存儲引擎默認(rèn)的事務(wù)隔離級別是REPEATABLE READ,在該隔離級別下,其采用Next-Key Locking的方式來加鎖

而在事務(wù)隔離級別READ COMMITTED下,其僅采用RecordLock行鎖

鎖的問題

臟讀

臟讀指的就是在不同的事務(wù)下,當(dāng)前事務(wù)可以讀到另外事務(wù)未提交的數(shù)據(jù),簡單來說就是可以讀到臟數(shù)據(jù)

臟讀發(fā)生的條件是需要事務(wù)的隔離級別為READ UNCOMMITTED,而目前絕大部分的數(shù)據(jù)庫都至少設(shè)置成READCOMMITTED。

InnoDB存儲引擎默認(rèn)的事務(wù)隔離級別為READ REPEATABLE,Microsoft SQLServer數(shù)據(jù)庫為READ COMMITTED,Oracle數(shù)據(jù)庫同樣也是READ COMMITTED

不可重復(fù)讀

不可重復(fù)讀是指在一個(gè)事務(wù)內(nèi)多次讀取同一數(shù)據(jù)集合。在這個(gè)事務(wù)還沒有結(jié)束時(shí),另外一個(gè)事務(wù)也訪問該同一數(shù)據(jù)集合,并做了一些DML操作。因此,在第一個(gè)事務(wù)中的兩次讀數(shù)據(jù)之間,由于第二個(gè)事務(wù)的修改,那么第一個(gè)事務(wù)兩次讀到的數(shù)據(jù)可能是不一樣的。這樣就發(fā)生了在一個(gè)事務(wù)內(nèi)兩次讀到的數(shù)據(jù)是不一樣的情況,這種情況稱為不可重復(fù)讀

不可重復(fù)讀和臟讀的區(qū)別是:臟讀是讀到未提交的數(shù)據(jù),而不可重復(fù)讀讀到的卻是已經(jīng)提交的數(shù)據(jù),但是其違反了數(shù)據(jù)庫事務(wù)一致性的要求

一般來說,不可重復(fù)讀的問題是可以接受的,因?yàn)槠渥x到的是已經(jīng)提交的數(shù)據(jù),本身并不會帶來很大的問題。因此,很多數(shù)據(jù)庫廠商(如Oracle、Microsoft SQL Server)將其數(shù)據(jù)庫事務(wù)的默認(rèn)隔離級別設(shè)置為READ COMMITTED,在這種隔離級別下允許不可重復(fù)讀的現(xiàn)象

在InnoDB存儲引擎中,通過使用Next-Key Lock算法來避免不可重復(fù)讀的問題。

在MySQL官方文檔中將不可重復(fù)讀的問題定義為Phantom Problem,即幻像問題。在Next-Key Lock算法下,對于索引的掃描,不僅是鎖住掃描到的索引,而且還鎖住這些索引覆蓋的范圍(gap)。

因此在這個(gè)范圍內(nèi)的插入都是不允許的。這樣就避免了另外的事務(wù)在這個(gè)范圍內(nèi)插入數(shù)據(jù)導(dǎo)致的不可重復(fù)讀的問題。因此,InnoDB存儲引擎的默認(rèn)事務(wù)隔離級別是READ REPEATABLE,采用Next-Key Lock算法,避免了不可重復(fù)讀的現(xiàn)象

丟失更新

丟失更新是另一個(gè)鎖導(dǎo)致的問題,簡單來說其就是一個(gè)事務(wù)的更新操作會被另一個(gè)事務(wù)的更新操作所覆蓋,從而導(dǎo)致數(shù)據(jù)的不一致

  • 事務(wù)T1將行記錄r更新為v1,但是事務(wù)T1并未提交
  • 與此同時(shí),事務(wù)T2將行記錄r更新為v2,事務(wù)T2未提交
  • 事務(wù)T1提交
  • 事務(wù)T2提交

在當(dāng)前數(shù)據(jù)庫的任何隔離級別下,都不會導(dǎo)致數(shù)據(jù)庫理論意義上的丟失更新問題。這是因?yàn)?,即使是READ UNCOMMITTED的事務(wù)隔離級別,對于行的DML操作,需要對行或其他粗粒度級別的對象加鎖

死鎖

死鎖是指兩個(gè)或兩個(gè)以上的事務(wù)在執(zhí)行過程中,因爭奪鎖資源而造成的一種互相等待的現(xiàn)象

解決死鎖問題最簡單的一種方法是超時(shí),即當(dāng)兩個(gè)事務(wù)互相等待時(shí),當(dāng)一個(gè)等待時(shí)間超過設(shè)置的某一閾值時(shí),其中一個(gè)事務(wù)進(jìn)行回滾,另一個(gè)等待的事務(wù)就能繼續(xù)進(jìn)行。在InnoDB存儲引擎中,參數(shù)innodb_lock_wait_timeout用來設(shè)置超時(shí)的時(shí)間

超時(shí)機(jī)制雖然簡單,但是其僅通過超時(shí)后對事務(wù)進(jìn)行回滾的方式來處理,或者說其是根據(jù)FIFO的順序選擇回滾對象。但若超時(shí)的事務(wù)所占權(quán)重比較大,如事務(wù)操作更新了很多行,占用了較多的undo log,這時(shí)采用FIFO的方式,就顯得不合適了,因?yàn)榛貪L這個(gè)事務(wù)的時(shí)間相對另一個(gè)事務(wù)所占用的時(shí)間可能會很多

因此,除了超時(shí)機(jī)制,當(dāng)前數(shù)據(jù)庫還都普遍采用wait-for graph(等待圖)的方式來進(jìn)行死鎖檢測。

較之超時(shí)的解決方案,這是一種更為主動(dòng)的死鎖檢測方式。InnoDB存儲引擎也采用的這種方式。

wait-for graph要求數(shù)據(jù)庫保存以下兩種信息

  • 鎖的信息鏈表
  • 事務(wù)等待鏈表

wait-for graph的死鎖檢測通常采用深度優(yōu)先的算法實(shí)現(xiàn),通常來說InnoDB存儲引擎選擇回滾undo量最小的事務(wù)

到此這篇關(guān)于詳解MySql中InnoDB存儲引擎中的各種鎖的文章就介紹到這了,更多相關(guān)詳解MySql中InnoDB存儲引擎中的各種鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MySQL 自動(dòng)清理binlog日志的方法

    MySQL 自動(dòng)清理binlog日志的方法

    這篇文章主要介紹了MySQL 自動(dòng)清理binlog日志的方法,需要的朋友可以參考下
    2016-10-10
  • MySQL系列之十一 日志記錄

    MySQL系列之十一 日志記錄

    這篇文章主要介紹了MySQL日志文件詳解,本文分別講解了錯(cuò)誤日志、二進(jìn)制日志、通用查詢?nèi)罩尽⒙樵內(nèi)罩?、Innodb的在線redo日志、更新日志等日志類型和作用介紹,需要的朋友可以參考下
    2021-07-07
  • MySQL索引優(yōu)化之不適合構(gòu)建索引及索引失效的幾種情況詳解

    MySQL索引優(yōu)化之不適合構(gòu)建索引及索引失效的幾種情況詳解

    索引是有雙面性的,合理的建立索引可以提高數(shù)據(jù)庫的效率。但是如果沒有合理的構(gòu)建索引和使用索引,可能會導(dǎo)致索引失效或者影響數(shù)據(jù)庫性能,本文主要討論的是索引失效以及不適合建立索引的場景
    2022-07-07
  • Mysql超時(shí)配置項(xiàng)的深入理解

    Mysql超時(shí)配置項(xiàng)的深入理解

    超時(shí)是我們?nèi)粘=?jīng)常會遇到的一個(gè)問題,這篇文章主要給大家介紹了關(guān)于Mysql超時(shí)配置項(xiàng)的深入理解,內(nèi)容簡明扼要并且容易理解,絕對能使你眼前一亮,需要的朋友可以參考下
    2023-01-01
  • 全面解析MySQL常見問題的排查與解決方法

    全面解析MySQL常見問題的排查與解決方法

    MySQL 是一款常用的關(guān)系型數(shù)據(jù)庫管理系統(tǒng),廣泛應(yīng)用于各類應(yīng)用開發(fā)和數(shù)據(jù)管理場景,然而,在實(shí)際使用中,MySQL 有時(shí)會遇到啟動(dòng)失敗、服務(wù)中斷或性能問題等情況,所以本文給大家介紹了MySQL常見問題的排查與解決方法,需要的朋友可以參考下
    2024-11-11
  • 輕松解決MySQL忘記密碼如何重置的方法

    輕松解決MySQL忘記密碼如何重置的方法

    這篇文章主要為大家介紹了MySQL忘記密碼如何重置的方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • mysql字段名和關(guān)鍵字沖突的問題

    mysql字段名和關(guān)鍵字沖突的問題

    這篇文章主要介紹了mysql字段名和關(guān)鍵字沖突的問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • MySQL多表聯(lián)查的實(shí)現(xiàn)思路

    MySQL多表聯(lián)查的實(shí)現(xiàn)思路

    數(shù)據(jù)庫應(yīng)用在我們的生活中是很常見的,在編輯一些應(yīng)用以及軟件的時(shí)候都需要用到數(shù)據(jù)庫來存儲數(shù)據(jù),下面這篇文章主要給大家介紹了關(guān)于MongoDB中實(shí)現(xiàn)多表聯(lián)查的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • MySQL5.7.21安裝與密碼圖文配置教程

    MySQL5.7.21安裝與密碼圖文配置教程

    這篇文章主要為大家詳細(xì)介紹了MySQL5.7.21安裝與密碼圖文配置教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • MySQL Explain使用詳解

    MySQL Explain使用詳解

    這篇文章主要介紹了MySQL Explain使用詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12

最新評論

中江县| 西青区| 嘉定区| 会泽县| 绍兴县| 黎平县| 望谟县| 琼海市| 广东省| 邢台市| 龙里县| 江源县| 绥阳县| 永康市| 徐州市| 改则县| 从化市| 乐都县| 休宁县| 双桥区| 阿拉尔市| 大兴区| 綦江县| 子长县| 双城市| 夏津县| 云浮市| 毕节市| 海丰县| 京山县| 新干县| 黄浦区| 英德市| 祁东县| 沁阳市| 湘潭市| 长岛县| 珲春市| 普陀区| 教育| 全州县|