java面試一日一題:講對mysql的MVCC的理解


問題:請講下對mysql中MVCC的理解

分析:這個問題要回答的是對MVCC的理解,以及MVCC解決了什么問題這幾個方面入手。

回答要點:

主要從以下幾點去考慮,

1、什么是MVCC?

2、MVCC用來解決什么問題?

3、MVCC是怎么實現的?

 

所謂MVCC,在mysql中指的是multi version concurrency control,即多版本並發控制。多版本比較好理解就是有多個版本,那么是指的什么有多個版本,這里指的是數據行,mysql中的數據行有多個版本,再看后面的並發控制,即對數據的行的讀取和更新要並發控制,並發控制的目的是為了多線程下的數據安全,就像在java環境下的多線程安全,這里並不是指線程安全,而是指多個線程下的數據隔離級別。

MVCC只有在讀已提交和可重復讀兩種隔離級別下才有效。我們都知道在讀已提交隔離級別下解決了臟讀,但存在不可重復讀及幻讀的情況,在可重復讀隔離級別下解決了不可重復讀和幻讀(如何解決的下篇文章分享),下面就看下在這兩個隔離級別下MVCC是如何其作用的。

MVCC的實現是通過undo log和read view來實現的

在innodb引擎下的表,每個數據行都有隱藏的兩列,一列是trx_id,也就是更新(insert、update、delete)這條記錄的事務ID;一列是roll_pointer,指向上次修改的指針,如果是新增的則為null;如果不存在主鍵的話,還會有第三列row_id,在沒有主鍵的情況下默認生成的主鍵;

我們都知道在mysql的事務日志中有redo log和undo log,redo log記錄的是真實改變的值,而undo log記錄的是和操作相反的操作,由於一條記錄可能會被修改多次,這些修改連在一起就形成了一個版本鏈,這個版本鏈就是MVCC實現的基礎。

如下就是一個版本鏈

其中最后兩列一個是trx_id,一個是roll_pointer。有了版本鏈,還有一個read view,看這是什么概念,翻譯過來叫一致性視圖,一致性視圖中有以下幾個屬性比較重要,

m_ids,在生成read view時當前活躍的讀寫事務的列表

min_trx_id,m_ids中最小的

max_trx_id,m_ids中最大的+1

版本鏈中的trx_id是否對當前事務可見通過以下的規則進行判斷,

trx_id<min_trx_id 表示數據中的事務ID比當前活躍的事務id最小的還小,代表該記錄在生成readview的時候已經提交,那么是可見的;

trx_id>=max_trx_id 表示數據中的事務ID比當前活躍的事務id最大的還大,代表該記錄在生成readview后提交的,那么是不可見的;

min_trx_id<=trx_id<max_trx_id 當trx_id在m_ids中表示,該事務還未提交,那么是不可見的;當trx_id不在m_ids中,說明已經提交了,那么是可見的;

如果某個版本的數據對當前事務是不可見的,那么就要順着版本鏈繼續查找下個版本,直到找到可見的版本。

 

那么在讀已提交和可重復讀下是如何實現的,在讀已提交下,是每次select都會生成read view,所以可以讀到提交的數據;在可重復讀隔離級別下,是在第一次select的時候生成read view,以后的select都是使用第一次生成的read view,所以解決了不可重復讀。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM