mysql innodb中mvcc (多版本併發控制)

InnoDB默認的隔離級別是RR(可重複讀),可以解決髒讀和不可重複讀,但是不能解決幻讀問題。以下介紹均是在mysql innodb RR級別 下的情況

1. MVCC簡介

MVCC是一種多版本併發控制機制。

2. MVCC是爲了解決什麼問題?

大多數的MYSQL事務型存儲引擎,如,InnoDB,Falcon以及PBXT都不使用一種簡單的行鎖機制.事實上,他們都和MVCC–多版本併發控制來一起使用.大家都應該知道,鎖機制可以控制併發操作,但是其系統開銷較大,而MVCC可以在大多數情況下代替行級鎖,使用MVCC,能降低其系統開銷.可以當做一種變種的行級鎖

============================================
可以解決髒讀 不可重複讀
解決原理:
不可重複讀:
每個用戶連接數據庫時,看到的都是某一特定時刻的數據庫快照,在B的事務沒有提交之前,A始終讀到的是某一特定時刻的數據庫快照,不會讀到B事務中的數據修改情況,直到B事務提交,纔會讀取B的修改內容
髒讀:
B事務沒提交,A事務按照MVCC原理更本就讀不到,版本是在提交的時候才更新

3. MVCC實現

MVCC是通過保存數據在某個時間點的快照來實現的. 不同存儲引擎的MVCC. 不同存儲引擎的MVCC實現是不同的,典型的有樂觀併發控制和悲觀併發控制.

4.MVCC 具體實現分析

下面,我們通過InnoDB的MVCC實現來分析MVCC使怎樣進行併發控制的.
InnoDB的MVCC,是通過在每行記錄後面保存兩個隱藏的列來實現的,這兩個列,分別保存了這個行的創建時間,一個保存的是行的刪除時間。這裏存儲的並不是實際的時間值,而是系統版本號(可以理解爲事務的ID),沒開始一個新的事務,系統版本號就會自動遞增,事務開始時刻的系統版本號會作爲事務的ID.下面看一下在REPEATABLE READ隔離級別下,MVCC具體是如何操作的.

INSERT
InnoDB爲新插入的每一行保存當前系統版本號作爲版本號.
第一個事務ID爲1;
SELECT
InnoDB會根據以下兩個條件檢查每行記錄:
a.InnoDB只會查找版本早於當前事務版本的數據行(也就是,行的系統版本號小於或等於事務的系統版本號),這樣可以確保事務讀取的行,要麼是在事務開始前已經存在的,要麼是事務自身插入或者修改過的.
b.行的刪除版本要麼未定義,要麼大於當前事務版本號,這可以確保事務讀取到的行,在事務開始之前未被刪除.
只有a,b同時滿足的記錄,才能返回作爲查詢結果.
DELETE
InnoDB會爲刪除的每一行保存當前系統的版本號(事務的ID)作爲刪除標識.
看下面的具體例子分析:

5.重點來了哈

MVCC只在REPEATABLE READ和READ COMMITTED兩個隔離級別下工作。其他兩個隔離級別都和MVCC不兼容,因爲READ UNCOMMITTED總是讀取最新的數據行,而不是符合當前事務版本的數據行,而SERIALIZABLE會對所有讀取到的行都加鎖。

READ COMMITTED(RC) :快照的粒度是語句級。
REPEATABLE READ(RR) :快照的粒度是事務級

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