MySQL -- MVCC

前言

最近在學(xué)MySQL肩钠,決定記錄一下碾褂,能寫多少寫多少兽间,不定時(shí)更新,加油正塌。

正文

分幾個(gè)部分來吧嘀略,大致如下:

  • 字符集與比較規(guī)則

  • 行格式與數(shù)據(jù)頁

  • InnoDB索引

  • 訪問方法與連接

  • explain 與 子查詢優(yōu)化

  • redoundo 日志

  • MVCC 與 鎖

本文為第四部分 MVCC 原理解析


主要就是想先寫這個(gè), 其他的后面有空再補(bǔ)~

由于我們跳過一些東西, 下面說MVCC的原理可能會(huì)各種懵


所以, 我們先簡單過幾個(gè)點(diǎn)吧.

一恤溶、溫故知新 -- 兩個(gè)隱藏列的含義

行格式的時(shí)候說過,InnoDB會(huì)為每行加上兩個(gè)隱藏列(row_id并不是必加的)trx_idroll_pointer 這倆哥們簡直生猛的一塌糊涂.

小聲明:
事務(wù)T1的編號(hào)是100
事務(wù)T2的編號(hào)是200

  • trx_id 這個(gè)明顯是事務(wù)ID的意思, 就是記錄一下最近操作此條記錄的事務(wù)ID. 比如事務(wù)T1中插入了一條記錄X,那X的trx_id就是100,如果在T1中繼續(xù)操作這條記錄是不會(huì)修改X的trx_id的.如果事務(wù)T2修改了這X記錄,那么其trx_id就變成200.
  • roll_pointer字面意思就是回滾指針, 指針存放的是一個(gè)地址, 指向了某個(gè)值. 它指向的是一條undo日志記錄.

這里簡單提一下undo日志,后面會(huì)專門寫一篇詳細(xì)講的[有生之年系列]帜羊。

一條undo日志就是一條記錄, 存放在頁中,叫undo日志頁.大致分為兩種,插入類型(insert)和修改類型(update咒程、delete),這里只需要知道他們有一個(gè)很大區(qū)別:插入類型的undo日志是沒有指向下一條undo日志的屬性的,也就是說他們組成了一個(gè)undo日志鏈表讼育,又稱版本鏈帐姻。

undo日志鏈表(版本鏈)
  • 第一條是真實(shí)記錄,0是記錄類型奶段,H是記錄頭饥瓷,300是trx_id R是roll_pointer, 1、3.. 是記錄的真實(shí)數(shù)據(jù)
  • 可以看到每條undo日志都有一個(gè)事務(wù)ID(圖中我畫在最后面,實(shí)際并不是存在最后),這個(gè)屬性其實(shí)是叫old trx_id, 表示當(dāng)前undo日志對(duì)應(yīng)的事務(wù)ID痹籍,也稱此版本的創(chuàng)建事務(wù)ID
  • 插入類型undo日志沒有old roll_pointer指向上一條roll_pointer呢铆,因?yàn)樗緛砭褪?code>版本鏈的第一條
  • 這條undo鏈表可以看出,此記錄由事務(wù)ID為100的事務(wù)插入蹲缠,在事務(wù)ID為200的事務(wù)中修改了兩次棺克,而事務(wù)ID為300的事務(wù)正在修改此記錄。
  • 記住這個(gè)順序线定,后面有用娜谊。

二、老生常談 -- 隔離級(jí)別

說這個(gè)隔離級(jí)別之前斤讥,我們先想想為什么要有這個(gè)東東纱皆?

其實(shí)每個(gè)新技術(shù)或新名詞的出現(xiàn), 都可以問這幾個(gè)問題
1.這個(gè)東東解決了什么問題嗎?
2.現(xiàn)有的技術(shù)解決不了嗎?
3.如果能, 它比當(dāng)前的解決方案強(qiáng)在哪些方面呢?
4.不足或改進(jìn)之處.

  • 以上純屬扯淡

隨著互聯(lián)網(wǎng)的發(fā)展,并發(fā)已經(jīng)是一道繞不開的坎周偎。各種問題都不斷冒出來,那并發(fā)事務(wù)訪問數(shù)據(jù)庫會(huì)發(fā)生什么樣的問題呢撑帖?

