Mysql innodb SQL語句加鎖方式

mysql innodb存儲引擎支持事務(wù)遂鹊,是mysql的默認(rèn)存儲引擎振乏。

數(shù)據(jù)庫事務(wù)

事務(wù)是由一組sql語句組成的邏輯單元,完成特定的任務(wù)秉扑。事務(wù)有四個基本屬性慧邮,通常稱為ACID:

Atomic:原子性,組成事務(wù)的sql語句要么全部執(zhí)行舟陆,要么全部不執(zhí)行

Consitensy:事務(wù)完成后误澳,數(shù)據(jù)庫處于一致性狀態(tài)。事務(wù)需經(jīng)過良好的設(shè)計秦躯,才能讓數(shù)據(jù)保持在一致狀態(tài)

Isolation:隔離性忆谓,并發(fā)事務(wù)不受彼此干擾,事務(wù)處理的中間狀態(tài)對外部不可見

durable:持久性踱承,一旦事務(wù)執(zhí)行完成倡缠,對于數(shù)據(jù)的修改是永久性的,即使出現(xiàn)故障也能夠保持

innodb支持事務(wù)茎活,是innodb區(qū)別于其他存儲引擎最重要的一點昙沦,除此之外還有行鎖,這也是mysql如此流行的原因载荔。

并發(fā)事務(wù)的常見問題

對于并發(fā)事務(wù)來說盾饮,能大大提高數(shù)據(jù)庫的性能以及吞吐量,但是并發(fā)事務(wù)處理身辨,通常存在如下問題:

Lost Update: 當(dāng)兩個事務(wù)并發(fā)修改同一行時丐谋,如果是基于原值基礎(chǔ)上的更新,有可能后寫入的覆蓋了之前一次的寫入

臟讀: 某個事務(wù)讀取到了其他事務(wù)未提交的值煌珊,稱之為臟讀

不可重復(fù)讀:在同一個事務(wù)里号俐,針對相同的查詢語句,返回的數(shù)據(jù)已經(jīng)發(fā)生了改變定庵,或者被刪除吏饿,稱為不可重復(fù)讀

幻讀:在同一個事務(wù)里,按照相同的查詢條件蔬浙,后一次查詢返回了比前一次查詢更多的結(jié)果猪落,發(fā)現(xiàn)其他事務(wù)插入的新數(shù)據(jù),稱之為幻讀

數(shù)據(jù)庫隔離級別

為了解決并發(fā)事務(wù)的問題畴博,就有了數(shù)據(jù)庫的隔離級別笨忌,不同的隔離級別,解決不同的問題俱病。通常有RU官疲,RC袱结,RR,Serializable四種

RU: read uncommited途凫,讀未提交

RC:read commited 讀已提交

RR:repeatable read 可重復(fù)讀

serializable: 串行化

事務(wù)的隔離性是通過鎖來實現(xiàn)的垢夹,mysql事務(wù)的默認(rèn)隔離級別是RR

InnoDB使用的鎖

為了支持事務(wù),以及不同的隔離級別维费,innodb提供了如下類型的鎖:

1.共享鎖果元,排他鎖(S鎖,X鎖)S通常指的是讀鎖犀盟,X是寫鎖而晒。有一點需要提出的是,S鎖且蓬,X鎖不是具體的鎖欣硼,而是鎖的模式,用來'修飾'其他的鎖

2.意向鎖 意向鎖是表鎖恶阴,Intention Lock有兩種模式诈胜,意向共享鎖和意向排他鎖 簡稱IS和IX

3.Record Lock,記錄鎖冯事,記錄鎖也分為S鎖和X鎖

4.Gap Locks 間隙鎖焦匈,鎖住記錄的間隙,解決幻讀問題

5.Next-key Locks昵仅,鄰鍵鎖 = 行鎖+間隙鎖

6.插入意向鎖

7.自增鎖 自增列的鎖

共享鎖排他鎖

共享鎖(S鎖)和排他鎖(X鎖)的概念在許多編程語言中都出現(xiàn)過缓熟。先來描述一下這兩種鎖在MySQL中的影響結(jié)果:

如果一個事務(wù)對某一行數(shù)據(jù)加了S鎖,另一個事務(wù)還可以對相應(yīng)的行加S鎖摔笤,但是不能對相應(yīng)的行加X鎖够滑。

如果一個事務(wù)對某一行數(shù)據(jù)加了X鎖,另一個事務(wù)既不能對相應(yīng)的行加S鎖也不能加X鎖吕世。

行鎖彰触,間隙鎖,鄰鍵鎖

這三種鎖描述的都是鎖定范圍命辖,mysql官方文檔的定義如下:

記錄鎖:記錄鎖鎖定索引的一條記錄况毅,對于unique索引,鎖住唯一的一行尔艇,對于二級索引尔许,鎖定索引以及對應(yīng)的聚集索引

間隙鎖:間隙索引要么鎖住索引記錄中間的值,要么鎖住索引第一個索引記錄之前的值终娃,或者是最后一個索引之后的值

鄰鍵鎖:是索引記錄上的鎖和在索引記錄之前的間隙鎖的組合

在定義中味廊,都提到了索引記錄,為什么?行鎖和索引有什么關(guān)系呢毡们?其實迅皇,innodb是通過掃描索引來進(jìn)行加鎖操作,innodb會為他

遇到的每一個索引增加共享鎖或者排他鎖衙熔,因此記錄鎖也稱為索引記錄鎖。row-level lock其實就是index-record lock搅荞。行鎖其實是加到

相應(yīng)的索引記錄上的

這三種鎖的鎖定范圍不同红氯,逐漸擴(kuò)大,我們舉個例子來說明咕痛,假設(shè)表test中有索引列3痢甘,5,8茉贡,9塞栅,四個數(shù)組值,那對應(yīng)的鎖的鎖定范圍如下:

記錄鎖:鎖定范圍是單獨的索引記錄腔丧,也就是3,5,8,9這四行

間隙鎖:間隙鎖的鎖定范圍為行中間隙放椰,為(-∞,3),(3,5),(5,8)(8,9)

鄰鍵鎖:索引記錄和索引記錄前的間隙鎖,為(-∞,3],(3,5],(5,8](8,9]

對于間隙鎖愉粤,需要額外補充如下幾點:

1.間隙鎖阻止其他事務(wù)對間隙的并發(fā)插入砾医,這樣能有效的解決幻讀問題,因此不是所有事務(wù)隔離級別都支持間隙鎖

2.間隙鎖的作用只是阻止其他事務(wù)在間隙插入數(shù)據(jù)衣厘,不會阻止其他事務(wù)擁有想用的間隙鎖如蚜,除了insert語句,其他事務(wù)對同樣的行加

間隙鎖不會被阻塞

3.對于唯一索引的加鎖行為影暴,間隙鎖會失效错邦,只有指定的行鎖

mysql 5.7及之前,可以通過information_schema.innodb_locks查看事務(wù)的鎖情況型宙,但是只能看到阻塞事務(wù)的鎖撬呢,如果事務(wù)并未阻塞,在

該表中看不到事務(wù)的鎖情況早歇。mysql 8.0刪除了information_schema.innodb_locks倾芝,添加了performance_schema.data_locks,? 支持查看未阻塞場景下的對事務(wù)持有的鎖

innodb常用SQL語句的加鎖方式

上面已經(jīng)介紹了innodb的各種類型的鎖,那么不同的sql語句分別加了什么鎖呢箭跳?

鎖的作用是為了解決并發(fā)事務(wù)的控制問題的晨另。即兩個并發(fā)執(zhí)行的事務(wù),如果T1正在修改某些行谱姓,那么T2要并發(fā)讀取借尿、修改、刪除,插入滿足T1查詢條件的行時路翻,T2就必須被阻塞狈癞。這就是通過鎖來實現(xiàn)的。通常茂契,要么是T1在已存在的行上加index record lock排他鎖是的T2無法觸碰已存在的行蝶桶,以及T1在不存在的行上加gap lock是的T2無法插入新的滿足條件的行

加什么樣的鎖,與以下因素相關(guān):

1.數(shù)據(jù)庫的事務(wù)隔離級別

2.SQL是一致性非鎖定讀掉冶,還是DML真竖,或鎖定讀

3.SQL執(zhí)行是是否用到的索引,以及索引類型(主鍵索引厌小,唯一索引恢共,普通索引)

下面我們來分析下,不同的隔離級別下璧亚,使用不同的索引時讨韭,分別加什么鎖。

通常癣蟋,普通SELECT使用(快照讀)Snapshot Read透硝,無需加鎖。RU和Serializable兩個事務(wù)隔離級別我們不會用到梢薪。

事務(wù)隔離級別為RR模式:

