mysql innodb高并發(fā)基礎(chǔ)-MVCC

mysql innodb能高效運(yùn)行,支撐高并發(fā)原因就是基于MVCC實(shí)現(xiàn)。

本文僅是簡(jiǎn)單介紹下MVCC原理昧诱,介紹事務(wù)隔離級(jí)別RC,RR中原理所袁。

MVCC

MVCC(全稱Multi-Version Concurrency Control)鳄哭,多版本并發(fā)控制,解決數(shù)據(jù)庫(kù)的并發(fā)訪問(wèn)高效問(wèn)題纲熏。

維基百科中有更具體的描述,感興趣可以看看妆丘。

MVCC到底解決什么問(wèn)題

數(shù)據(jù)庫(kù)中,讀數(shù)據(jù)的同時(shí)局劲,有另外的任務(wù)寫入數(shù)據(jù)勺拣,在沒(méi)有任何鎖機(jī)制情況下,很有可能讀到是『半寫』或者不一致的數(shù)據(jù)鱼填。

當(dāng)然解決這個(gè)問(wèn)題最簡(jiǎn)單的方法药有,通過(guò)加鎖,即Share lock,write lock,會(huì)有讀讀兼容,讀寫或?qū)懽x阻塞問(wèn)題愤惰,這種方式效率很低苇经。實(shí)際中,在寫某行數(shù)據(jù)同時(shí)宦言,又另外任務(wù)使用mysql同時(shí)去讀數(shù)據(jù)扇单,讀操作并沒(méi)有感受到block,反而覺(jué)得效率很高奠旺≈├剑可以確定是mysql中沒(méi)有最簡(jiǎn)單的機(jī)制來(lái)保證并發(fā),官方文檔上申明使用了MVCC响疚。

當(dāng)然鄙信,innodb是行鎖,針對(duì)記錄的更新會(huì)加排他鎖忿晕,保證并發(fā)時(shí)資源時(shí)線程安全装诡。
鎖的介紹博文中有介紹,這里就不多介紹践盼。

MVCC是怎么做到的

mysql文檔:InnoDB是一個(gè)多版本的存儲(chǔ)引擎慎王,保存有關(guān)行已更改的old version的信息,以支持并發(fā)和回滾等事務(wù)功能宏侍。

簡(jiǎn)而言之:

MVCC使用了快照手段,每個(gè)連接到數(shù)據(jù)庫(kù)的讀者蜀漆,在某個(gè)瞬間看到的是數(shù)據(jù)庫(kù)的 某一個(gè)快照谅河,寫者寫操作造成的變化在寫操作完成之前(或者數(shù)據(jù)庫(kù)事務(wù)提交之前)對(duì)于其他的讀者來(lái)說(shuō)是不可見(jiàn)的。

內(nèi)部确丢,InnoDB為數(shù)據(jù)庫(kù)中存儲(chǔ)的每一行j記錄添加三個(gè)字段:

  • 6字節(jié)的事務(wù)ID(DB_TRX_ID ):表示插入或更新該行的最后一個(gè)事務(wù)的事務(wù)標(biāo)識(shí)符
  • 7字節(jié)的回滾指針(DB_ROLL_PTR):指向?qū)懭牖貪L段的undo log記錄绷耍。更新了行,則undo log記錄包含在更新行之前重建行內(nèi)容所需的信息鲜侥。
  • 6字節(jié)的自增 (DB_ROW_ID):插入新行時(shí)單調(diào)增加的行ID褂始。

undo log

回滾使用undo log,以rollback segment的數(shù)據(jù)結(jié)構(gòu)(Oracle也是類似數(shù)據(jù)結(jié)構(gòu))為單位進(jìn)行存儲(chǔ)描函,存儲(chǔ)在表空間中崎苗,可以說(shuō)undo log被劃分為多個(gè)段,具體某行的undo log就保存在某個(gè)段中 舀寓。因此InnoDB使用回滾段中的信息來(lái)執(zhí)行事務(wù)回滾中所需的undo操作胆数。磁盤上不存在單獨(dú)的undo log文件,所有的undo log存放在存放于ibdata文件中互墓。

具體操作:copy事務(wù)前的數(shù)據(jù)庫(kù)內(nèi)容(行)到undo buffer必尼,在適合的時(shí)間把undo buffer中的內(nèi)容刷新到磁盤。undo buffer是環(huán)形緩沖,但當(dāng)緩沖滿的時(shí)候判莉,undo buffer中的內(nèi)容會(huì)也會(huì)被刷新到磁盤undo log文件豆挽,所有的undo log均存放在主ibdata文件中(表空間),即使客戶端設(shè)置了每表一個(gè)數(shù)據(jù)文件也是如此券盅。

undo log分為insert 和update undo log類型帮哈,刪除也是update undo log。

insert undo log:原始的數(shù)據(jù)并不存在渗饮,所以回滾時(shí)把insert undo log丟棄即可

流程如下

  1. 初始數(shù)據(jù)行


    image.png

    原始的數(shù)據(jù)并不存在但汞,回滾指針是null,回滾時(shí)直接丟棄改行。

  2. 事務(wù)1更修改
    獲得記錄更新鎖后互站,把該行修改前的值Copy到undo log私蕾,記錄事務(wù)ID 回滾ID。