一個(gè)一個(gè)來看下蓉坎。

  • 臟寫(Dirty Write
    T1事務(wù)開啟
    T1修改:X=5
    T2事務(wù)開始
    T2修改:X=6
    T2事務(wù)提交
    T1事務(wù)提交

結(jié)果:X=5

這個(gè)時(shí)候T2的事務(wù)所做修改就丟失了.

一個(gè)事務(wù)修改了另一個(gè)未提交事務(wù)修改過的數(shù)據(jù),此為臟寫胡嘿。

  • 臟讀(Dirty Read
    數(shù)據(jù)狀態(tài):X=5
    T1事務(wù)開啟
    T2事務(wù)開始
    T2修改:X=6
    T1讀闰劝:X=6
    T2事務(wù)回滾
    T1事務(wù)提交

T1讀到的X=6,庫中X=5

一個(gè)事務(wù)讀取了另一個(gè)未提交事務(wù)修改過的數(shù)據(jù)衷敌,此為臟讀勿侯。

  • 不可重復(fù)讀(Non-Repeatable Read
    事務(wù)T1開啟
    事務(wù)T2開啟
    T1讀取:X=5
    T2修改:X=6
    事務(wù)T2提交
    T1讀冉陕蕖:X=6
    助琐。。面氓。

T1兩次讀取到的同一條記錄的值不一樣兵钮。

每次事務(wù)提交后蛆橡,當(dāng)前事務(wù)都能讀取到記錄的最新值,此為不可重復(fù)讀掘譬。

  • 幻讀(Phantom
    庫中數(shù)據(jù): X=6
    事務(wù)T1開啟
    事務(wù)T2開啟
    T1讀忍┭荨:X>5 (得到一條X=6)
    T2新增:X=7
    T1讀取:X>5 (得到兩條X=6和X=7)
    葱轩。睦焕。。

T1第二次讀取的記錄數(shù)量比第一次讀取到的記錄數(shù)量多靴拱。

如果事務(wù)T1根據(jù)條件N查詢數(shù)據(jù)垃喊,事務(wù)T2添加了滿足條件N的記錄并提交了,T1再次根據(jù)N查詢數(shù)據(jù)能查詢T2新增的記錄缭嫡,此為幻讀缔御。

注意幾個(gè)點(diǎn):

  • 不可重復(fù)讀是針對(duì)單條記錄的改動(dòng)(包括刪除與修改)
  • 幻讀是針對(duì)查詢條件的范圍內(nèi)記錄的新增
  • 幻讀只是針對(duì)新增,如果有范圍內(nèi)記錄的刪除或修改妇蛀,都屬于不可重復(fù)讀

為了解決這些問題耕突,有一幫人提出了一個(gè)SQL標(biāo)準(zhǔn),給出了四種隔離級(jí)別评架,用以解決上訴問題:

  • READ UNCOMMITTED
  • READ COMMITTED
  • READ REPEATABLE
  • SERIALABLE

SQL標(biāo)準(zhǔn)中規(guī)定眷茁,

  • READ UNCOMMITTED 解決臟寫
  • READ COMMITTED 解決臟讀
  • READ REPEATABLE 解決臟讀與不可重復(fù)讀
  • SERIALABLE 解決幻讀

數(shù)據(jù)庫對(duì)臟寫的問題是零容忍,哪怕最低的隔離級(jí)別都不允許出現(xiàn)

然而MySQL里的大佬還是牛逼纵诞,他們?cè)?code>READ REPEATABLE 級(jí)別就已經(jīng)解決了幻讀問題上祈。

實(shí)現(xiàn)一般有兩種方式,第一是加鎖浙芙,第二是MVCC登刺。

實(shí)際上,二者都有用到.


三嗡呼、千呼萬喚 -- MVCC的原理

ReadView登場(chǎng)

先看下其大致結(jié)構(gòu)

ReadView結(jié)構(gòu)
  • m_ids 存放當(dāng)前系統(tǒng)中活躍的事務(wù)集合
  • min_trx_idm_ids中最小的事務(wù)ID
  • max_trx_id 分配給下一個(gè)開啟事務(wù)的事務(wù)ID
  • creator_trx_id 創(chuàng)建此ReadView的事務(wù)ID

事務(wù)ID注意兩點(diǎn):

  • 只有在對(duì)表中的記錄做改動(dòng)時(shí)(執(zhí)行INSERT纸俭、DELETEUPDATE這些語句時(shí))才會(huì)為事務(wù)分配事務(wù)id南窗,否則在一個(gè)只讀事務(wù)中的事務(wù)id值都默認(rèn)為0揍很。
  • 按分配順序遞增

怎么突然蹦出來一個(gè)ReadView? 先看看怎么用.

如果你不是一條魚的話,應(yīng)該還記得前面說過万伤,每條記錄都有一個(gè)版本鏈吧窒悔,當(dāng)一個(gè)事務(wù)要訪問某條記錄時(shí),對(duì)著這個(gè)ReadView的操作是這樣的:

  • 判斷trx_idcreator_trx_id是否相等敌买,是則意味著此版本正在被當(dāng)前事務(wù)操作简珠,可以訪問
  • 判斷trx_id是否小于min_trx_id,表示此版本的生成事務(wù)已經(jīng)提交虹钮,可以訪問
  • 判斷trx_id是否大于等于max_trx_id北救,表示此版本的生成事務(wù)已經(jīng)提交荐操,可以訪問
  • 判斷trx_id是否在m_ids中,若不在珍策,則意味著此版本的創(chuàng)建事務(wù)已經(jīng)提交托启,可以訪問;若在攘宙,則表明此版本在創(chuàng)建ReadView時(shí)還在活動(dòng)屯耸,不能訪問。

若無法訪問則順著版本鏈找下一個(gè)版本蹭劈,如果到最后一個(gè)版本(也就是Insert的undo日志)仍無法訪問疗绣,那么此記錄對(duì)當(dāng)前事務(wù)不可見。

現(xiàn)在知道這玩意有多牛逼了吧~

那跟隔離級(jí)別有啥關(guān)系呢铺韧?

READ COMMITTEDREAD REPEATABLE 的最大區(qū)別就是生成ReadView的時(shí)機(jī)不一樣

  • READ REPEATABLE 事務(wù)開啟時(shí)生成
  • READ COMMITTED 每次查詢前生成

想想ReadView與其生成時(shí)機(jī)如何能解決臟讀/幻讀問題~


喊我來加班多矮,到公司都寫完一篇MVCC了,還沒見到人~~~~[允悲]

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末哈打,一起剝皮案震驚了整個(gè)濱河市塔逃,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌料仗,老刑警劉巖湾盗,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異立轧,居然都是意外死亡格粪,警方通過查閱死者的電腦和手機(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
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼喘蟆!你這毒婦竟也來了缓升?” 一聲冷哼從身側(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)容

  • 什么是事務(wù) 事務(wù)是一條或多條數(shù)據(jù)庫操作語句的組合谜叹,具備ACID匾寝,4個(gè)特點(diǎn)。 原子性:要不全部成功荷腊,要不全部撤銷 隔...
    jiangmo閱讀 1,086評(píng)論 0 3
  • MVCC(Mutil-Version Concurrency Control)艳悔,就是多版本并發(fā)控制。MVCC 是一...
    yes的練級(jí)攻略閱讀 1,662評(píng)論 2 2
  • MVCC: 1什么是MVCC? MVCC是一種多版本并發(fā)控制機(jī)制女仰。 2 MVCC的作用猜年? 鎖的開銷畢竟很大...
    機(jī)智的老劉明同志閱讀 987評(píng)論 0 3
  • 1.Mysql特點(diǎn) 可靠、事務(wù)疾忍、開源乔外。 2.MySQL架構(gòu) 接入層,連接通信一罩、權(quán)限驗(yàn)證杨幼、連接池、線程管理 服務(wù)層聂渊,...
    不是明天閱讀 4,452評(píng)論 1 0
  • MVCC(Multi Version Concurrency Control的簡稱)差购,代表多版本并發(fā)控制。與MVC...
    漿水面韭菜花閱讀 58,435評(píng)論 21 87