目錄
MVCC是什麼?
Multiversion concurrency control (多版本併發控制)。對事物內正在處理的數據做多版本控制,以避免寫操作的堵塞,而引發讀操作的併發問題。
MVCC處理邏輯
通過在每行數據增加隱藏列(數據航的版本號、刪除版本號)來標記當前數據行。如下圖所示。
-
插入
-
刪除
-
修改
-
查詢
查詢條件有兩個關鍵規則:
1、查找的【數據行的版本號】要小於等於當前事務版本號;
2、查找的【刪除行版本號】要大於當前事務版本號或者爲NULL;
MVCC案例
-
案例一、執行順序1,2,3,4,1
-
案例二、執行順序3,4,1,2
在案例二中,出現了髒讀(3,4的執行結果並沒有commit的時候,1、2已經能夠讀到未提交數據)。MySQL如何解決這個問題呢?
那就是UndoLog!
Undo Log
指事務開始之前,在操作任何數據之前,首先將需操作的數據備份到一個地方 (Undo Log),它是爲了實現事務的原子性:事務處理過程中如果出現了錯誤或者用戶執行了 ROLLBACK語句,Mysql可以利用Undo Log中的備份將數據恢復到事務開始之前的狀態。
UndoLog在Mysql Innodb存儲引擎中用來實現多版本併發控制:事務未提交之前,Undo保存了未提交之前的版本數據,Undo 中的數據可作爲數據舊版本快照供其他併發事務進行快照讀。
所以當我們執行普通select操作時,就是通過UndoLog進行的快照讀;當需要讀取當前數據時,通過鎖機制來保證讀取的數據無法通過其他事務進行修改,UPDATE、DELETE、INSERT、SELECT … LOCK IN SHARE MODE、SELECT … FOR UPDATE都是當前讀。
上例中,update和select其實操作的不是同一塊數據區。update寫入的是數據區,select讀的是UndoLog的快照版本,所以不會出現髒讀的問題,如果select有S鎖,則會在獲取鎖之後(update未開始或者提交後)才能進行數據讀取。