mvcc詳解

1 為什么需要MVCC

  • 用來進(jìn)行事務(wù)回滾操作;

  • 有事務(wù)存在讀寫沖突時(shí)汇跨,也能做到不加鎖务荆,非阻塞并發(fā)讀

2 undolog

2.1 undolog定義

在InnoDB中的每一條記錄實(shí)際都會(huì)存在三個(gè)隱藏列:

  • DB_TRX_ID:事務(wù) ID,是根據(jù)事務(wù)產(chǎn)生時(shí)間順序自動(dòng)遞增的穷遂,是獨(dú)一無二的函匕。如果某個(gè)事務(wù)執(zhí)行過程中對該記錄執(zhí)行了增、刪蚪黑、改操作盅惜,那么InnoDB存儲(chǔ)引擎就會(huì)記錄下該條事務(wù)的 id中剩。

  • DB_ROLL_PTR:回滾指針,本質(zhì)上就是一個(gè)指向記錄對應(yīng)的undo log的一個(gè)指針抒寂,InnoDB 通過這個(gè)指針找到之前版本的數(shù)據(jù)

  • DB_ROW_ID:主鍵结啼,如果有自定義主鍵,那么該值就是主鍵蓬推;如果沒有主鍵妆棒,那么就會(huì)使用定義的第一個(gè)唯一索引;如果沒有唯一索引沸伏,那么就會(huì)默認(rèn)生成一個(gè)隱藏列作為主鍵。

image.png

版本V1动分、V2并不是物理上真實(shí)存在的毅糟,而是每次需要的時(shí)候根據(jù)當(dāng)前版本和undo log計(jì)算出來的。比如澜公,需要V1的時(shí)候姆另,就是通過V3依次執(zhí)行U2、U1算出來坟乾。

可以將這些 undo 日志都連起來迹辐,串成一個(gè)鏈表,形成版本鏈甚侣。版本鏈的頭節(jié)點(diǎn)就是當(dāng)前記錄最新的值明吩。

2.2 undo log分類

  • Insert undo log :insert生成的日志,僅在事務(wù)回滾中需要殷费,并且可以在事務(wù)提交后立即丟棄印荔。

  • Update undo log:update/delete生成的日志,除了用于事務(wù)回滾详羡,還用于一致性讀取仍律,只有不存在innodb為其分配快照的事務(wù)之后才能丟棄它們,在一致讀取中可能需要update undo log中的信息來構(gòu)建數(shù)據(jù)庫行的早期版本实柠。

2.3 數(shù)據(jù)刪除

刪除操作實(shí)際上不會(huì)直接刪除水泉,而只是標(biāo)記為刪除,最終的刪除操作是purge線程完成的

purge線程作用

1窒盐、清理undo log

2草则、清除page里面帶有Delete_Bit標(biāo)識(shí)的數(shù)據(jù)行。在InnoDB中登钥,事務(wù)中的Delete操作實(shí)際上并不是真正的刪除掉數(shù)據(jù)行畔师,而是一種Delete Mark操作,在記錄上標(biāo)識(shí)刪除牧牢,真正的刪除工作需要后臺(tái)purge線程去完成看锉。

2.4 更新主鍵

聚簇索引和二級索引都無法進(jìn)行in place update姿锭,都會(huì)產(chǎn)生兩個(gè)版本

update分兩步執(zhí)行,先刪除該行伯铣,再插入一行目標(biāo)行

image.png

2.5 更新非主鍵

聚簇索引可以in place update呻此,二級索引產(chǎn)生兩個(gè)版本

聚簇索引記錄undo log,二級索引不記錄undo log

更新二級索引腔寡,同時(shí)需要判斷是否修改索引頁面的MAX_TRX_ID


image.png

2.6 刪除操作

刪除操作實(shí)際上不會(huì)直接刪除焚鲜,而只是標(biāo)記為刪除,最終的刪除操作是purge線程完成的

image.png

3 Read View

