MVCC,多版本并發控制協議,是資料庫中經常使用的的一種并發控制手段,是MySQL中基于樂觀鎖理論實作隔離級別的方式,用于實作讀已提交和可重復讀取隔離級別的實作
MVCC最大的好處是:讀不加鎖,讀寫不沖突,在讀多寫少的OLTP應用中,讀寫不沖突是非常重要的,極大的提高了系統的并發性
Mysql在可重復讀隔離級別下如何保證事務較高的隔離性,同樣的sql查詢陳述句在一個事務里多次執行查詢結果相同,就算其它事務對資料有修改也不會影響當前事務sql陳述句的查詢結果,
這個隔離性就是靠MVCC(Multi-Version Concurrency Control)機制來保證的,對一行資料的讀和寫兩個操作默認是不會通過加鎖互斥來保證隔離性,避免了頻繁加鎖互斥,而在串行化隔離級別為了保證較高的隔離性是通過將所有操作加鎖互斥來實作的,
Mysql在讀已提交和可重復讀隔離級別下都實作了MVCC機制,
MVCC就一句話總結:同一份資料臨時保存多個版本的一種方式,進而實作并發
快照讀和當前讀
在MVCC并發控制中,讀操作可以分成兩類:快照讀 (snapshot read)與當前讀 (current read),快照讀,讀取的是記錄的可見版本 (有可能是歷史版本),不用加鎖,當前讀,讀取的是記錄的最新版本,并且當前讀回傳的記錄,都會加上鎖,保證其他事務不會再并發修改這條記錄
快照讀: 簡單的select操作,屬于快照讀,不加鎖
當前讀: 特殊的讀操作,插入/更新/洗掉操作,屬于當前讀,需要加鎖
select * from table where ? lock in share mode;
select * from table where ? for update;
insert into table values (…);
update table set ? where ?;
delete from table where ?;
所有以上的陳述句,都屬于當前讀,讀取記錄的最新版本,并且讀取之后,還需要保證其他并發事務不能修改當前記錄,對讀取記錄加鎖
其中,除了第一條陳述句,對讀取記錄加S鎖 (共享鎖)外,其他的操作,都加的是X鎖 (排它鎖)
基本實作
InnoDB的MVCC,是通過在每行記錄后面保存兩個隱藏的列來實作的,這兩個列,分別保存了這個行的創建時間,一個保存的是行的洗掉時間
一個行記錄資料有多個版本對快照資料,這些快照資料在undo log中
這里存盤的并不是實際的時間值,而是系統版本號(可以理解為事務的ID),每開始一個新的事務,系統版本號就會自動遞增,事務開始時刻的系統版本號會作為事務的ID
INSERT
InnoDB為新插入的每一行保存當前系統版本號作為版本號
SELECT
InnoDB會根據以下兩個條件檢查每行記錄:
a.InnoDB只會查找創建的版本號早于當前事務版本的資料行
(也就是,行的系統版本號小于或等于事務的系統版本號),這樣可以確保事務讀取的行,要么是在事務開始前已經存在的,要么是事務自身插入或者修改過的
b.行的洗掉版本要么未定義,要么大于當前事務版本號
這可以確保事務讀取到的行,在事務開始之前未被洗掉
只有a,b同時滿足的記錄,才能回傳作為查詢結果
DELETE
InnoDB會為洗掉的每一行保存當前系統的版本號(事務的ID)作為洗掉標識
UPDATE
InnoDB執行UPDATE,實際上是新插入了一行記錄,并保存其創建時間為當前事務的ID,同時保存當前事務ID到要UPDATE的行的洗掉時間
MVCC由淺入深學習
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/170026.html
標籤:其他
上一篇:Mysql系列第二十五講 mysql如何確保資料不丟失?有幾點值得我們借鑒
下一篇:資料庫——資料庫用戶管理
