multi-version concurrency control 多版本併發控制
大多數的mysql事務型儲存引擎,如innodb,falcon以及pbxt都不使用一種簡
單的行鎖機制。
事實上,他們都和和另外一種用來增加併發性的被稱為「多版本併發控制(mvcc)」的機制來一直使用。
mvcc不只使用在mysql
中,oracle,postgresql以及其他一些資料為系統也同樣使用它。
你可將將mvcc看成行級別鎖的一種妥協,它在許多情況下避免了使用鎖,同時可以提供更小的開銷。
根據實現的不同,它可以允許非阻塞式讀,在寫操作進行時只鎖定必要的記錄。
mvcc會儲存某個時間點上的資料快照。
這意味闃事務可以看到乙個一致的資料檢視,不管他們需
要跑多久。
這同時也意味著不同的事務在同乙個時間點看到的同乙個表的資料可能是不同的。
如果你從來沒有過種體驗的話,可能理解起來比較抽象,但是隨著慢慢
地熟悉這種理解將會很容易。
各個儲存引擎對於mvcc的實現各不相同。
這些不同中的一些包括樂觀和悲觀併發控制。
我們將通過乙個簡化的innodb版本的行為來展示mvcc工作的乙個側面。
innodb:通過為每一行記錄新增兩個額外的隱藏的值來實現mvcc,這兩個值乙個記錄這行
資料何時被建立,另外乙個記錄這行資料何時過期(或者被刪除)。但是innodb並不儲存這些事件發生時的實際時間,相反它只儲存這些事件發生時的系統版
本號。這是乙個隨著事務的建立而不斷增長的數字。每個事務在事務開始時會記錄它自己的系統版本號。每個查詢必須去檢查每行資料的版本號與事務的版本號是否
相同。讓我們來看看當隔離級別是repeatable read時這種策略是如何應用到特定的操作的:
select innodb必須每行資料來保證它符合兩個條件:
1、innodb必須找到乙個行的版本,它至少要和事務的版本一樣老(也即它的版本號不大於事務的版本號)。這保證了不管是事務開始之前,或者事務建立時,或者修改了這行資料的時候,這行資料是存在的。
2、這行資料的刪除版本必須是未定義的或者比事務版本要大。這可以保證在事務開始之前這行資料沒有被刪除。
符合這兩個條件的行可能會被當作查詢結果而返回。
insert:innodb為這個新行記錄當前的系統版本號。
delete:innodb將當前的系統版本號設定為這一行的刪除id。
update:innodb會寫乙個這行資料的新拷貝,這個拷貝的版本為當前的系統版本號。
它同時也會將這個版本號寫到舊行的刪除版本裡。
這種額外的記錄所帶來的結果就是對於大多數查詢來說根本就不需要獲得乙個鎖。
他們只是簡單地以最快的速度來讀取資料,確保只選擇符合條件的行。
這個方案的缺點在於儲存引擎必須為每一行儲存更多的資料,做更多的檢查工作,處理更多的善後操作。
mvcc只工作在repeatable read和read
commited隔離級別下。
read
uncommited不是mvcc相容的,因為查詢不能找到適合他們事務版本的行版本;
它們每次都只能讀到最新的版本。
seriablable也不與
mvcc相容,因為讀操作會鎖定他們返回的每一行資料[1]
。通過使用mvcc(multi-version concurrency
control)演算法自動提供併發控制。mvcc維持乙個資料的多個版本使讀寫操作沒有衝突。也就是說資料元素x上的每乙個寫操作產生x的乙個新版
本,gbase 8m為x的每乙個讀操作選擇乙個版本。由於消除了資料庫中資料元素讀和寫操作的衝突,gbase
8m得到優化,具有更好的效能。特別是對於資料庫讀和寫兩種方法,他們不用等待其他同時進行的相同資料寫和讀的完成。在併發事務中,資料庫寫只等待正在對
同一行資料進行更新的寫,這是現有的行鎖定方法的弱點。同時mvcc**不需要的和長時間不用的記憶體,防止記憶體空間的浪費。mvcc優化了資料庫併發系
統,使系統在有大量併發使用者時得到最高的效能,並且可以不用關閉伺服器就直接進行熱備份。使用mvcc多版本併發控制比鎖定模型的主要優點是在mvcc裡, 對檢索(讀)資料的鎖要求與寫資料的鎖要求不衝突, 所以讀不會阻塞寫,而寫也從不阻塞讀。
在資料庫裡也有表和行級別的鎖定機制, 用於給那些無法輕鬆接受 mvcc 行為的應用。 不過,恰當地使用 mvcc 總會提供比鎖更好地效能。在 gbase 中的查詢功能通過 mvcc
提供的一致性非鎖讀(在下文我們簡稱為一致性讀),就是提供通過資料庫在乙個時間點上的快照來實現資訊的查詢。查詢只是對那些在這個時間點之前提交的事務
所做的變更,而並不關注在時間點之後的變更或未提交的事務。當然,若是該事務自身進行的變更,對於查詢是可見的。
gbase 的預設級別是 read committed ,在該隔離級別下事務中的查詢語句,使用當前時間戳進行一致性讀,每次查詢的時間戳是不相同的。
但對 repeatable read 隔離級別,在同乙個事務中的所有一致性讀,使用的時間戳均是第乙個查詢的時間戳,這樣讀取的也就是由該事務第一次讀建立起來的資料快照。使用者只有通過提交當前事務,並發出乙個新的查詢才會得到新的資料快照。
一致性讀是 gbase 在 read committed 和 repeatable read 隔離級別下,處理 select 語句中使用的預設模式。一致性讀在它讀的資料上不設定任何鎖,因此在一致性讀某個表的同時,其它使用者均可以修改這個表。
注意在 drop table 和 alter table 運作時,一致性讀無效
。一致性讀在 drop table 上無效是因為 gbase 不能使用已經 drop 的表,該錶已經刪除。一致性讀在 alter table
上無效是因為 gbase
會在事務內,重新建立乙個新錶並從舊表向新錶插入記錄。這樣當使用者再次執行一致性讀時,在新錶中將看不到任何行,因為在新錶中的資料都在第一次一致性讀的
快照之外。
參考資料
理解MYSQL MVCC 實現機制
1.1 什麼是mvcc mvcc是一種多版本併發控制機制。1.2 mvcc是為了解決什麼問題?1.3 mvcc實現 mvcc是通過儲存資料在某個時間點的快照來實現的.不同儲存引擎的mvcc.不同儲存引擎的mvcc實現是不同的,典型的有樂觀併發控制和悲觀併發控制.下面,我們通過innodb的mvcc實...
理解MYSQL MVCC 實現機制
大家都應該知道,鎖機制可以控制併發操作,但是其系統開銷較大,而mvcc可以在大多數情況下代替行級鎖,使用mvcc,能降低其系統開銷.start transaction insert into yang values null,yang insert into yang values null,lon...
輕鬆理解MYSQL MVCC 實現機制
支援原創,大家去看原文吧 1.1 什麼是mvcc mvcc是一種多版本併發控制機制。1.2 mvcc是為了解決什麼問題?1.3 mvcc實現 mvcc是通過儲存資料在某個時間點的快照來實現的.不同儲存引擎的mvcc.不同儲存引擎的mvcc實現是不同的,典型的有樂觀併發控制和悲觀併發控制.下面,我們通...