輕松掌握Mysql的InnoDB存儲引擎中的鎖

本文主要給大家介紹MySQL的InnoDB存儲引擎中的鎖,文章內(nèi)容都是筆者用心摘選和編輯的,具有一定的針對性,對大家的參考意義還是比較大的,下面跟筆者一起了解下Mysql的InnoDB存儲引擎中的鎖吧。 

10年積累的網(wǎng)站設(shè)計(jì)制作、網(wǎng)站制作經(jīng)驗(yàn),可以快速應(yīng)對客戶對網(wǎng)站的新想法和需求。提供各種問題對應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識你,你也不認(rèn)識我。但先網(wǎng)站設(shè)計(jì)后付款的網(wǎng)站建設(shè)流程,更有宜豐免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

這里鎖的對象是事務(wù),用來鎖定數(shù)據(jù)庫中的對象,如:表、頁、行。并且一般鎖的對象僅在事務(wù)commit或rollback后進(jìn)行釋放。并且有死鎖機(jī)制。

下面我們看InnoDB存儲引擎中兩種標(biāo)準(zhǔn)的行級鎖:

  • 共享鎖(S Lock),允許事務(wù)讀一行數(shù)據(jù)

  • 排它鎖(X Lock),允許事務(wù)刪除或更新一行數(shù)據(jù)

若事務(wù)T對數(shù)據(jù)對象A加上S鎖,則事務(wù)T可以讀A但不能修改A,其他事務(wù)只能再對A加S鎖,而不能加X鎖,直到T釋放A上的S鎖。這保證了其他事務(wù)可以讀A,但在T釋放A上的S鎖之前不能對A做任何修改。

若事務(wù)T對數(shù)據(jù)對象A加上X鎖,事務(wù)T可以讀A也可以修改A,其他事務(wù)不能再對A加任何鎖,直到T釋放A上的鎖。

上述情況稱為鎖不兼容。

此外,InnoDB存儲引擎還支持多粒度鎖定,這種鎖定允許事務(wù)在行級上的鎖和表級上的鎖同時(shí)存在。為了支持在不同粒度上進(jìn)行加鎖操作,InnoDB存儲引擎支持一種額外的鎖方式,稱之為意向鎖。

所謂意向鎖,就是將要鎖定的對象分成多個(gè)層次,意向鎖意味著事務(wù)希望在更細(xì)粒度上進(jìn)行加鎖。如果把上鎖的對象看成樹形結(jié)構(gòu)(從根到葉為從粗粒度到細(xì)粒度的順序),那么對最下層的對象上鎖,必須先對他的上層節(jié)點(diǎn)上鎖。

舉個(gè)例子,比如事務(wù)T要對某一行R1加X鎖,必須先對R1所在的表T1加意向鎖IX(Intention X Lock)。相應(yīng)的也有IS(Intetion S Lock)鎖。

剛開始我也是很懵的,不知道引入意向鎖到底是干嘛的。后來再刷書的時(shí)候,才豁然開朗。下面我談下我的理解。

因?yàn)橐胍庀蜴i是用來實(shí)現(xiàn)多粒度鎖定的,即行鎖和表鎖同時(shí)存在。我們看看如果不引入意向鎖,怎么判斷。

如果事務(wù)T要對表T1加X鎖,那么這是就必須要判斷T1表下的每一行記錄是否加了S鎖或X鎖(因?yàn)樯厦嫣岬搅随i有不兼容性)。這樣做效率無疑很低。那么引入意向鎖之后呢?

如果事務(wù)T要對表T1加X鎖,在這之前,已經(jīng)有事務(wù)對表T1中的行記錄R加了S鎖,那么此時(shí)在表T1上有IS鎖,當(dāng)事務(wù)T對表T1準(zhǔn)備加X鎖時(shí),由于X鎖與IS鎖不兼容(關(guān)于兼容性后面會給出表格),所以事務(wù)T要等待行鎖操作完成。你看,這樣就省去了遍歷的操作,提升了鎖定父節(jié)點(diǎn)(本例為表T1)的效率。

下圖就是X、S、IX、IS鎖的兼容性了:

輕松掌握Mysql的InnoDB存儲引擎中的鎖

二、鎖的算法

InnoDB存儲引擎有3種行鎖的算法,分別是:

  • Record Lock:單個(gè)行記錄上的鎖

  • Gap Lock:間隙鎖,鎖定一個(gè)范圍,但不包含記錄本身

  • Next-Key Lock:Gap Lock+Record Lock,鎖定一個(gè)范圍,并且鎖定記錄本身。

舉例說明:
假如一個(gè)索引有10,11,13,20這四個(gè)值。那么該索引可能被Next-Key Locking的區(qū)間為:
(-∞,10]
(10,11]
(11,13]
(13,20]
(20,+∞)


對于Next_Key Lock,如果我們鎖定了一個(gè)行,且查詢的索引含有唯一屬性時(shí)(即有唯一索引),那么這個(gè)時(shí)候InnoDB會將Next_Key Lock優(yōu)化成Record Lock,也就是鎖定當(dāng)前行,而不是鎖定當(dāng)前行加一個(gè)范圍;如果我們使用的不是唯一索引鎖定一行數(shù)據(jù),那么此時(shí)InnoDB就會按照本來的規(guī)則鎖定一個(gè)范圍和記錄。還有需要注意的點(diǎn)是,當(dāng)唯一索引由多個(gè)列組成時(shí),如果查詢僅是查找其中的一個(gè)列,這時(shí)候是不會降級的。還有注意的點(diǎn)是,InnoDB存儲引擎還會對輔助索引的下一個(gè)鍵值區(qū)間加上gap lock(這么做也是為了防止幻讀)。Next_Key Lock是為了解決數(shù)據(jù)庫出現(xiàn)幻讀的問題。

關(guān)于如何加鎖詳見我的這篇文章:Mysql的一致性非鎖定讀和一致性鎖定讀

有關(guān)臟讀、不可重復(fù)讀、幻讀詳見我的這篇文章淺析Mysql的隔離級別及MVCC

InnoDB存儲引擎默認(rèn)的事務(wù)隔離級別是RR級別,即可重復(fù)讀。在該級別下,采用next-key locking的方式加鎖。故而可以防止幻讀現(xiàn)象。

舉例一下,為什么next-key locking 可以解決幻讀問題吧:

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

創(chuàng)建表t:

create table t (a int primary key);insert into t select 1;insert into t select 2;insert into t select 5;

這時(shí)有三行記錄,分別是1,2,5。

假設(shè)有如下執(zhí)行序列:我們分析一下,會話A在時(shí)間2查詢的結(jié)果為5,由于使用了select...for update語句,為(2,+∞)這個(gè)范圍加了X鎖。因此任何對于這個(gè)范圍的插入都是不被允許的,由于4在這個(gè)范圍,所以不允許插入,也就避免了幻讀。

看完以上關(guān)于Mysql的InnoDB存儲引擎中的鎖,很多讀者朋友肯定多少有一定的了解,如需獲取更多的行業(yè)知識信息 ,可以持續(xù)關(guān)注我們的行業(yè)資訊欄目的。

名稱欄目:輕松掌握Mysql的InnoDB存儲引擎中的鎖
文章轉(zhuǎn)載:http://muchs.cn/article42/gheoec.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制網(wǎng)站、Google、網(wǎng)站設(shè)計(jì)公司、網(wǎng)站設(shè)計(jì)、網(wǎng)站營銷做網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

商城網(wǎng)站建設(shè)