InnoDB的MVCC之(樂觀鎖),是通過在每行記錄保存兩個隱藏列來實現的。這兩個列,一個是存創建時間,一個是刪除時間,這里的時間指的是,系統版本號,並不是真正的時間值。
每開始一個新的事務,系統版本號都會自動遞增。事務開始時刻的系統版本號會作為事務的版本號,用來和查詢到的每行記錄版本號比較。
下面看一個在REPEATABLE READ(可重復讀)隔離級別下,MVCC的具體操作:
SELECT
InnoDB會根據以下兩個條件檢查每行記錄:
1、InnoDB只查找版本小於或等於當前事務版本的數據行,這樣可以確保事務讀取的行,是在事務開始前就已經存在的,或者是事務自身插入或者修改過的數據。
2、行的刪除版本要么未定義,要么大於當前事務的版本。這可以確保事務讀取到的行,在事務開始前未被刪除。
只有符合上述兩個條件的記錄,才能返回做為查詢結果。
INSERT
InnoDB為新插入的每一行保存當前系統版本號作為行版本號。
DELETE
InnoDB為刪除的每一行保存當前系統版本號作為行刪除標識。
UPDATE
InnoDB為插入一行新記錄,保存當前系統版本號作為行版本號,同時保存當前系統版本號到原來的行作為刪除標識。
----------------------------------------------------------------------------------------------------------------------------------------------------------
保存這兩個額外的系統版本號,使大多數讀操作都可以不用加鎖。這樣設計使得讀數據操作很簡單,性能很好。並且也能保證只會讀取到符合標准的行。不足之處是每行記錄都需要額外的存儲空間,需要做更多的檢查工作,以及一些額外的維護工作。
MVCC只在REPEATABLE READ(可重復讀)和READ COMMITTED(提交讀)兩個隔離級別下工作。其他兩個隔離級別都和MVCC不兼容。READ UNCOMMITTED(未提交讀)總是讀取最新的數據行,而SERIALIZBLE(可串行化)則會對所有讀取的行加鎖。