image.png

3.事務(wù)2修改


image.png
  1. 事務(wù)提交
    當(dāng)事務(wù)正常提交時(shí),只需要更改事務(wù)狀態(tài)為COMMIT即可胡桃,不需做其他額外的工作踩叭,而Rollback則稍微復(fù)雜點(diǎn),需要根據(jù)當(dāng)前回滾指針從undo log中找出事務(wù)修改前的版本并恢復(fù)翠胰。

上面的流程看來(lái)容贝,undo log是不是越來(lái)越大,這點(diǎn)mysql也做了考慮之景,會(huì)啟動(dòng)purge進(jìn)程以真實(shí)刪除老的斤富、過(guò)時(shí)的數(shù)據(jù)。

redo log

為了支持事務(wù)使用redo log锻狗。當(dāng)客戶端執(zhí)行每條SQL(更新語(yǔ)句)時(shí)满力,redo log會(huì)被首先寫入log buffer,執(zhí)行COMMIT命令時(shí)轻纪,log buffer中的內(nèi)容會(huì)被視情況刷新到磁盤油额。具體作用:保存執(zhí)行的SQL語(yǔ)句到一個(gè)指定的Log文件,當(dāng)Mysql服務(wù)因斷電恢復(fù)或強(qiáng)行重啟等時(shí)重新執(zhí)行redo log記錄的SQL操作刻帚,繼續(xù)那些已經(jīng)commit但數(shù)據(jù)尚未完全回寫到磁盤的事務(wù)潦嘶,保證操作不丟失。

與事務(wù)關(guān)系

  • READ_UNCOMMITTED
    讀事務(wù)直接讀取主記錄崇众,無(wú)論更新事務(wù)是否完成掂僵。

  • READ_COMMITTED
    優(yōu)先讀取本事務(wù)修改的值,未有修改的每次都讀取undo log中最近的版本顷歌。兩次對(duì)同一字段的讀可能讀到不同的數(shù)據(jù)看峻,但能保證每次都讀到最新的數(shù)據(jù)。使用行鎖衙吩。

  • REPEATABLE_READ
    讀該事務(wù)第一次讀建立起來(lái)的數(shù)據(jù)快照,每次都讀取指定的版本互妓,如果沒(méi)有做更新可能讀不到最新的數(shù)據(jù)。這里使用行鎖,gap鎖冯勉,next-key鎖澈蚌,如果索引不是聚鏃索引,使用next-key鎖能保證不會(huì)產(chǎn)生幻讀灼狰。

  • SERIALIZABLE
    讀加共享鎖宛瞄,寫加排他鎖,讀讀不會(huì)阻塞交胚,讀寫或?qū)懽x出現(xiàn)阻塞份汗,因此并發(fā)度大幅下降。

參考資料

https://en.wikipedia.org/wiki/Multiversion_concurrency_control
https://dev.mysql.com/doc/refman/5.7/en/innodb-multi-versioning.html
http://www.360doc.cn/article/12904276_403505950.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蝴簇,一起剝皮案震驚了整個(gè)濱河市杯活,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌熬词,老刑警劉巖旁钧,帶你破解...
    沈念sama閱讀 206,723評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異互拾,居然都是意外死亡歪今,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門颜矿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)寄猩,“玉大人,你說(shuō)我怎么就攤上這事骑疆√锲” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 152,998評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵封断,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我舶担,道長(zhǎng)坡疼,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 55,323評(píng)論 1 279
  • 正文 為了忘掉前任衣陶,我火速辦了婚禮柄瑰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘剪况。我一直安慰自己教沾,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布译断。 她就那樣靜靜地躺著授翻,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上堪唐,一...
    開(kāi)封第一講書人閱讀 49,079評(píng)論 1 285
  • 那天巡语,我揣著相機(jī)與錄音,去河邊找鬼淮菠。 笑死男公,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的合陵。 我是一名探鬼主播枢赔,決...
    沈念sama閱讀 38,389評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼拥知!你這毒婦竟也來(lái)了踏拜?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 37,019評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤举庶,失蹤者是張志新(化名)和其女友劉穎执隧,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體户侥,經(jīng)...
    沈念sama閱讀 43,519評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡镀琉,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蕊唐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片屋摔。...
    茶點(diǎn)故事閱讀 38,100評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖替梨,靈堂內(nèi)的尸體忽然破棺而出钓试,到底是詐尸還是另有隱情,我是刑警寧澤副瀑,帶...
    沈念sama閱讀 33,738評(píng)論 4 324
  • 正文 年R本政府宣布弓熏,位于F島的核電站,受9級(jí)特大地震影響糠睡,放射性物質(zhì)發(fā)生泄漏挽鞠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評(píng)論 3 307
  • 文/蒙蒙 一狈孔、第九天 我趴在偏房一處隱蔽的房頂上張望信认。 院中可真熱鬧,春花似錦均抽、人聲如沸嫁赏。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,289評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)潦蝇。三九已至款熬,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間护蝶,已是汗流浹背华烟。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,517評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留持灰,地道東北人盔夜。 一個(gè)月前我還...
    沈念sama閱讀 45,547評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像堤魁,于是被迫代替她去往敵國(guó)和親喂链。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評(píng)論 2 345