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

一、并發(fā)控制基本知識

? 數(shù)據(jù)庫是共享資源划址,通常有許多個事務(wù)同時(shí)在運(yùn)行,當(dāng)多個事務(wù)并發(fā)地存取同一個數(shù)據(jù)庫時(shí)就會產(chǎn)生沖突,若對并發(fā)操作不加控制就可能會存取和存儲不正確的數(shù)據(jù)评汰,破壞數(shù)據(jù)庫的一致性。所以數(shù)據(jù)庫管理系統(tǒng)必須提供并發(fā)控制機(jī)制痢虹。

當(dāng)多個事務(wù)同時(shí)對數(shù)據(jù)庫進(jìn)行操作時(shí)被去,會出現(xiàn)3種沖突情形:

  1. 讀-讀:不存在任何問題。
  2. 讀-寫:有隔離性問題奖唯,可能遇到臟讀(會讀到未提交的數(shù)據(jù))惨缆,幻影讀等。
  3. 寫-寫:可能丟失更新數(shù)據(jù)丰捷。

1.1 讀寫鎖

? 為了最大化數(shù)據(jù)庫事務(wù)的并發(fā)能力坯墨,數(shù)據(jù)庫在處理并發(fā)讀或者寫的時(shí)候,可以通過一個由兩種類型的鎖組成的鎖系統(tǒng)來解決問題病往,這兩種類型的鎖分別是共享鎖和互斥鎖捣染,也叫做讀鎖和寫鎖。

? 讀鎖是共享的停巷,多個客戶在同一時(shí)刻讀取同一個資源的時(shí)候液斜,互不干擾。寫鎖是排他的叠穆,一個寫鎖會阻塞其他讀鎖以及其他寫鎖少漆,保證在給定的時(shí)間段中,只能有一個用戶能執(zhí)行寫入操作硼被。

1.2 鎖粒度與鎖策略

? 鎖粒度顧名思義就是加鎖時(shí)需要鎖住的范圍有多大(讓鎖對象更有選擇性)示损,這個概念的提出是為了提高共享資源的并發(fā)性,只對需要修改的資源進(jìn)行精確的鎖定嚷硫。

? 鎖策略就是在鎖的開銷和數(shù)據(jù)的安全性之間尋求平衡检访。因?yàn)樵诩渔i的時(shí)候也需要消耗資源,鎖的各種操作仔掸,包括獲得鎖脆贵、檢查鎖是否已經(jīng)解除、釋放鎖等起暮,都會增加系統(tǒng)的開銷卖氨。如果系統(tǒng)花費(fèi)大量的時(shí)間來管理鎖,而不是存取數(shù)據(jù),那么系統(tǒng)的性能可能會因此受到影響筒捺。

1.3 表鎖與行級鎖

? 表鎖與行級鎖是兩種比較重要鎖策略(MySQL中還有一種為頁級鎖)柏腻。

? 表鎖是MySQL中最基本的鎖策略,鎖定是MySQL各存儲引擎中最大顆粒度的鎖定機(jī)制(每次鎖定一張表)系吭。該鎖定機(jī)制最大的特點(diǎn)是實(shí)現(xiàn)邏輯非常簡單五嫂,帶來的系統(tǒng)負(fù)面影響最小。所以獲取鎖和釋放鎖的速度很快肯尺。由于表級鎖一次會將整個表鎖定沃缘,所以可以很好的避免死鎖問題。使用表級鎖定的主要是MyISAM则吟,MEMORY孩灯,CSV等一些非事務(wù)性存儲引擎。

? 行級鎖可以最大程度的支持并發(fā)處理逾滥,同時(shí)鎖定對象的顆粒度很小峰档,也是目前各大數(shù)據(jù)庫管理軟件所實(shí)現(xiàn)的鎖定顆粒度最小的。雖然能夠在并發(fā)處理能力上面有較大的優(yōu)勢寨昙,但是行級鎖定也因此帶來了不少弊端讥巡。由于鎖定資源的顆粒度很小,所以每次獲取鎖和釋放鎖需要的開銷更大了舔哪。此外欢顷,行級鎖定也最容易發(fā)生死鎖。使用行級鎖定的主要是InnoDB存儲引擎捉蚤。

二抬驴、MVCC