Read View是InnoDB在實(shí)現(xiàn)MVCC時(shí)用到的一致性讀視圖放前,用于支持讀提交和可重復(fù)讀隔離級別的實(shí)現(xiàn)忿磅,作用是執(zhí)行期間判斷版本鏈中的哪個(gè)版本是當(dāng)前事務(wù)可見的。

本質(zhì)上是InnoDB為每個(gè)事務(wù)構(gòu)造了一個(gè)數(shù)組凭语,用來保存當(dāng)前正在活躍(啟動(dòng)了但還沒提交)的所有事務(wù)ID葱她。

數(shù)組里面事務(wù)ID的最小值記為低水位,當(dāng)前系統(tǒng)里面已經(jīng)創(chuàng)建過的事務(wù)ID的最大值加1記為高水位似扔;這個(gè)視圖數(shù)組和高水位吨些,就組成了當(dāng)前事務(wù)的一致性視圖(read-view)。

對于以上事務(wù):

  1. 如果在「已提交事務(wù)」部分炒辉,表示這個(gè)版本是已提交的事務(wù)或者是當(dāng)前事務(wù)自己生成的豪墅,這個(gè)數(shù)據(jù)對當(dāng)前事務(wù)是可見的;

  2. 如果落在「未開啟事務(wù)」部分黔寇,表示這個(gè)版本是由將來啟動(dòng)的事務(wù)生成的偶器,是肯定不可見的;

  3. 如果落在「未提交」部分啡氢,那就包括兩種情況
    a. 若當(dāng)前版本的trx_id在一致性試圖中状囱,表示這個(gè)版本是由還沒提交的事務(wù)生成的,不可見倘是;
    b. 若當(dāng)前版本的trx_id不在一致性試圖中亭枷,表示這個(gè)版本是已經(jīng)提交了的事務(wù)生成的,可見搀崭。

3 MVCC的工作原理

3.1 MVCC查詢的工作流程

3.1.1 查詢主鍵索引

生成Read View讀視圖

通過主鍵查找記錄叨粘,根據(jù)記錄里的DB_TRX_ID與Read View讀視圖進(jìn)行可見性判斷

配合DB_ROLL_PTR回滾指針和undo log來找到當(dāng)前事務(wù)可見的數(shù)據(jù)記錄

3.1.2 查詢二級索引

由于二級索引由于沒有三個(gè)隱藏列(DB_TRX_ID,DB_ROLL_PTR瘤睹,DB_ROW_ID)如何實(shí)現(xiàn)一致讀升敲,可重復(fù)讀?

更新二級索引列時(shí)轰传,舊的二級索引記錄將被刪除標(biāo)記(并非真正的刪除)驴党,新記錄將被插入;

如果二級索引記錄被標(biāo)記為刪除获茬,或者二級索引頁被更新的事務(wù)更新港庄,則不使用覆蓋索引技術(shù)(要通過聚族索引查找正確版本)倔既。

如果啟用了索引條件下推(ICP)優(yōu)化,首先會(huì)通過索引下推過濾掉不符合要求的行鹏氧,來避免使用聚集索引查找渤涌。如果找到匹配的記錄,即使在刪除標(biāo)記的記錄中把还,InnoDB也會(huì)在聚集索引中查找該記錄实蓬。

具體查詢步驟:

  • 生成Read View讀視圖

  • 比較讀視圖的up_limit_id與MAX_TRX_ID大小

    • 如果MAX_TRX_ID **小于 **本次Read View的up_limit_id,則全部可見吊履,過濾記錄中的有效記錄

    • 否則安皱,無法通過二級索引判斷可見性,需要一次遍歷每條記錄艇炎,反查到聚簇索引記錄练俐,通過聚簇索引記錄來判斷可見性

3.2 MVCC與隔離級別

