Mysql MVCC機制原理詳解

2022-09-21 23:39:09 字數 2306 閱讀 4530

mvcc,全稱multi-version concurrency control,即多版本併發控制。mvcc是一種併發控制的方法,一般在資料庫管理系統中,實現對資料庫的併發訪問,在程式語言中實現事務記憶體。

我們知道,一般情況下我們使用mysql資料庫的時候使用的是innodb儲存引擎,innodb儲存引擎是支援事務的,那麼當多執行緒同時執行事務的時候,可能會出現併發問題。這個時候需要乙個能夠控制併發的方法,mvcc就起到了這個作用。

在理解mvcc機制的原理之前,需要先理解mysql的鎖機制和事務的隔離級別,拋開myisam儲存引擎不談,就innodb儲存引擎來說,分別有行鎖和表鎖兩種鎖,表鎖就是一次操作鎖住整張表,這樣鎖的粒度最大,但是效能也最低,不會出現死鎖。行鎖就是一次操作鎖住一行,這樣鎖的粒度小,併發度高,但是會出現死鎖。

innodb的行鎖又分為共享鎖(讀鎖)和排它鎖(寫鎖),當乙個事務對某一行加了讀鎖時,允許其他事務對這一行進行讀操作,但是不允許進行寫操作,也不允許其他事務對這一行執行加寫鎖,但是可以加讀鎖。

當乙個事務對某一行加了寫鎖時,不允許其他事務對這一行進行寫操作,但是可以讀,同時不允許其他事務對這一行加讀寫鎖。

下面來看一下mysql的事務隔離級別,分為以下四種:

mvcc底層依賴mysql的undo log,undo log記錄了資料庫的操作,因為undo log是邏輯日誌,可以理解為delete一條記錄的時候,undo log會記錄一條對應的insert記錄,update一條記錄的時候,undo log會記錄一條相反的update記錄,當事務失敗需要回滾操作時,就可以通過讀取undo log中相應的內容進行回滾,mvcc就利用到了undo log。

mvcc的實現,利用到了資料庫的隱式字段,undo log和readview。首先來看隱式字段,其實mysql在表中的每行記錄的後面,都隱式的記錄了db_trx_id(最近修改(修改/插入)事務id),db_roll_ptr(回滾指標,指向這條記錄的上乙個版本),db_row_id(自增id,如果資料表沒有主鍵,則預設以此id簡歷聚簇索引)這幾個隱藏的字段。

undo log分為兩種,分別為insert undo log,在insert新記錄時產生的undo log, 只在事務回滾時需要,並且在事務提交後可以被立即丟棄,還有update undo log,事務在進行update或delete時產生的undo log; 不僅在事務回滾時需要,在快照讀時也需要;所以不能隨便刪除,只有在快速讀或事務回滾不涉及該日誌時,對應的日誌才會被purge執行緒統一清除。mvcc利用到的是update undo log。

實際上undo log記錄的是乙個版本鏈,假設資料庫中有一條記錄如下:

現在有乙個事務a修改了這條記錄,把name改為tom,這個時候的操作流程為:

此時的情況如下:

此時又有乙個事務b來修改這條記錄,把age改為28,這時候的操作流程為:

此時的情況如下:

從上面我們可以看到,不同的事務或者相同的事務對同一行記錄進行的修改,會使得該行記錄的undo log形成乙個版本鏈,undo log的鏈首就是最近一次的舊記錄,而鏈尾就是最早一次的舊記錄。

現在我們來假設一種情況,先假設事務a和事務b都沒有提交,這時候有乙個事務c,修改了name為tom的記錄,把age改成了30,然後把事務提交,事務c的id為3,同樣的,會插入一條記錄到undo log中,此時的undo log版本鏈鏈首記錄的db_trx_id為3。

現在有乙個事務d,查詢name為tom的記錄,此時將會啟用快照讀,快照是事務開始由查詢操作觸發的乙個資料快照,不加鎖的讀在可重複讀隔離級別下預設就是快照讀,相對於快照讀還有乙個叫做當前讀,更新操作都是當前讀。在快照讀時會產生乙個讀檢視(read view),在該事務執行快照讀的那一刻,會生成資料庫當前的乙個快照,記錄並且維護當前活躍的事務的id,因為事務的id都是自增的,所以越新的事務id越大。讀檢視遵循可見性演算法,而是否可見則需要做一些判斷,讀檢視中除了記錄當前活躍的事務id以外,還記錄了當前建立的最大事務id,快照讀時需要和read view做比較來獲得可見性結果。

read view主要是把當前事務的id,和系統中的活spbse躍事務的id作比較,比較的規則如下:

首先,read view中會有乙個read view生成時刻系統中活躍的事務id的陣列,暫稱為id_list

然後read view中會記錄乙個id_list中最小的事務id,暫稱為low_id

最後read view中還會記錄乙個read view生成時刻系統中尚未分配的事務id,也就是當前最大的事務id+1,暫稱為high_ispbsed

如果可見性結果為不可見的話,需要通過db_roll_ptr到undo log中取出該記錄的db_trx_id進行比較,通過遍歷版本鏈,直到找到滿足特定條件的db_trx_id, 那麼這個db_trx_id所在的舊記錄就是當前事務能看見的最新老版本。

校招mysql MVCC原理機制

mvcc實現原理 整體流程 彩蛋rr和rc隔離級別下的innodb快照讀有什麼區別 閒聊 邁莫coding 寫 校招mysql那些事 系列文章,一方面幫助在校大學生可以提早知道大廠的面試過程,了解大廠究竟需要什麼樣人才,自己該如何進行準備,全力以赴 另一方面也是自我鞏固知識,因為我也是從校招進入大廠...

mvcc原理 MySQL MVCC原理

1 mvcc基本原理 mvcc 多版本併發控制 mvcc,multiversion currency control 一般情況下,事務性儲存引擎不是只使用表鎖,行加鎖的處理資料,而是結合了mvcc機制,以處理更多的併發問題。mvcc處理高併發能力最強,但系統開銷 比最大 較表鎖 行級鎖 這是最求高併...

Mysql MVCC多版本併發控制原理詳解

我們建立乙個hero表 create table hero number int,name varchar 100 country varchar 100 primary key number engine innodb charset utf8 然後向這個表裡插入一條資料 insert into ...