mvcc 是一種併發控制的方法,實現對資料庫的併發訪問,提高讀併發效率。
在innodb中就是指:在已提交讀(rc)和可重複讀(rr)這兩種隔離級別下的事務對於select操作時,會訪問版本鏈中的記錄。
版本鏈
在innodb中,聚簇索引記錄中有兩個必要的隱藏列:
trx_id:這個id用來儲存的每次對某條聚簇索引記錄進行修改的時候的事務id。
roll_pointer:每次對哪條聚簇索引記錄有修改的時候,都會把老版本寫入 undo 日誌中。roll_pointer就是存了乙個指標,它指向這條聚簇索引記錄的上乙個版本的位置,通過它來獲得上乙個版本的記錄資訊。(注意插入操作的 undo 日誌沒有這個屬性,因為它沒有老版本)
readview
已提交讀和可重複讀的區別就在於它們生成readview的策略不同。
readview中主要就是有個列表來儲存我們系統中當前活躍著的讀寫事務,也就是還未提交的事務。通過這個列表來判斷記錄的某個版本是否對當前事務可見。
當前列表裡的事務id為[50-90]
如果要訪問記錄版本的事務id為30,比當前列表最小的id小,說明這個事務已經提交過了,所以是可以訪問的。
如果要訪問的記錄版本的事務id為70,在列表最大與最小值之間,此時需要判斷事務是否在列表內,如果在,說明事務未提交,不能訪問;如果不在,說明事物已提交,版本可以被訪問。
如果要訪問的記錄版本的事務大於列表中最大id,那說明版本是在readview之後生成的,不能訪問版本。
這些記錄都是去版本鏈裡面找的,先找最近記錄,如果最近這一條記錄事務id不符合條件,不可見的話,再去找上乙個版本比較當前事務的id和這個版本事務id看能不能訪問,以此類推直到返回可見的版本或者結束。
已提交讀隔離級別下的事務在每次查詢的開始都會生成乙個獨立的readview,而可重複讀隔離級別則在第一次讀的時候生成乙個readview,之後的讀都復用之前的readview。
實際上,mvcc解決了資料庫採用悲觀鎖這樣效能不佳的方式去解決讀-寫衝突問題,而提出的解決方案,所以在資料庫中,可以採用以下組合最大程度的提高資料庫併發效能。
當前讀:讀取的是記錄的最新版本,讀取時還要保證其他併發事務不能修改當前記錄,會對讀取的記錄進行加鎖。
快照讀:像不加鎖的select操作就是快照讀。快照讀的前提是隔離級別不是序列級別,序列級別下的快照讀會退化成當前讀。基於提高併發效能的考慮,快照讀的實現是基於多版本併發控制,即mvcc。
mvcc其實就是為了實現不加鎖解決讀-寫衝突,而這個讀指的就是快照讀。當前讀實際上是一種加鎖的操作,是悲觀鎖的實現。
多版本併發控制(MVCC)
mysql的大多數事務性儲存引擎 如innodb 實現的都不是簡單的行級鎖。基於提公升併發效能的考慮,它們一般都同時實現了多版本併發控制 mvcc 可以認為mvcc是行級鎖的乙個變種,但是它在很多情況下避免了加鎖操作,因此開銷更低。雖然實現機制有所不同,但大都實現了非阻塞的讀操作,寫操作也只鎖定必要...
多版本併發控制MVCC
大多數mysql的事務性儲存引擎,例如innodb.falcon 和pbxt,不是簡單地使用行加鎖的機制,而是選用一種叫做 多版本併發控制 mvcc,mutiversion concurrency control 的技術,和行加鎖機制關聯使用,以應對更多的併發處理問題。mvcc不是mysql獨有的技...
MVCC(多版本併發控制)
mvcc是資料庫鎖策略的一種實現的統稱。使用mvcc可以在大多數情況下避免加鎖的操作,為服務帶來更好的效率。mysql的大多數事務型儲存引擎實現的都不是簡單的行級鎖。基於提公升併發效能的考慮,它們一般都同時實現了多版本併發控制 mvcc 不同的資料庫實現mvcc的機制不盡相同。我們可以粗略的認為mv...