Mysql的大多數事務型存儲引擎實現的都不是簡單的行級鎖。基於提升並發性能的考慮,他們一般都同時實現了MVCC.實現了非阻塞的讀操作,寫操作也只鎖定必要的行。
MVCC的實現,是通過保存數據在某個時間點的快照來實現的。即為:不管需要執行多長時間,每個事務看到的數據都是一致的。
不同的存儲引擎的MVCC實現不同,典型的有樂觀並發控制和悲觀並發控制。
innodb的MVCC,是通過在每行記錄后面保存兩個隱藏的列來實現的。這兩個列,一個是行的創建時間,一個保存行的過期時間。存儲的是系統版本號,不是真實的時間。每開始一個新的事務,系統版本號都會自動遞增。事務開始時刻的系統版本號會作為事務的版本號,用來和查詢到的每行記錄的版本號進行比較。
在REPEATABLE READ隔離級別下,MVCC具體操作:
SELECT
innodb會根據以下兩個條件檢查每行記錄:
a.innodb只查找版本號早於當前事務版本的數據行,<=當前事務版本號,這樣可以確保事務讀取的行,要么是在事務開始前已經存在的,要么是事務自身插入或者修改過的
b.行的刪除版本要么未定義,要么大於當前的事務版本號。這可以確保事務讀取到的行,在事務開始之前未被刪除。
INSERT
INNODB為新插入的每一行保存當前系統版本號作為行版本號
DELETE
innodb為刪除的每一行保存當前系統版本號作為行刪除標識
UPDATE
innodb為插入一行新紀錄,保存當前系統版本號為行版本號,同時保存當前系統版本號到原來的行作為行刪除標識
MVCC只在repeatable read和read committed兩個隔離級別下工作。其他兩個隔離級別和MVCC不兼容。因為READ UNCOMMITTED 總是讀取最新的數據行,而不是符合當前事務版本的數據行。而SERIALIZABLE 則會對所有讀取的行都加鎖。