MySQL InnoDB 的多版本并發(fā)控制(MVCC)

innoDB 的多版本并發(fā)控制(MVCC)

1. MVCC定義

1.1定義

MVCC全稱Mutli Version Concurreny Control,多版本并發(fā)控制,也可稱之為一致性非鎖定讀驹止;它通過行的多版本控制方式來讀取當前執(zhí)行時間數(shù)據(jù)庫中的行數(shù)據(jù)淋样。實質(zhì)上使用的是快照數(shù)據(jù),這樣就可以實現(xiàn)不加鎖讀。MVCC 主要應(yīng)用于 Read CommitedRepeatable read 兩個事務(wù)隔離級別截驮。

1.2一些困惑

  • MYSQL的事務(wù)隔離級中的RC,RR級別怎么實現(xiàn)?
  • 事務(wù)回滾操作是怎么回滾啄糙?
  • 數(shù)據(jù)多版本并發(fā)控制中的多版本在哪里?

2.innoDB 的邏輯存儲結(jié)構(gòu)

innoDB 的數(shù)據(jù)保存在表空間中云稚,表空間又包含各種段隧饼,其中有數(shù)據(jù)段,索引段静陈,回滾段燕雁。InnoDB中數(shù)據(jù)以B+Tree的數(shù)據(jù)結(jié)構(gòu)存儲的,非葉子節(jié)點既是索引鲸拥,葉子節(jié)點既是數(shù)據(jù)行拐格,回滾段用于存儲undoLog,undoLog中記錄的就是多版本數(shù)據(jù)刑赶,用于快照讀和事務(wù)失敗后的數(shù)據(jù)回滾,MySQL在合適的時機會清理undoLog捏浊。


960295-20180123215304569-1124033252.png

3.MVCC的實現(xiàn)

MVCC的實現(xiàn)依賴于 每行的隱藏字段,DB_TRX_ID,DB_ROLL_PTR,刪除標記位,還有read_view撞叨。

3.1 三個隱藏字段

innoDB 向數(shù)據(jù)庫中存儲的每行添加三個隱藏字段(有的書上說是兩個金踪,但是我看官方文檔說是三個)。

數(shù)據(jù)初始化.png

1 DB_TRX_ID 事務(wù)id

占6 字節(jié)牵敷,表示這一行數(shù)據(jù)最后插入或修改的事務(wù)id热康。此外刪除在內(nèi)部也被當作一次更新,在行的特殊位置添加一個刪除標記(記錄頭信息有一個字節(jié)存儲是否刪除的標記)劣领。

2 DB_ROLL_PTR 回滾指針

占7字節(jié)姐军,回滾指針指向被寫在Rollback segment中的undoLog記錄,在該行數(shù)據(jù)被更新的時候尖淘,undoLog 會記錄該行修改前內(nèi)容到undoLog奕锌。

3 DB_ROW_ID 行ID

占7字節(jié),他就項自增主鍵一樣隨著插入新數(shù)據(jù)自增村生。如果表中不存主鍵 或者 唯一索引惊暴,那么數(shù)據(jù)庫 就會采用DB_ROW_ID生成聚簇索引。否則DB_ROW_ID不會出現(xiàn)在索引中趁桃。

3.2 undo log

undo log是為回滾而用辽话,具體內(nèi)容就是copy事務(wù)前的數(shù)據(jù)庫內(nèi)容(行)到undo buffer,在適合的時間把undo buffer中的內(nèi)容刷新到磁盤卫病。undo buffer與redo buffer一樣油啤,也是環(huán)形緩沖,但當緩沖滿的時候蟀苛,undo buffer中的內(nèi)容會也會被刷新到磁盤益咬;與redo log不同的是,磁盤上不存在單獨的undo log文件帜平,所有的undo log均存放在主ibd數(shù)據(jù)文件中(表空間)幽告,即使客戶端設(shè)置了每表一個數(shù)據(jù)文件也是如此梅鹦。

undo log 在 Rollback segment中又被細分為 insert 和 update undo log , insert 類型的undo log 僅僅用于事務(wù)回滾,當事務(wù)一旦提交,insert undo log 就會被丟棄冗锁。update的undo log 被用于 一致性的讀和事務(wù)回滾齐唆,update undo log 的清理 是在 沒有事務(wù) 需要對這部分數(shù)據(jù)快照進行一致性讀的時候 進行清理。

undo log 的創(chuàng)建
每次對數(shù)據(jù)進行更新操作時冻河,都會copy 當前數(shù)據(jù),保存到undo log 中箍邮。并修改 當前行的 回滾指針指向 undo log 中的 舊數(shù)據(jù)行。


undolog.png

3.3 read_view 判斷數(shù)據(jù)行可見性

在innodb中芋绸,創(chuàng)建一個新事務(wù)的時候媒殉,innodb會將當前系統(tǒng)中的活躍事務(wù)列表創(chuàng)建一個副本(read view)担敌,副本中保存的是系統(tǒng)當前不應(yīng)該被本事務(wù)看到的其他事務(wù)id列表摔敛。當用戶在這個事務(wù)中要讀取該行記錄的時候,innodb會將該行當前的版本號與該read view進行比較全封。

