MySQL的多版本併發控制(MVCC)

2022-01-31 09:38:51 字數 2176 閱讀 3141

快照讀(snapshot read) 是一種一致性不加鎖的讀,是 innodb 併發如此之高的核心原因之一。

在 read committed 事務隔離級別下,一致性不加鎖的讀是指,總是讀取被鎖定行的最新乙份快照資料,因此其它事務修改了該行資料,該事務也能讀取到,這也貼合了 rc 隔離級別下允許不可重複讀的問題;

在 repeatable read 事務隔離級別下,一致性不加鎖的讀是指,事務讀取到的資料,要麼是事務開始前就已經存在的資料,要麼是事務自身插入或者修改過的資料。(下面將以此隔離級別說明);

不加鎖的簡單的 select 都屬於快照讀,例如:

select * from t where id=1;
與快照讀相對應的則是當前讀(current read),當前讀就是讀取最新資料,而不是歷史版本的資料。加鎖的 select 就屬於當前讀,例如:

select * from t where id=1 lock in share mode;

select * from t where id=1 for update;

select...for update 對讀取的行記錄加乙個 x 鎖,其它事務不能對已鎖定的行加上任何鎖。

select...lock in share mode 對讀取的行記錄加乙個 s 鎖,其它事務可以向被鎖定的行加 s 鎖,但是如果加 x 鎖,則會被阻塞。

多版本併發控制技術的英文全稱是:multiversion concurrency control,簡稱 mvcc,是通過儲存資料的歷史版本,通過對資料行的多個版本管理來實現資料庫的併發控制。這樣我們就可以通過比較版本號決定資料是否顯示出來,讀取資料的時候不需要加鎖也可以保證事務的隔離效果(可以理解成樂觀鎖)。

多版本併發控制(mvcc)只在可重複讀(repeatable read)和提交讀(read committed)兩個隔離級別下工作,其他兩個隔離級別都和 mvcc 不相容,因為未提交讀(read uncommitted),總是讀取最新的資料行,而不是符合當前事務版本的資料行;而可序列化(serializable) 則會對所有讀取的行都加鎖。

mysql 的大多數事務型儲存引擎實現的都不是簡單的行級鎖。基於提公升併發效能的考慮,它們一般都同時實現了多版本併發控制(mvcc)。不僅是 mysql,包括 oracle、postgresql 等其他資料庫系統也都實現了 mvcc,但各自的實現機制不盡相同,因為 mvcc 沒有乙個統一的實現標準,典型的有樂觀(optimistic)併發控制和悲觀(pessimistic)併發控制。

mvcc 的流程過程非常類似於 svn 等版本控制系統的流程,或者說 svn 等版本控制系統就是使用的 mvcc 思想。

通過 mvcc 可以讓讀寫互相不阻塞,即讀不阻塞寫,寫不阻塞讀,這樣就可以提公升事務併發處理能力。

提高併發的演進思路:

因為 innodb 的 mvcc 採用了樂觀鎖的方式,讀取資料時並不需要加鎖,對於寫操作,也只鎖定必要的行。

一致性非鎖定讀也被稱為快照讀,這也是 innodb 儲存引擎的預設讀取方式,當我們查詢資料庫在某個時間點的快照時,只能看到這個時間點之前事務提交更新的結果,而不能看到這個時間點之後事務提交的更新結果。

事務版本號:每開啟乙個事務,我們都會從資料庫中獲得乙個事務 id(也就是事務版本號),這個事務 id 是自增長的,通過 id 大小,我們就可以判斷事務的時間順序。

行記錄的隱藏列:innodb 的葉子段儲存了資料頁,資料頁中儲存了行記錄,而在行記錄中有一些重要的隱藏字段:

undo log:innodb 將行記錄快照儲存在了 undo log 裡,我們可以在回滾段中找到它們,如下圖所示,回滾指標將資料行的所有快照記錄都通過鍊錶的結構串聯了起來,每個快照的記錄都儲存了當時的 db_trx_id,也是那個時間點操作這個資料的事務 id。這樣如果我們想要找歷史快照,就可以通過遍歷回滾指標的方式進行查詢。

Mysql多版本併發控制

mysql的絕大多數事務型儲存引擎都不是簡單的行級鎖。他們實現了多版本的併發控制,也就是mvvc,當然,支援mvvc的資料庫並不只有mysql,orcale postgresql等都實現了mvvc,只不過他們實現的方式不同而已,因為mvvc沒有乙個統一的規範。其實mvvc可以理解為行級鎖的一種變異,...

MySQL 架構 多版本併發控制

大部分的mysql的儲存引擎,比如innodb,falcon,以及pbxt並不是簡簡單單的使用行鎖機制。它們都使用了行鎖結合一種提高併發的技術,被稱為mvcc 多版本併發控制 mvcc並不單單應用在mysql中,其他的資料庫如oracle,postgresql,以及其他資料庫也使用這個技術。mvcc...

mysql多版本併發控制MVCC

innodb的mvcc是通過在每行記錄的後面儲存兩個隱藏的列來實現的,這兩個列乙個儲存行的建立時間,乙個儲存行的過期時間。但是並不是儲存時間而是儲存版本號,每開始乙個新的事務,版本號會自動遞增。事務開始時刻的系統版本號會作為事務的版本號,用來和查詢到每行記錄的版本號進行比較。select innod...