MYSQL-MVCC多版本并發(fā)控制

MVCC概念:InnoDB使用MVCC實現(xiàn)高并發(fā)

MVCC并不是MySql獨有的,Oracle,PostgreSQL等都實現(xiàn)了MVCC,但各自實現(xiàn)機制不同。因為MVCC沒有統(tǒng)一實現(xiàn)標準。

MVCC可以認為它是行級鎖的一個變種,但是它在很多情況下避免了加鎖操作,因此開銷更低。實現(xiàn)了非阻塞的讀操作,寫操作也只鎖定必要的行。


MVCC的基本原理:

MVCC的實現(xiàn),通過保存數(shù)據(jù)在某個時間點的快照來實現(xiàn)的。這意味著一個事務無論執(zhí)行多長時間,在同一個事務里看到數(shù)據(jù)都實一致的。根據(jù)事務開始的時間不同,每個事務對同一張表同一個時刻看到的數(shù)據(jù)可能不同。

MVCC的基本特征:

每行數(shù)據(jù)都存在一個版本,每次數(shù)據(jù)更新時都更新該版本。

修改時Copy出當前版本隨意修改,各個事務之間無干擾。

保存時比較版本號,如果成功(commit),則覆蓋原記錄;失敗則放棄copy(rollback)


InnoDB存儲引擎MVCC的實現(xiàn)策略:

通過在每一行數(shù)據(jù)后面保存兩個隱藏的列實現(xiàn)當前行創(chuàng)建時的版本號和刪除時的版本號(可能為空)。這里的版本號并不是實際的時間值,而是系統(tǒng)版本號。每開始一個新的事務,系統(tǒng)版本號都會自動遞增。事務開始時刻的系統(tǒng)版本號會作為事務的版本號,用來和查詢到的每行記錄的版本號進行比較。

每個事務又有自己的版本號,這樣事務內(nèi)執(zhí)行CRUD操作時,就通過版本號的比較來達到數(shù)據(jù)版本控制的目的。具體做法見下面的示意圖。

MVCC具體的操作如下:

SELECT:InnoDB會根據(jù)以下兩個條件檢查每行記錄:

1)InnoDB只查找版本早于當前事務版本的數(shù)據(jù)行(也就是,行的系統(tǒng)版本號小于或等于事務的系統(tǒng)版本號),這樣可以確保事務讀取的行,要么是在事務開始前已經(jīng)存在的,要么是事務自身插入或者修改過的。

2)行的刪除版本要么未定義,要么大于當前事務版本號。這可以確保事務讀取到的行,在事務開始之前未被刪除。

INSERT:InnoDB為新插入的每一行保存當前系統(tǒng)版本號作為行版本號。

DELETE:InnoDB為刪除的每一行保存當前系統(tǒng)版本號作為行刪除標識。

UPDATE:InnoDB為插入一行新記錄,保存當前系統(tǒng)版本號作為行版本號,同時保存當系統(tǒng)的版本號為原來的行作為刪除標識。

保存這兩個額外系統(tǒng)版本號,使大多數(shù)操作都可以不用加鎖。這樣設計使得計數(shù)據(jù)操作很簡單,性能很好,并且也能保證只會讀取到符合標準的行。不足之處是每行記錄都需要額外的存儲空間,需要做更多的行檢查工作,以及一些額外的維護工作。

MVCC只在REPEATABLE READ和READ COMMITED兩個隔離級別下工作,其它兩個隔離級別和MVCC不兼容。


Purge流程

Purge功能:

InnoDB由于要支持多版本協(xié)議,因此無論是更新,刪除,都只是設置記錄上的deleted bit標記位,而不是真正的刪除記錄。后續(xù)這些記錄的真正刪除,是通過Purge后臺進程實現(xiàn)的。Purge進程定期掃描InnoDB的undo,按照先讀老undo,再讀新undo的順序,讀取每條undo record。對于每一條undo record,判斷其對應的記錄是否可以被purge


MVCC 可以保證不阻塞地讀到一致的數(shù)據(jù)

參考:

http://blog.csdn.net/chen77716/article/details/6742128

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容