具體的算法是(可重復(fù)讀級別):

假設(shè)當前 數(shù)據(jù)行 事務(wù)ID 為 T0 马昙,read view 中保存的 最老的事務(wù)id T_min ,最新的 事務(wù)id 為 T_max,當前進行的事務(wù)id 為 T_new 。

  • 如果 T0 < T_min ,那么該行數(shù)據(jù)可見刹悴。

    因為 T0 在 T_new 事務(wù)開始前 已經(jīng)提交行楞。

  • 如果 T0 > T_max ,數(shù)據(jù)行不可見。根據(jù)DB_ROLL_PTR 指針 找到下一個 數(shù)據(jù)版本土匀,再次進行數(shù)據(jù)可見性判斷子房。

    因為 T0事務(wù) 在 T_new 開始前并不存在,也就是說T0 在T_new 開始后 創(chuàng)建就轧。

  • 如果 T_min <= T0 <= T_max 证杭,判斷T0 是否在read_view 中,如果 不在該行數(shù)據(jù)可見妒御。如果不可見根據(jù)DB_ROLL_PTR 指針 找到下一個 數(shù)據(jù)版本解愤,再次進行數(shù)據(jù)可見性判斷。

3.4 Read Commited 乎莉,Repeatable read 數(shù)據(jù)可見性判斷

Read CommitedRepeatable read 采用相同的數(shù)據(jù)可見性判斷邏輯送讲。
那么怎么在相同的判斷邏輯下 分別 實現(xiàn) RC 和 RR 級別的?

  • Read Commited
    在每次語句執(zhí)行的過程中惋啃,都關(guān)閉read_view, 重新創(chuàng)建當前的一份新的read_view哼鬓。
    這樣就可以根據(jù)當前的全局事務(wù)鏈表創(chuàng)建read_view的事務(wù)區(qū)間,實現(xiàn)read committed隔離級別边灭。
  • Repeatable read
    在repeatable read的隔離級別下魄宏,創(chuàng)建事務(wù)trx結(jié)構(gòu)的時候,就生成了當前的global read view存筏。
    使用trx_assign_read_view函數(shù)創(chuàng)建宠互,一直維持到事務(wù)結(jié)束味榛,這樣就實現(xiàn)了repeatable read隔離級別。

正是因為Read CommitedRepeatable read的read view 生成方式和時機不同予跌,導(dǎo)致在不同隔離級別下,read committed 總是讀最新一份快照數(shù)據(jù)搏色,而repeatable read 讀事務(wù)開始時的行數(shù)據(jù)版本。

4. 新的疑問

每行的記錄頭信息保存在什么位置券册,官方文檔說是刪除是邏輯的刪除频轿,刪除只是記錄一個刪除標記。
通過查看一些博客說是被記錄在記錄頭信息中烁焙,但是官方說的三個隱藏字段并沒有提到這個記錄頭信息航邢。那他到底算不算隱藏字段。如果不是隱藏字段那他記錄在哪里骄蝇?


1253350-20180420172417526-524213118.jpg

5 .參考文檔

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末膳殷,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子九火,更是在濱河造成了極大的恐慌赚窃,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件岔激,死亡現(xiàn)場離奇詭異,居然都是意外死亡虑鼎,警方通過查閱死者的電腦和手機辱匿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來炫彩,“玉大人匾七,你說我怎么就攤上這事∶铰ィ” “怎么了乐尊?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長划址。 經(jīng)常有香客問我扔嵌,道長,這世上最難降的妖魔是什么夺颤? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任痢缎,我火速辦了婚禮,結(jié)果婚禮上世澜,老公的妹妹穿的比我還像新娘独旷。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布嵌洼。 她就那樣靜靜地躺著案疲,像睡著了一般。 火紅的嫁衣襯著肌膚如雪麻养。 梳的紋絲不亂的頭發(fā)上褐啡,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天,我揣著相機與錄音鳖昌,去河邊找鬼备畦。 笑死,一個胖子當著我的面吹牛许昨,可吹牛的內(nèi)容都是我干的懂盐。 我是一名探鬼主播,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼糕档,長吁一口氣:“原來是場噩夢啊……” “哼莉恼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起翼岁,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤类垫,失蹤者是張志新(化名)和其女友劉穎司光,沒想到半個月后琅坡,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡残家,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年榆俺,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片坞淮。...
    茶點故事閱讀 40,427評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡茴晋,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出回窘,到底是詐尸還是另有隱情诺擅,我是刑警寧澤,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布啡直,位于F島的核電站烁涌,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏酒觅。R本人自食惡果不足惜撮执,卻給世界環(huán)境...
    茶點故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望舷丹。 院中可真熱鬧抒钱,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蕾额,卻和暖如春厉颤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背凡简。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工逼友, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人秤涩。 一個月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓帜乞,卻偏偏與公主長得像,于是被迫代替她去往敵國和親筐眷。 傳聞我的和親對象是個殘疾皇子黎烈,可洞房花燭夜當晚...
    茶點故事閱讀 45,440評論 2 359