?首先需要知道什么是 MVCC?
MVCC 多版本并發(fā)控制。MVCC就是通過數(shù)據(jù)行的多個版本管理來實現(xiàn)數(shù)據(jù)庫的并發(fā)控制。這項技術(shù)是的InnoDB的事務(wù)隔離級別下執(zhí)行一致性讀 有了保證。換言之,就是為了查詢一些正在被一個事務(wù)更新的行。并且可以看到他們被更新之前的值。查詢在做查詢的時候就不用等待 另一個事務(wù)釋放鎖。
MVCC在MySQL InnoDB中的實現(xiàn)主要是為了提高數(shù)據(jù)庫并發(fā)性能,用更好的方式就是 讀-寫 沖突,做到即使有多寫沖突時。也能做到 不加鎖,非阻塞并發(fā)讀,而這個讀指的就是 快照讀,當前讀實際時一種加鎖的操作,是悲觀鎖的實現(xiàn)。而MVCC本質(zhì)是采用悲觀鎖思想的一種方式。
對應(yīng)InnoDB來說,聚簇索引中的每個記錄都包含了兩個必要的隱藏字段:
??? trx_id:每次一個事務(wù)對某條聚簇索引記錄進行改動時,都會把該事務(wù)的事務(wù)id賦值給trx_id隱藏列。
??? roll_pointer:回滾指針,每次修改數(shù)據(jù)時,都會把舊數(shù)據(jù)放入undo log日志中,新的數(shù)據(jù)指向該舊數(shù)據(jù),做成一個版本鏈,該指針字段就稱為回滾指針,通過該指針可以找到修改前的數(shù)據(jù)。
四、Read View(讀視圖)
有了undo log日志就可以讀取記錄的歷史版本。但是如何去欸的那個具體的版本記錄?就需要用Read View記錄,他解決了行的可見性問題。
RC(讀已提交) 和 RR(可重復(fù)讀)必須要保證讀的數(shù)據(jù) 都是其他事務(wù)已經(jīng)提交的數(shù)據(jù)。所以,其他事務(wù)修改數(shù)據(jù),但是還未提交,我們不可以訪問此數(shù)據(jù)。但是可以通過MVCC可以訪問 對應(yīng)的歷史版本。核心問題:判斷版本鏈中的那條數(shù)據(jù) 對于當前事務(wù)是 可見的。這也是 ReadView 需要解決的問題。
ReadView 就是當某一個使用MVCC機制使用快照讀而形成的視圖。該試圖是當前所有 活躍事務(wù)id
組成一個列表的快照。(記錄版本鏈的統(tǒng)計信息)
??? m_trx_ids:表示在生成Read View時當前系統(tǒng)中活躍的事務(wù)id列表。提交了的事務(wù)不在其中。
??? min_trx__id:活躍的事務(wù)中最小的事務(wù)id。指的版本鏈的末尾
??? max_trx_id:表示生成Read View時系統(tǒng)應(yīng)該分配給下一個事務(wù)的id值,同樣也表示系統(tǒng)中最大的事務(wù)id值。
? creator_trx_id:表示生成該ReadView
的事務(wù)的事務(wù)id
具體ReadView的匹配規(guī)則用下來描述
解釋圖片中的具體數(shù):
圖片中的活躍事務(wù)(活躍事務(wù)= 讀未提交的事務(wù))有 90,100,200。
則對應(yīng)的 trx_ids? = (90,100,200)
min_trx_id =90,就是最小的事務(wù)號,也就是m_ids
中的最小值,則版本鏈的隊尾數(shù)據(jù)。
max_trx_id = 201. 是因為它為系統(tǒng)分配下一個事務(wù)的id。當前事務(wù)id=200.下一個就是201.并不是trx_ids中的最大值。最大值+1.
creator_trx_id:由于ReadView 是由當前事務(wù)創(chuàng)建,當前事務(wù)=201,所以 creatoe_trx_id = 201.
接下來就是 具體的匹配兜底規(guī)則:
需要理解的是:當前事務(wù)是201,我們需要判斷的是判斷鏈條中的那些數(shù)據(jù)可以訪問。(就是用 200,100,90)分別進行匹配兜底判斷。
1.如果被訪問版本的trx_id 等于 ReadView中的creator_trx_id ,就是說明當前事務(wù) 正在訪問被他自己修改的記錄,因此是可以訪問的。
2.如果被訪問版本的trx_id 小于 ReadView中的 min_trx_id,就是說明該版本的事務(wù) 在 生成ReadView之前就已經(jīng)提交,因此可以訪問的。
3.如果被訪問版本的trx_id 小于 ReadView中的 max_trx_id,就是說明該版本的事務(wù) 在 生成ReadView之后才開啟,因此是不可以訪問。
4.如果被訪問版本的trx_id
屬性值在ReadView
的min_trx_id
和max_trx_id
之間,那就需要判斷一下trx_id
屬性值是不是在m_ids
列表中,如果在,說明創(chuàng)建ReadView
時生成該版本的事務(wù)還是活躍的,該版本不可以被訪問;如果不在,說明創(chuàng)建ReadView
時生成該版本的事務(wù)已經(jīng)被提交,該版本可以被訪問。
?文章來源:http://www.zghlxwxcb.cn/news/detail-570193.html
- READ COMMITTED —— 每次讀取數(shù)據(jù)前都生成一個ReadView
- REPEATABLE READ —— 在第一次讀取數(shù)據(jù)時生成一個ReadView
?文章來源地址http://www.zghlxwxcb.cn/news/detail-570193.html
到了這里,關(guān)于面試之MySQL中的mvcc的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!