MVCC的基本概念
MVCC,一個數據的多個版本,使得讀寫操作沒有沖突。
在多個事務并發的情況下,確定到底要訪問哪個版本。
MVCC實現原理
MVCC實現依賴于隱式字段,undo log日志,readView
隱式字段
在mysql用戶自定義的字段后面,隱藏了MySQL提供好的3個隱藏字段
DB_TRX_ID
:最近修改事務IDDB_ROLL_PTR
:指向回滾段中的undo log記錄,指向上一個版本DB_ROW_ID
:隱藏主鍵(當表無主鍵時自動生成)
undo log日志
回滾日志,在insert、update、delete的時候產生的便于數據回滾的日志。
當insert的時候,產生的undolog日志只在回滾時需要,在事務提交后,可被立即刪除。
而update、delete的時候,產生的undolog日志不僅在回滾時需要,mvcc版本訪問也需要,不會立即被刪除。
undo log版本鏈
undo log日志 記錄 數據修改前的值,形成版本鏈(相當于一個修改記錄)
ReadView機制 事務執行時會生成ReadView
ReadView(讀視圖)是 快照讀 SQL執行時MVCC提取數據的依據,記錄并維護系統當前活躍的事務(未提交的)id。
- 當前讀:讀取的是最新版本,會加鎖,讀取時不會被修改。
- 快照讀:不加鎖,讀取的是記錄數據的可見版本,可能是歷史數據。
ReadView包含4個核心字段
m_ids
:當前活躍事務ID集合,還未提交的 事務的集合。min_trx_id
:最小活躍事務IDmax_trx_id
:預分配的下個事務ID,當前最大事務id+1(事務id是自增的)creator_trx_id
:創建該ReadView的事務ID
版本鏈 數據訪問規則
DB_TRX_ID:最近修改的事務id
-
如果
DB_TRX_ID
小于min_trx_id
,說明該版本在ReadView創建前已提交,可訪問 -
如果
DB_TRX_ID
大于等于max_trx_id
,說明該版本在ReadView創建后生成,不可訪問 -
如果
DB_TRX_ID
等于creator_trx_id
,說明該版本由當前事務修改,可訪問 -
如果
DB_TRX_ID
在m_ids
列表中,說明該版本由未提交事務創建,不可訪問
不同隔離級別,生成的ReadView的時機不一樣
- READ COMMITTED(RC):每次查詢都生成新的ReadView,能看到其他事務已提交的修改。(每次查詢時我都來判斷:最新提交的事務是誰,我就讀誰)
- REPEATABLE READ(RR):僅在第一次查詢時生成ReadView并復用,保證事務期間看到的數據版本一致。(第一查詢,中間改動了,我還是復用第一次的查詢,不能識別到中間改動了)