如果使用非唯一索引進(jìn)行搜索或掃描蹬铺,則在鎖掃描的每一個索引記錄上都設(shè)置next-key lock。這里鎖掃描的每一個索引記錄是指當(dāng)掃描執(zhí)行計劃中所使用的的索引時秉撇,搜索遇到的每一條記錄甜攀,where條件是否排除掉某個數(shù)據(jù)行并沒有關(guān)系。innodb并不記得確切的where條件琐馆,innodb倔強(qiáng)的只認(rèn)其掃描的索引范圍规阀。

這個有點難以理解,對于mysql的執(zhí)行計劃只會選擇一個索引瘦麸,使用一個索引來進(jìn)行掃描谁撼。mysql執(zhí)行sql語句的流程是先由innodb引擎執(zhí)行索引掃描,然后把結(jié)果返回給mysql服務(wù)器滋饲,mysql服務(wù)器再對該索引條件之外的其他查詢條件進(jìn)行求值厉碟,從而得到最終結(jié)果集。而加鎖時只考慮innodb掃描的索引屠缭,非索引的where條件并不考慮箍鼓。當(dāng)然,mysql使用index_merge優(yōu)化時會同時使用多個索引的呵曹。

加的鎖一般是next key lock款咖,這種鎖不僅鎖住索引本身何暮,還鎖住了每一條索引記錄前面的間隙,從而阻止其他事務(wù)向索引記錄前面緊接著的間隙中插入記錄

由于innodb聚集索引的特性铐殃,以及普通索引的實現(xiàn)海洼,對普通索引加鎖時,會隱含的鎖住想用的聚集索引(主鍵索引)富腊。

如果使用了唯一索引的唯一搜索條件坏逢,innodb只在滿足條件的索引記錄上設(shè)置行鎖,不鎖定前面的間隙蟹肘。如果使用范圍搜索條件词疼,還是會加next key lock鎖住間隙

insert在插入的索引記錄上加X鎖,以及insert intention lock帘腹,不會阻止其他事務(wù)在插入的記錄前的間隙插入新的記錄,不同的事務(wù)可以向同一索引的間隙插入記錄而無需互相等待许饿。一個事務(wù)中insert語句會在插入的行的索引記錄上設(shè)置一把排他鎖阳欲,如果有鍵重復(fù)的錯誤發(fā)生,則會在重復(fù)的索引記錄上設(shè)置一把共享鎖陋率,在多個session同時插入一行球化,且另外的某個session已經(jīng)持有了該索引記錄的排他鎖時,共享鎖的使用可能導(dǎo)致死鎖的出現(xiàn)瓦糟。

事務(wù)隔離級別為RC模式

事務(wù)隔離級別為RC模式時筒愚,默認(rèn)Gap鎖被禁用,next key lock也被禁用菩浙,只剩下行鎖了巢掺。











?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市劲蜻,隨后出現(xiàn)的幾起案子陆淀,更是在濱河造成了極大的恐慌,老刑警劉巖先嬉,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件轧苫,死亡現(xiàn)場離奇詭異,居然都是意外死亡疫蔓,警方通過查閱死者的電腦和手機(jī)含懊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來衅胀,“玉大人岔乔,你說我怎么就攤上這事∞中。” “怎么了重罪?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我剿配,道長搅幅,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任呼胚,我火速辦了婚禮茄唐,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蝇更。我一直安慰自己沪编,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布年扩。 她就那樣靜靜地躺著蚁廓,像睡著了一般拐叉。 火紅的嫁衣襯著肌膚如雪皆的。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天承桥,我揣著相機(jī)與錄音况脆,去河邊找鬼饭宾。 笑死,一個胖子當(dāng)著我的面吹牛格了,可吹牛的內(nèi)容都是我干的看铆。 我是一名探鬼主播,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼盛末,長吁一口氣:“原來是場噩夢啊……” “哼弹惦!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起满败,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤肤频,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后算墨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體宵荒,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年净嘀,在試婚紗的時候發(fā)現(xiàn)自己被綠了报咳。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡挖藏,死狀恐怖暑刃,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情膜眠,我是刑警寧澤岩臣,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布溜嗜,位于F島的核電站,受9級特大地震影響架谎,放射性物質(zhì)發(fā)生泄漏炸宵。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一谷扣、第九天 我趴在偏房一處隱蔽的房頂上張望土全。 院中可真熱鬧,春花似錦会涎、人聲如沸裹匙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽概页。三九已至,卻和暖如春练慕,著一層夾襖步出監(jiān)牢的瞬間绰沥,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工贺待, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人零截。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓麸塞,卻偏偏與公主長得像,于是被迫代替她去往敵國和親涧衙。 傳聞我的和親對象是個殘疾皇子哪工,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,452評論 2 348

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