MVVC概念
Multi-Version Concurrency Control :多版本并發(fā)控制
-
優(yōu)勢(shì):
允許多個(gè)版本同時(shí)存在生蚁,并發(fā)執(zhí)行肋拔。
不依賴鎖機(jī)制氛魁,性能高。
只在RC與RR級(jí)別下工作(其他隔離級(jí)別沒有意義)乖篷。
只有在InnoDB下支持。
實(shí)現(xiàn)原理
1. 隱藏列
InnoDB存儲(chǔ)引擎中透且,它的聚簇索引記錄中都包含兩個(gè)必要的隱藏列(row_id
并不是必要的撕蔼,我們創(chuàng)建的表中有主鍵或者非NULL的UNIQUE鍵時(shí)都不會(huì)包含row_id
列):
trx_id
:每次一個(gè)事務(wù)對(duì)某條聚簇索引記錄進(jìn)行改動(dòng)時(shí),都會(huì)把該事務(wù)的事務(wù)id
賦值給trx_id
隱藏列秽誊。roll_pointer
:每次對(duì)某條聚簇索引記錄進(jìn)行改動(dòng)時(shí)鲸沮,都會(huì)把舊的版本寫入到undo日志
中,然后這個(gè)隱藏列就相當(dāng)于一個(gè)指針锅论,可以通過(guò)它來(lái)找到該記錄修改前的信息讼溺。
當(dāng)MVCC數(shù)據(jù)庫(kù)需要對(duì)一條記錄操作的時(shí)候,它不會(huì)直接在老的數(shù)據(jù)上行直接修改最易,而是創(chuàng)建新的數(shù)據(jù)行怒坯,包含上述兩個(gè)字段,這樣儲(chǔ)存多個(gè)版本的數(shù)據(jù)藻懒,就有效的防止了并發(fā)讀寫的問題剔猿。
2.事務(wù)鏈
每次對(duì)記錄進(jìn)行改動(dòng),都會(huì)記錄一條undo日志
嬉荆,每條undo日志
也都有一個(gè)roll_pointer
屬性(INSERT
操作對(duì)應(yīng)的undo日志
沒有該屬性归敬,因?yàn)樵撚涗洸]有更早的版本),可以將這些undo日志
都連起來(lái),串成一個(gè)鏈表汪茧。
ReadView
對(duì)于RU
級(jí)別的事務(wù)椅亚,每次都可以讀取到未提交的修改記錄,而SERIALIZABLE
級(jí)別下通過(guò)加鎖來(lái)訪問記錄舱污。而在RC
與RR
級(jí)別下都要讀取到已經(jīng)提交的記錄什往,也就是說(shuō)假如另一個(gè)事務(wù)已經(jīng)修改了記錄但是尚未提交,是不能直接讀取最新版本的記錄的慌闭,核心問題就是:需要判斷一下版本鏈中的哪個(gè)版本是當(dāng)前事務(wù)可見的别威。為此,設(shè)計(jì)InnoDB
的大叔提出了一個(gè)ReadView
的概念驴剔,這個(gè)ReadView
中主要包含4個(gè)比較重要的內(nèi)容:
m_ids
:表示在生成ReadView
時(shí)當(dāng)前系統(tǒng)中活躍的讀寫事務(wù)的事務(wù)id
列表省古。min_trx_id
:表示在生成ReadView
時(shí)當(dāng)前系統(tǒng)中活躍的讀寫事務(wù)中最小的事務(wù)id
,也就是m_ids
中的最小值丧失。max_trx_id
:表示生成ReadView
時(shí)系統(tǒng)中應(yīng)該分配給下一個(gè)事務(wù)的id
值豺妓。
對(duì)于RC與RR他們的區(qū)別是:
RC級(jí)別下可以讀取別的事務(wù)提交后的修改,而RR級(jí)別讀取不到布讹。
之所以有這個(gè)差別是因?yàn)椋核麄兩蒖eadView的時(shí)機(jī)不同:
在RC下:每個(gè)select都會(huì)創(chuàng)建一個(gè)ReadView琳拭,也就是說(shuō)每個(gè)select語(yǔ)句都會(huì)讀取目前已經(jīng)提交的新數(shù)據(jù)。
在RR下:當(dāng)事務(wù)的第一個(gè)select語(yǔ)句后創(chuàng)建一個(gè)ReadView描验,之后讀取的都是這個(gè)ReadView白嘁。
快照讀與當(dāng)前讀
在RR級(jí)別下快照讀(snapshot read)
是通過(guò)MVCC與undo log實(shí)現(xiàn)的,它能防止不可重復(fù)讀問題膘流,缺不能杜絕幻讀絮缅。
當(dāng)前讀(current read)
通過(guò)record lock與gap lock實(shí)現(xiàn),可以杜絕幻讀問題呼股。
https://dev.mysql.com/doc/refman/5.7/en/innodb-multi-versioning.html