【MySQL】MVCC詳解與MVCC實(shí)現(xiàn)原理

一陋葡、什么是MVCC

MVCC,全稱 Multi-Version Concurrency Control 彻采,MVCC是多版本并發(fā)控制的全稱腐缤,是指多版本的并發(fā)控制。MVCC是一種并發(fā)控制方法肛响。通常岭粤,在數(shù)據(jù)庫管理系統(tǒng)中,它用編程語言實(shí)現(xiàn)對(duì)數(shù)據(jù)庫和事務(wù)存儲(chǔ)器的并發(fā)訪問特笋。

MVCC 是一種在讀取數(shù)據(jù)時(shí)無需鎖定(加鎖)即可提高讀取效率和并發(fā)性的方法剃浇。

數(shù)據(jù)庫并發(fā)有以下情況:

1、讀-讀:沒有問題猎物。

2虎囚、讀-寫:存在線程安全問題,這可能導(dǎo)致臟讀蔫磨、幻讀和不可重復(fù)讀淘讥。

3、寫-寫:存在線程安全問題堤如,更新可能會(huì)丟失适揉。

二、MVCC的實(shí)現(xiàn)原理

這里面講解了煤惩,事務(wù)的特性、事務(wù)的隔離級(jí)別炼邀,當(dāng)時(shí)說MySQL事務(wù)實(shí)現(xiàn)原理有單版本控制——鎖魄揉,以及多版本控制MVCC。

現(xiàn)在我們需要知道拭宁,在讀已提交RC洛退,Read Committed)和可重復(fù)讀RR,Repeatable Read)隔離級(jí)別下的快照讀杰标,都是基于MVCC實(shí)現(xiàn)的兵怯!

MVCC最大的優(yōu)點(diǎn)是沒有讀鎖,讀寫之間沒有沖突腔剂。在讀多寫少的OLTP(On-Line Transaction Processing媒区,聯(lián)機(jī)事務(wù)處理)應(yīng)用程序中,讀寫之間沒有沖突非常重要,這大大提高了系統(tǒng)的并發(fā)性袜漩。

1绪爸、MVCC多版本實(shí)現(xiàn)

為了讓您更直觀地理解MVCC的實(shí)現(xiàn)原理,這里通過事務(wù)更新一行記錄的過程的例子宙攻,來解釋MVCC中多個(gè)版本的實(shí)現(xiàn)奠货。

假設(shè) ID~……是表中字段的名稱(DATA)。最后三個(gè)隱藏字段對(duì)應(yīng)對(duì)應(yīng)行的隱藏ID座掘、事務(wù)編號(hào)和回滾指針递惋,如下圖所示:

隱含ID(DB_ROW_ID),6字節(jié)溢陪,當(dāng)InnoDB自動(dòng)生成聚集索引時(shí)萍虽,聚集索引包括這個(gè)DB_ROW_ ID的值。

事務(wù)編號(hào)(DB_TRX_ID)嬉愧,6字節(jié)贩挣,它標(biāo)記了此行最新更新記錄的事務(wù)ID。每個(gè)事務(wù)都被處理没酣,其值自動(dòng)為+1王财。

回滾指針(DB_ROLL_PT),7個(gè)字節(jié)裕便,指向當(dāng)前記錄項(xiàng)的回滾段的撤消日志記錄绒净,通過該記錄可以找到以前版本的數(shù)據(jù)。

具體更新過程簡述如下:

首先偿衰,如果數(shù)據(jù)只是INSERT挂疆,則可以認(rèn)為ID是 1,其他兩個(gè)字段為空下翎。

當(dāng) 事務(wù)1 更改此行的數(shù)據(jù)值時(shí)缤言,將執(zhí)行,一视事、使用獨(dú)占鎖鎖定行胆萧,記錄重做日志;二俐东、將修改前這一行的值復(fù)制到Undo日志跌穗;三、修改當(dāng)前行的值虏辫,填寫事務(wù)ID蚌吸,并使回滾指針指向撤銷日志中修改前的行。

接下來砌庄,與 事務(wù)1 相同羹唠。此時(shí)奕枢,undo 日志中有兩行記錄,它們由回滾指針連接肉迫。

因此验辞,如果撤消日志沒有一直被刪除,那么當(dāng)前記錄的回滾指針將追溯到創(chuàng)建該行時(shí)的初始內(nèi)容喊衫。InnoDB中有一個(gè)清除線程跌造,將查詢比最舊的活動(dòng)事務(wù)更早的撤消日志并將其刪除,從而確保撤消日志文件不會(huì)無限增長族购。

