Mysql MVCC總結

MVCC是不加鎖實現多個事務對數據庫的併發訪問

淺顯原理:

在每一行除了本來的數據外附加了兩列,一列是創建行時的版本號ID一列是刪除時的版本號ID

id name create-version delete-version
1 tom
  1. 如果現在事務ID爲1的事務插入了一行數據就會有
id name create-version delete-version
1 tom
將createversion修改爲當前的事務id
  1. 如果現在事務ID爲2的事務改了id = 1的name
id name create-version delete-version
1 tom 1 2
1 mike 2
會把之前的刪除版本號填上自己的,並且代替原來的創建版本號

查詢過濾條件:

  1. 只有創建版本號小於或等於當前事務id,即事務id爲2的事務只能讀取到create version<=2的已提交的事務的數據集

  2. 刪除版本號未指定,或者刪除版本號大於當前事務id,就是說當前事務時,確保這個數據沒有被刪除。

底層原理(複雜原理)

首先在每個事務對數據庫某一行進行修改的時候,在這一行上還會有附加的事務id(DB_TRX_ID)和回滾指針(DB_ROLL_PTR)
在這裏插入圖片描述
(先不用管隱式主鍵不重要)
當我們事務對數據庫進行修改的時候,新的回滾指針指向上一次的版本,把老的放到undo日誌裏面,這樣就會形成一條版本引用鏈

如下圖
在這裏插入圖片描述

我們從上到下按時間順序搞三個事務:
時間圖
看select1的第一個select,因爲事務100和事務200未對account表操作,很顯然id = 1就是lilei300
再看第二次select,這時候就得用生成的readview結合一定的過濾條件去版本鏈裏面找哪個版本的lilei合適
先說readview,MVCC只適用於可重複讀和讀已提交,可重複讀是一直沿用第一次select生成的readview,讀已提交是每一次查找都生成新的readview。那麼readview是什麼呢

readview

它由未提交的事務id數組(裏面最小的事務id叫min_id)和已知的最大事務id(max_id)組成,每次都是拿這個readview按照一定的規則在版本鏈中去找哪一行數據合適,可見:
會根據min_id,max_id將整個事務版本號集合劃分爲:
在這裏插入圖片描述
版本鏈比對規則:
1.如果落在綠色部分(trx id<min id),表示個版本是已提交的事務生成的,這個數據是可見的
2.如果落在紅色部分(trx id > max_id),表示這個版本是由將來啓動的事務生成的,是肯定不可見的

3.如果落在黃色部分 max id),那就包括兩種情況

a.若row的 trx id在數組中,表示這個版本是由還沒提交的事務生成的,不可見,當前自己的事務是可見的
b.若rowtrx的 id不在數組中,表示這個版本是已經提交了的事務生成的,可見。

再來看select 1中的第二條查詢:
readview = [100,200]300;
在這裏插入圖片描述
在版本鏈中按照此規則找出lilei300

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章