MVCC 只在 **Read Commited(讀已提交) 和 Repeatable Read(可重讀讀) **兩種隔離級別下工作。

  • 在RC隔離級別下冕臭,是每個(gè)快照讀都會(huì)生成并獲取最新的Read View,這就是我們在RC級別下的事務(wù)中可以看到別的事務(wù)提交的更新的原因

  • 在RR隔離級別下燕锥,則是同一個(gè)事務(wù)中的第一個(gè)快照讀才會(huì)創(chuàng)建Read View, 之后的快照讀獲取的都是同一個(gè)Read View辜贵,從而做到可重復(fù)讀

3.3 mvcc能否解決幻讀

幻讀:在一次事務(wù)里面,多次查詢之后归形,結(jié)果集的個(gè)數(shù)不一致的情況叫做幻讀托慨。而多出來或者少的哪一行被叫做幻行。

  • 在快照讀讀情況下暇榴,mysql通過mvcc來避免幻讀厚棵。

  • 在當(dāng)前讀讀情況下,mysql通過next-key來避免幻讀蔼紧。

  • 不能把快照讀和當(dāng)前讀得到的結(jié)果不一樣這種情況認(rèn)為是幻讀婆硬,這是兩種不同的使用。所以mysql的rr級別是解決了幻讀的奸例。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末彬犯,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子查吊,更是在濱河造成了極大的恐慌谐区,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件逻卖,死亡現(xiàn)場離奇詭異宋列,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)评也,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進(jìn)店門炼杖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來灭返,“玉大人,你說我怎么就攤上這事嘹叫∑诺睿” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵罩扇,是天一觀的道長婆芦。 經(jīng)常有香客問我,道長喂饥,這世上最難降的妖魔是什么消约? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮员帮,結(jié)果婚禮上或粮,老公的妹妹穿的比我還像新娘。我一直安慰自己捞高,他們只是感情好氯材,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著硝岗,像睡著了一般氢哮。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上型檀,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天冗尤,我揣著相機(jī)與錄音,去河邊找鬼胀溺。 笑死裂七,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的仓坞。 我是一名探鬼主播背零,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼扯躺!你這毒婦竟也來了捉兴?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤录语,失蹤者是張志新(化名)和其女友劉穎倍啥,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體澎埠,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡虽缕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蒲稳。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片氮趋。...
    茶點(diǎn)故事閱讀 38,137評論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡伍派,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出剩胁,到底是詐尸還是另有隱情诉植,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布昵观,位于F島的核電站晾腔,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏啊犬。R本人自食惡果不足惜灼擂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望觉至。 院中可真熱鬧剔应,春花似錦、人聲如沸语御。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽应闯。三九已至月洛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間孽锥,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工细层, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留惜辑,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓疫赎,卻偏偏與公主長得像盛撑,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子捧搞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評論 2 345

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

  • Innodb-MVCC詳解 借用高性能 MySQL 的幾句話 MySQL 的大多數(shù)事務(wù)型存儲(chǔ)引擎都不是簡單的行級鎖...
    mago_dg閱讀 1,245評論 0 1
  • 1 mvcc是什么抵卫? 阿里數(shù)據(jù)庫內(nèi)核2017/12月報(bào)多版本控制: 指的是一種提高并發(fā)的技術(shù)。最早的數(shù)據(jù)庫系統(tǒng)胎撇,只...
    Aaron_Swartz閱讀 15,285評論 0 7
  • 1. MVCC的基本概念 1.1 三種數(shù)據(jù)庫并發(fā)場景 讀-讀:不存在任何問題介粘,也不需要并發(fā)控制 讀-寫:有線程安全...
    小青菜的技術(shù)博客閱讀 4,678評論 1 41
  • 最近要在公司內(nèi)做一次技術(shù)分享,思來想去不知道該分享些什么晚树,最后在朋友的提示下姻采,準(zhǔn)備分享一下MySQL的InnoDB...
    阿Q說代碼閱讀 578評論 0 3
  • 深入了解MVCC數(shù)據(jù)庫并發(fā)控制 問題: 我們知道這個(gè)是因?yàn)閿?shù)據(jù)庫的隔離級別,那到底是怎么實(shí)現(xiàn)的呢爵憎?思考這個(gè)問題的同...
    e0e180156aa8閱讀 2,518評論 0 8