1. 程式人生 > 其它 >MVCC(多版本併發控制)詳解

MVCC(多版本併發控制)詳解

在 MySQL InnoDB儲存引擎下,RC、RR 基於 MVCC 進行併發事務控制, MVCC 是基於“資料版本”對併發事務進行訪問
用一個例子來解釋一下,下面是一張事務執行流程圖:

稍微解釋一下:

  1. 事務 Aid=1088 的記錄的 name 改為 “張三”,並提交
  2. 事務 Bid=1088 的記錄的 name 改為 “張小三”,並提交
  3. 事務 Cid=1088 的記錄的 name 改為 “張老三”,並提交
  4. 事務 D 只是去查詢 id=1088 的記錄

首先模擬一下在 RC 隔離級別下:事務D 第一次讀取的資料是 “張三”,第二次讀取的就是“張小三”
這裡應該很好理解,因為在 RC 隔離級別下,事務D 能讀到 commit 的資料,所以就導致了“不可重複讀”問題
如果使用 RR 隔離級別,事務D 的兩次讀取都是 “張三”
RR 隔離級別

是基於 MVCC 實現的,MVCC 又依賴 UNDO_LOGUNDO_LOG就是回滾日誌,它是一個版本鏈,它記錄了上一次版本的資料變化
eg:事務 B 把“張三”改為了“張小三”,在UNDO_LOG 中的體現如下:

注:最原始的資料,也就是最下面這一條,它的 事務ID回滾指標 都是 null
瞭解了 UNDO_LOG 之後,現在引入一個新的名詞:ReadView(快照讀)
快照都就是普通的 sql 查詢語句:select ....
有了快照讀就有當前讀,當前讀是指:
Insert、Update、Delete、
Select ... for update
Select ... lock in share mode

ReadView 資料結構


圖是從 IT老齊 那兒盜的,稍微解釋一下:
m_ids 未提交的事務,不允許讀
min_trx_id 就是快要執行完的事務 id
max_trx_id 就是下一個新的事務的 id
creator_trx_id 就是建立這個 ReadView 是哪個事務

RC 原理

RC(讀已提交):在每一次執行快照讀時生成 ReadView,根據上面的例子

讀了兩次,生成了兩個 ReadView,先看第一個 ReadView,因為在這個 ReadView 生成的時候,事務1 已經 commit 了,所以他不在活躍事務集合裡面,所以 m_ids 是 2,3,4
最小活躍事務就是 2 沒有異議
預分配事務id 就是 4+1 = 5
當前的 ReadView 是事務 4 建立的,所以 creator_trx_id = 4
第二個 ReadView 也是一樣的的邏輯

版本鏈資料訪問規則:

RR 原理

可重複讀原理很簡單,就是複用 ReadView

eg:在第二次查詢的時候,生成的 ReadView 是複用前一次的,所以不會造成 不可重複讀

RR 能解決幻讀嗎?

能,但不完全能。
如果是多次快照讀,ReadView會產生複用,沒有幻讀產生
但是當多次快照讀中間存在當前讀,ReadView會重新生成,導致產生幻讀