目錄
1.MVCC多版本并發控制的一些基本概念
MVCC實現原理
記錄中的隱藏字段
undo log
undo log 版本鏈
ReadView
數據訪問規則
具體實現邏輯
總結
1.MVCC多版本并發控制的一些基本概念
當前讀:該取的是記錄的最新版本,讀取時還要保證其他并發事務不能修改當前記錄,會對該取的記錄進行加鎖。對于我們日常的操作,如:select...lock in share mode(共享鎖), select...for update,update,insert. delete(排他鎖)都是一種當前讀。
快照讀:簡單的select(不加鎖)就是快照讀,快照讀讀取的是記錄數據的可見版本,有可能是歷史數據,不加鎖,是非阻塞讀。正常select語句就是一個快照讀,
- read committed:每次select,都生成一個快照讀。
- repeatable read:開啟事務后第一個select語句才是快照讀的地方。
- serializable:快照讀會退化為當前讀。
MVCC:全稱multi-versioncurency contol,多版本井發控制,指推護一個數據的多個版本,使得讀寫提作沒有沖突,快照讀為MySQL實現。MVCC提供了一個非阻塞讀功能。MVCC的具體實現,還需要依賴于數據庫記錄中的三個隱式字段,undolog日志,readview。
MVCC實現原理
記錄中的隱藏字段
DB_TRX_ID:最近修改事務id,記錄插入這條記錄或者最后一次修改記錄的事務id
DB_ROLL_PTR:回滾指針,指向這條記錄的上一個版本,用于配合undo log,指向上一個版本
DB_ROW_ID:隱藏主鍵,如果表結構沒有指定主鍵,將會生成該隱藏字段。
undo log
回滾日志,在insert,update,delete的時候產生的便于數據回滾的日志。記錄數據回滾之前是什么樣的
insert:產生的undo log日志在回滾時需要,在事務提交后,可被立即刪除。
undate,delete:產生undo log日志不僅在回滾時需要,在快照讀時也需要,不會被立即刪除
undo log 版本鏈
1.首先事務2去執行sql語句之前InnoDB引擎會在undo log日志里記錄數據回滾前是什么樣的
再去修改數據,DB_TRX_ID會修改為當前事務id,DB_ROLL_PTR會指向回滾日志
2.事務3去修改數據首先會在undo log 日志記錄當前數據,再去修改數據DB_TRX_ID修改為3,DB_ROLL_PTR指向當前日志記錄,當前日志記錄指向前一次記錄形成一個版本鏈
所以undo log版本鏈指的是:不用事務或者相同事務對同一條記錄進行修改,導致該記錄的undolog生成一條記錄版本鏈表,鏈表頭部是最最新的舊紀錄,鏈表尾部是最早的舊紀錄。
那我們應該選擇哪一個版本呢在事務回滾的時候?
ReadView
ReadView(讀視圖)是快照讀SQL執行時MVCC提取數據的依據,記錄并維護系統當前活躍的事務(未提交的)id
ReadView包含了四個核心字段:
不同的隔離級別,生成ReadView的時機不同:
read committed:在事務中每一次執行快照讀時生成readview.
repeatableread:僅在事務中第一次執行快照讀時生成readview,后續復用該readview.
數據訪問規則
- 1.trx_id(當前事務id)==cteator_trx_id(創建快照版本的事務id)?可以訪問該版本->? 成立,說明數據時當前這個事務更改的
- 2.trx_id<mix_trx_id(最小活動事務id,最先開啟事務還沒有提交事務id)?可以訪問該版本->? 成立,說明數據已經提交了
- 3.trx_id > max_trx_id?不可以訪問該版本->? 成立,說明該事務是在readview生成后才開啟。
- 4.min_trx_id <= trx_id <= max_trx_id?如果trx_id不在m_ids中是可以訪問該版本的->? 說
- 明數據已經提交
具體實現邏輯
1.m_ids:{3,4,5}由圖可知,事務2commited了還有3,4,5沒有提交
2.min_trx_id:3 事務3是還沒有提交事務的最早開啟事務的
3.max_trx_id:6 預先分配事務,下一個事務為6
4.creator_trx_id:5創建readview的為事務5
在RC(read commited)隔離級別下查找快照讀版本邏輯
1.當前記錄DB_TRX_ID = 4根據數據訪問規則去匹配,發現這四條規則一體條都匹配不上,選擇去undo log版本鏈找第二條記錄
2.第二條記錄當前操作事務id=3,也就是DB_TRX_ID = 3根據數據訪問規則去匹配發現這四條規則也一樣一條匹配不上,選擇去undo log 版本鏈找第三條記錄操作事務id = 2
3.第三條記錄當前操作事務id = 2,根據數據數據訪問規則去匹配,發現 trx_id < min _ trx_id匹配上了說明這次快照讀找的版本是這條記錄id = 2,直接把這個版本記錄直接返回
在RR(repeatatable)事務隔離級別下,僅在事務中第一次執行快照讀時生成ReadView,后續復用該ReadView
在第二次快照讀的時候不會生成快照讀,復用上面readview,可重復讀
兩個readview都一樣,匹配規則肯定一樣,查找出來的數據也是一模一樣,這就保證了可重復讀
總結
MVCC作用主要我們在快照讀的時候來決定我們提取的到底是哪個版本
MVCC實際上實現原理是3部分,隱藏字段,Undo log ,Read View
隱藏字段:主要取決于事務id,和回滾指針
undo log 版本鏈
Read View讀視圖
MVCC? + 鎖保證了事務當中的隔離性,一致性:指的是數據執行前和執行之后是一致的,如果事務執行失敗全部回滾保證數據執行前后一致,一致性由 redo log 和undo log 保證的