1. 程式人生 > 資料庫 >mysql innodb中mvcc (多版本併發控制)

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

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會對所有讀取到的行都加鎖。