? MVCC,多版本的并發(fā)控制,英文全稱:Multi Version Concurrency Control缆巧。是數(shù)據(jù)庫中常用的解決讀-寫沖突的操作布持。前面提到,行級鎖是主要用于處理事務(wù)的鎖陕悬,但是在MySQL中大多事務(wù)型存儲引擎實(shí)現(xiàn)的都不是簡單的行級鎖题暖,而是多版本并發(fā)控制(MVCC),可以簡單的認(rèn)為MVCC是行級鎖的一個變種捉超。除了MySQL胧卤,其他數(shù)據(jù)庫也實(shí)現(xiàn)了MVCC,但是各自的實(shí)現(xiàn)機(jī)制不同拼岳,沒有一個統(tǒng)一的標(biāo)準(zhǔn)枝誊。

? 在MVCC中,很多情況下都避免了加鎖操作惜纸,因此開銷更低叶撒,大多數(shù)標(biāo)準(zhǔn)的MVCC都實(shí)現(xiàn)令非阻塞的讀操作绝骚,寫操作也只鎖定必要的行。

? MVCC的實(shí)現(xiàn)痊乾,是通過保存數(shù)據(jù)在某個時(shí)間點(diǎn)的快照實(shí)現(xiàn)的。就是當(dāng)我們在修改數(shù)據(jù)的時(shí)候椭更,可以為這條數(shù)據(jù)創(chuàng)建一個快照哪审,后面就可以直接讀取這個快照。

2.1InnoDB MVCC實(shí)現(xiàn)原理

? 在InnoDB的MVCC虑瀑,是通過每行記錄后面保存的兩個隱藏列實(shí)現(xiàn)的湿滓。

? 每一行記錄都有兩個隱藏列: DATA_TRX_ID(保存了行的建立時(shí)間)、 DATA_ROLL_PTR(保持了行的過期時(shí)間或刪除時(shí)間)舌狗。保存的時(shí)間值指的是系統(tǒng)版本號而不是真正的時(shí)間叽奥,同時(shí)每開始一個新的事務(wù)時(shí),系統(tǒng)的版本號就會遞增痛侍。

? 在進(jìn)行事務(wù)的操作前朝氓,MVCC設(shè)置了以下規(guī)則:

SELECT

? InnoDB會根據(jù)以下兩個條件檢查每行紀(jì)錄:

  1. InnoDB只查找版本早于當(dāng)前事務(wù)版本的數(shù)據(jù)行,即主届,行的系統(tǒng)版本號小于或等于事務(wù)的系統(tǒng)版本號赵哲,這樣可以確保事務(wù)讀取的行,要么是在事務(wù)開始前已經(jīng)存在的君丁,要么是事務(wù)自身插入或者修改過的枫夺。

  2. 行的刪除版本,要么未定義绘闷,要么大于當(dāng)前事務(wù)版本號橡庞。這樣可以確保事務(wù)讀取到的行,在事務(wù)開始之前未被刪除印蔗。

    只有符合上述兩個條件的紀(jì)錄扒最,才能作為查詢結(jié)果返回。

INSERT

? InnoDB為插入的每一行保存當(dāng)前系統(tǒng)版本號作為行版本號华嘹。

DELETE

? InnoDB為刪除的每一行保存當(dāng)前系統(tǒng)版本號作為行刪除標(biāo)識扼倘。

UPDATE

? InnoDB為插入一行新紀(jì)錄,保存當(dāng)前系統(tǒng)版本號作為行版本號除呵,同時(shí)再菊,保存當(dāng)前系統(tǒng)版本號到原來的行作為行刪除標(biāo)識。

2.2 InnoDB MVCC實(shí)現(xiàn)實(shí)例

? 首先需要了解的一個概念是ReadView颜曾,ReadView中主要就是有個列表來存儲我們系統(tǒng)中當(dāng)前活躍著的讀寫事務(wù)纠拔,也就是開始了還未提交的事務(wù)。通過這個列表來判斷記錄的某個版本是否對當(dāng)前事務(wù)可見泛豪。

? 以可重復(fù)讀隔離級別為例稠诲,假設(shè)當(dāng)前列表里的事務(wù)id為[80,100]侦鹏。在可重復(fù)讀隔離級別,這時(shí)候我的ReadView還是第一次select時(shí)候生成的ReadView,也就是列表的值還是[100]臀叙。當(dāng)我需要執(zhí)行一次select語句時(shí)

? 1.如果我需要訪問的記錄版本的事務(wù)id為50略水,比當(dāng)前列表最小的id80小,那說明這個事務(wù)在之前就提交了劝萤,所以對當(dāng)前活動的事務(wù)來說是可訪問的渊涝。

