為了提高並發MySQL加入了多版本並發控制,它把舊版本記錄保存在了共享表空間,在事務未提交之前對應的行記錄還是受到鎖的限制,當事務提交之後對應的記錄行就在緩存中被修改了記錄也被持久化了,當刷新線程按一定的規律進行刷新的時候行的修改記錄被刷新到了物理數據頁中,並且共享表空間的中的舊版本記錄頁也被清除。
多版本並發控制只針對innodb的repeatable read和read committed這兩種隔離級別。多版本並發控制的原理就是在每個記錄行後面增加兩個標示列用來存儲該行的狀態,分別存儲改行的新系統版本號和刪除系統版本號。
版本號:系統的版本號會隨著每增加一個事務遞增。
通過閱讀高性能mysql這本書的解釋是MVCC是行級鎖的一個變種,但是它在很多情況下避免了加鎖操作,但大都實現了非阻塞的讀操作,寫操作也只鎖定必要的行。
TABLE
ID
NAME
Trx_id
De_Trx_id
1
a
1
有四個事務:select(trx=2),insert(trx=3),delete(trx=4),update(trx=5)
現在這四個事務同時對該行進行操作,演示SELECT的可重復讀,假設四個操作在SLECT提交之前都未提交,當然SELECT是能查看到四個操作的記錄的。
SELECT:
SELET會根據以下兩個條件去查找記錄:
1.只查找小於或等於當前事務版本號的記錄行。
2.刪除版本號為空或者大於當前事務版本號的記錄行。
BEGIN TRAN SELECT NAME FROM TABLE WHERE ID=1
ID
NAME
Trx_id
De_Trx_id
1
a
1
WAIT 10 MINUTE SELECT NAME FROM TABLE WHERE ID=1
COMMIT
ID
NAME
Trx_id
De_Trx_id
1
a
1
4
根據SELECT 的查找條件INSERT記錄的事務版本號大於當前版本號所以不會被查到;DELETE的事務刪除版本號大於當前版本號,所以該行會被查出;UPDATE第一行的事務的版本號小於當前版本號而刪除版本號大於當前版本號,可以被查到,第二行因為事務版本號大於當前版本號所以不滿足,最終SELECT查詢的記錄是UPDATE操作的第一條記錄;SELECT兩次查詢的結果一致,滿足可重復讀隔離級別。當然在這裡除了INSERT操作,其它的操作都無法在SELECT提交之前提交。
INSERT:
INSERT INTO TABLE(ID,NAME) VALUES(2,'B');
ID
NAME
Trx_id
De_Trx_id
2
b
2
DELETE:
DELETE FROM TABLE WHERE ID=1;
ID
NAME
Trx_id
De_Trx_id
1
a
1
3
UPDATE:
BEGIN TRAN UPDATE TABLE SET NAME='B' WHERE ID=1 COMMIT
ID
NAME
Trx_id
De_Trx_id
1
a
1
4
ID
NAME
Trx_id
De_Trx_id
1
b
4
注意:多版本並發控制不支持myisam存儲引擎。
在緩存中有一個用於維護鎖的資源,對鎖的維持需要消耗mysql的資源,多版本並發控制它就是減少了用於維持鎖資源的消耗來提高性能。