2壳贪、MVCC 實(shí)現(xiàn)原理

它的實(shí)現(xiàn)原理主要是依賴記錄中的 3個(gè)隱式字段(DB_ROW_ID、DB_TRX_ID寝杖、DB_ROLL_PT)违施,undo日志 , Read View 來實(shí)現(xiàn)的瑟幕。

上面我們已經(jīng)詳細(xì)介紹了3個(gè)隱式字段的含義磕蒲,總結(jié)一下

默認(rèn)情況下,DB_ROW_ID 是數(shù)據(jù)庫為這行記錄生成的唯一隱式主鍵只盹。DB_TRX_ID 是當(dāng)前操作記錄的事務(wù)ID辣往,而 DB_ROLL_PTR 是一個(gè)回滾指針,與撤消日志一起使用以指向以前的舊版本殖卑。

有兩種 undo 日志:insert undo log站削、update undo log,幫助MVCC的撤銷的本質(zhì)是update undo log 孵稽。事實(shí)上许起,撤消日志是回滾段中的舊記錄鏈。(MySQL日志系統(tǒng)的詳解:(待補(bǔ)充))菩鲜。

3园细、什么是 Read View

什么是 Read View

Read View 是事務(wù)執(zhí)行快照讀取操作時(shí)生成的視圖接校。在事務(wù)執(zhí)行快照讀取時(shí)珊肃,將生成數(shù)據(jù)庫系統(tǒng)的當(dāng)前快照,并記錄和維護(hù)系統(tǒng)當(dāng)前活動(dòng)事務(wù)的ID(當(dāng)每個(gè)事務(wù)啟動(dòng)時(shí)馅笙,將分配一個(gè)ID,該ID是增量的厉亏,因此最新事務(wù)的ID值更大)董习。

當(dāng)我們使用select讀取數(shù)據(jù)時(shí),此時(shí)會(huì)有許多版本的數(shù)據(jù)爱只,但我們不知道要讀取哪個(gè)版本皿淋。

此時(shí),我們依賴readview來限制我們可以讀取的版本。只有通過readview才能知道我們可以閱讀哪個(gè)版本窝趣。

3.1疯暑、Read View 解析

Read View主要用于進(jìn)行可見性判斷,也就是說哑舒,當(dāng)我們?yōu)槭聞?wù)執(zhí)行快照讀時(shí)妇拯,我們會(huì)為記錄創(chuàng)建一個(gè)讀取視圖 Read View。以判斷當(dāng)前事務(wù)可以看到哪個(gè)版本的數(shù)據(jù)洗鸵。它可能是當(dāng)前期間的最新數(shù)據(jù)越锈,也可能是記錄 undo log 中某個(gè)版本的數(shù)據(jù)。

讀取視圖遵循可見性算法膘滨,主要是要修改的數(shù)據(jù)的最新記錄中的 DB_TRX_ID (即當(dāng)前事務(wù)ID)甘凭,并與系統(tǒng)中其他活動(dòng)事務(wù)的ID(由讀取視圖 Read View 維護(hù))進(jìn)行比較。

如果 DB_TRX_ID 跟 Read View 屬性不符合可見性火邓,通過 DB_ROLL_PTR 回滾指針在撤消日志Undo Log中的 DB_TRX_ID 比較中檢索數(shù)據(jù)庫(遍歷鏈表的 DB_TRX_ID)丹弱。

遍歷鏈接列表的DB _ TRX_ ID(從鏈的開始到鏈的結(jié)束,即從最近的修改)铲咨,直到找到滿足特定條件的 DB_TRX_ID , 那么這個(gè) DB_TRX_ID 所在的舊記錄就是當(dāng)前事務(wù)能看見的最新老版本躲胳。

3.2、Read View 含義

在一個(gè) Read View 快照中主要包括以下這些字段:

m_ids鸣驱,表示生成 Read View 時(shí)當(dāng)前系統(tǒng)中活動(dòng)讀/寫事務(wù)的事務(wù)ID列表

min_trx_id泛鸟,表示生成 Read View 時(shí)當(dāng)前系統(tǒng)中活動(dòng)讀/寫事務(wù)中最小的事務(wù)ID,即 m_ids 最小值

max_trx_id踊东,表示生成 Read View 時(shí)應(yīng)分配給系統(tǒng)中下一個(gè)事務(wù)的ID值

creator_trx_id,表示生成 Read View 的事務(wù)的事務(wù)ID

3.3北滥、Read View 如何判斷版本鏈可用

trx_id == creator_trx_id,可以訪問這個(gè)版本闸翅;