? 2.如果我需要訪問的記錄版本的事務(wù)id為70,發(fā)現(xiàn)此事務(wù)在列表id最大值和最小值之間,那就再判斷一下是否在列表內(nèi)床嫌,如果在那就說明此事務(wù)還未提交跨释,所以版本不能被訪問。如果不在那說明事務(wù)已經(jīng)提交厌处,所以版本可以被訪問鳖谈。

? 3.如果我要訪問的記錄版本的事務(wù)id為110,那比事務(wù)列表最大id100都大阔涉,那說明這個版本是在ReadView生成之后才發(fā)生的缆娃,所以不能被訪問。

2.3 MVCC特點(diǎn)

? 在MVCC中瑰排,不管執(zhí)行多少時(shí)間龄恋,每個事務(wù)看到的數(shù)據(jù)都是一致的;而根據(jù)事務(wù)開始的時(shí)間不同凶伙,每個事務(wù)對同一張表郭毕,看到的同一時(shí)間看到的數(shù)據(jù)也不同。

? MVCC在大多數(shù)情況下代替了行鎖函荣,實(shí)現(xiàn)了對讀的非阻塞显押,讀不加鎖,讀寫不沖突傻挂。缺點(diǎn)是每行記錄都需要額外的存儲空間乘碑,需要做更多的行維護(hù)和檢查工作。MVCC手段只適用于Msyql隔離級別中的讀已提交(Read committed)和可重復(fù)讀(Repeatable Read)金拒,因?yàn)樽x未提交會讀取最新的數(shù)據(jù)行兽肤,而可串行化則會將讀取的行都加鎖。

三绪抛、補(bǔ)充

? 在并發(fā)控制中资铡,要解決沖突,總共由三種方式:

? 1.(悲觀)鎖幢码,即基于鎖的并發(fā)控制笤休,比如2PL,這種方式開銷比較高症副,而且無法避免死鎖店雅。

? 2.多版本并發(fā)控制(MVCC)政基,是一種用來解決讀-寫沖突的無鎖并發(fā)控制。

? 3.樂觀并發(fā)控制(OCC)是一種用來解決寫-寫沖突的無鎖并發(fā)控制闹啦,認(rèn)為事務(wù)間爭用沒有那么多沮明,所以先進(jìn)行修改,在提交事務(wù)前窍奋,檢查一下事務(wù)開始后荐健,有沒有新提交改變,如果沒有就提交费变,如果有就放棄并重試摧扇。樂觀并發(fā)控制類似自選鎖圣贸。樂觀并發(fā)控制適用于低數(shù)據(jù)爭用挚歧,寫沖突比較少的環(huán)境。

? 在使用MVCC控制的時(shí)候吁峻,可以以結(jié)合基于鎖的并發(fā)控制來解決寫-寫沖突滑负,即MVCC+2PL;也可以結(jié)合樂觀并發(fā)控制來解決寫-寫沖突用含。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末矮慕,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子啄骇,更是在濱河造成了極大的恐慌痴鳄,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件缸夹,死亡現(xiàn)場離奇詭異痪寻,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)虽惭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進(jìn)店門橡类,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人芽唇,你說我怎么就攤上這事顾画。” “怎么了匆笤?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵研侣,是天一觀的道長。 經(jīng)常有香客問我炮捧,道長义辕,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任寓盗,我火速辦了婚禮灌砖,結(jié)果婚禮上璧函,老公的妹妹穿的比我還像新娘。我一直安慰自己基显,他們只是感情好蘸吓,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著撩幽,像睡著了一般库继。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上窜醉,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天宪萄,我揣著相機(jī)與錄音,去河邊找鬼榨惰。 笑死拜英,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的琅催。 我是一名探鬼主播居凶,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼藤抡!你這毒婦竟也來了侠碧?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤缠黍,失蹤者是張志新(化名)和其女友劉穎弄兜,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瓷式,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡替饿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蒿往。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片盛垦。...
    茶點(diǎn)故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖瓤漏,靈堂內(nèi)的尸體忽然破棺而出腾夯,到底是詐尸還是另有隱情,我是刑警寧澤蔬充,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布蝶俱,位于F島的核電站,受9級特大地震影響饥漫,放射性物質(zhì)發(fā)生泄漏榨呆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一庸队、第九天 我趴在偏房一處隱蔽的房頂上張望积蜻。 院中可真熱鬧闯割,春花似錦、人聲如沸竿拆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽丙笋。三九已至谢澈,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間御板,已是汗流浹背锥忿。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留怠肋,地道東北人敬鬓。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像灶似,于是被迫代替她去往敵國和親列林。 傳聞我的和親對象是個殘疾皇子瑞你,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評論 2 355