trx_id < min_trx_id再芋,可以訪問這個(gè)版本;trx_id > max_trx_id坚冀,不可以訪問這個(gè)版本;

min_trx_id <= trx_id <= max_trx_id济赎,如果 trx_id 在 m_ids 中不可以訪問,反之可以

三记某、當(dāng)前讀司训,快照讀與MVCC

1、什么是當(dāng)前讀和快照讀

1.1液南、當(dāng)前讀

select lock in share mode (共享鎖), select for update; update; insert; delete (排他鎖)這些操作都是一種當(dāng)前讀壳猜。

它讀取最新版本的記錄,讀取時(shí)滑凉,它還確保其他并發(fā)事務(wù)無法修改當(dāng)前記錄统扳,并鎖定讀取的記錄喘帚。

1.2、快照讀

不加鎖的 select 操作就是快照讀咒钟,即無鎖的非阻塞讀却涤伞;

快照讀的前提是隔離級(jí)別不是串行級(jí)別朱嘴,在串行級(jí)別下讀取的快照將退化為當(dāng)前讀取倾鲫,發(fā)生快照讀的原因是基于提高并發(fā)性能的考慮。

快照讀的實(shí)現(xiàn)基于多版本并發(fā)控制腕够,即MVCC级乍。MVCC可以被認(rèn)為是行鎖的變體,但在許多情況下帚湘,它避免了鎖操作并減少了開銷玫荣;由于它基于多個(gè)版本,也就是說大诸,讀取的快照可能不是數(shù)據(jù)的最新版本捅厂,而是以前的歷史版本

MVCC的設(shè)計(jì)目的是在不鎖定讀寫沖突,這種讀取指的是快照讀取资柔,而不是當(dāng)前讀取焙贷。

當(dāng)前的讀取實(shí)際上是一個(gè)鎖操作,這是悲觀鎖的實(shí)現(xiàn)

2贿堰、快照讀辙芍、當(dāng)前讀與MVCC辨析

MVCC多版本并發(fā)控制的概念是“維護(hù)一個(gè)數(shù)據(jù)的多個(gè)版本,以便讀寫操作之間沒有沖突”羹与。

因?yàn)镸VCC只是一個(gè)抽象的概念故硅,為了實(shí)現(xiàn)這樣的概念,MySQL需要提供特定的功能來實(shí)現(xiàn)它纵搁〕孕疲“快照讀取是MySQL MVCC理想模型的非阻塞讀取功能之一”。

相對(duì)而言腾誉,當(dāng)前讀是悲觀鎖的具體功能實(shí)現(xiàn)徘层,快照閱讀本身也是一個(gè)抽象概念。

3利职、MVCC 只在 RC 和 RR 隔離級(jí)別下工作

一趣效、 在RC(Read Commited )的隔離級(jí)別下,每次快照讀取都會(huì)生成并獲得最新的 readview猪贪。

二英支、在RR(Repeatable Read)隔離級(jí)別,只有讀取同一事務(wù)的第一個(gè)快照才能創(chuàng)建 readview哮伟。每個(gè)后續(xù)快照讀取都使用相同的 readview干花,因此每個(gè)查詢結(jié)果都相同。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末楞黄,一起剝皮案震驚了整個(gè)濱河市池凄,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌鬼廓,老刑警劉巖肿仑,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異碎税,居然都是意外死亡尤慰,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門雷蹂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來伟端,“玉大人,你說我怎么就攤上這事匪煌≡痱穑” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵萎庭,是天一觀的道長霜医。 經(jīng)常有香客問我,道長驳规,這世上最難降的妖魔是什么肴敛? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮吗购,結(jié)果婚禮上医男,老公的妹妹穿的比我還像新娘。我一直安慰自己巩搏,他們只是感情好昨登,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著贯底,像睡著了一般丰辣。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上禽捆,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天笙什,我揣著相機(jī)與錄音,去河邊找鬼胚想。 笑死琐凭,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的浊服。 我是一名探鬼主播统屈,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼胚吁,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了愁憔?” 一聲冷哼從身側(cè)響起腕扶,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎吨掌,沒想到半個(gè)月后半抱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡膜宋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年窿侈,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片秋茫。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡史简,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出学辱,到底是詐尸還是另有隱情乘瓤,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布策泣,位于F島的核電站衙傀,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏萨咕。R本人自食惡果不足惜统抬,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望危队。 院中可真熱鬧聪建,春花似錦、人聲如沸茫陆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽簿盅。三九已至挥下,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間桨醋,已是汗流浹背棚瘟。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留喜最,地道東北人偎蘸。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親迷雪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子限书,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

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