首頁  >  文章  >  資料庫  >  什麼是MVCC,為什麼要設計間隙鎖?

什麼是MVCC,為什麼要設計間隙鎖?

青灯夜游
青灯夜游轉載
2022-03-11 10:52:263005瀏覽

這篇文章帶大家了解MVCC,介紹一下MVCC與隔離等級的關係,從設計的角度上,聊聊為什麼要設計出MVCC,且RC和RR的隔離等級到底有什麼不同。

MVCC作用

MVCC使得大部分支援行鎖的交易引擎,不再單純的使用行鎖來進行資料庫的並發控制,而是把資料庫的行鎖和行的版本號碼結合起來,只需要很小的開銷,就可以實現非鎖定讀。 從而提高資料庫的並發效能。

MVCC是採用無鎖定的形式來解決讀取-寫入衝突問題。這裡的讀是指的快照讀。 即MVCC實現的快照讀! ! !

什麼是MVCC

多版本並發控制(MVCC)是一種解決讀取-寫入衝突的無鎖定並發控制。

每一行記錄都有兩個隱藏欄位:建立版本號和回滾指標。事務開啟後存在一個事務id。多個並發事務同時操作某行,不同的事務對該行update操作會產生多個版本,然後透過回滾指標組成undo log鏈。而MVCC的快照讀取正是透過事務id和創建版本號而實現的快照讀取。

MVCC與隔離等級的關係

MVCC是為了解決讀取-寫入問題。且透過不同的配置,也可以解決交易開啟後,快照讀不可重複讀取的問題。

  • 無法重複讀取:在同一個交易中讀取某些資料已經改變,或某些記錄已刪除。

  • 幻讀:一個事務按照相同的查詢條件重新讀取先前檢索過的數據,卻發現其他事務插入了滿足查詢條件的新數據,這種現象稱為幻讀。

RC和RR都實作了MVCC,但為什麼RR解決了RC不可重複讀取的問題?

你可以這樣認為,RC之所以有不可重複讀的問題,只是因為開發者有意設定的(設定多種隔離級別,使用者可以根據情況設定)。本來資料都提交到資料庫了,RC讀取出來也沒什麼問題呀?況且Oracle資料庫本身的隔離等級就是RC。

READ-COMMITTED(已提交)
讀取已提交RC,在這一隔離等級下,可以在SQL層級做到一致性讀取,每次SQL語句都會產生新的ReadView。這就意味著兩次查詢之間有別的事務提交了,是可以讀到不一致的資料的。

REPEATABLE-READ(可重複讀取)
可重複讀取RR,在第一次創建ReadView後,這個ReadView就會一直維持到事務結束,也就是說,在事務執行期間可見性不會發生變化,從而實現了事務內的可重複讀取。

MVCC與間隙鎖定

MVCC無鎖定解決了讀取-寫入衝突的問題。 並且解決了不可重複讀取問題。從而實現了RC和RR兩個隔離等級。

間隙鎖本質上依舊是鎖,會阻塞兩個並發交易的執行。

那麼RR為什麼還要進入間隙鎖,難道只是為了解決幻讀的問題嗎?

注意:只有RR隔離等級才存在間隙鎖定。

間隙鎖在一定程度上可以解決幻讀的問題,但是間隙鎖的引入我覺得更多是為了處理binlog的statement模式的bug。

mysql資料庫的主從複製依靠的是binlog。而在mysql5.0之前,binlog模式只有statement格式。這種模式的特徵:binlog的記錄順序是依照資料庫事務commit順序為順序的。

當不存在間隙鎖定的情況下,會有以下的場景:
master函式庫有這麼兩個交易:

1、事務a先delete id<6,然後在commit前;
2、事務b直接insert id=3,並且完成commit;
3、事務a進行commit;
此時binlog記錄的日誌是:事務b先執行,事務a在執行(binlog記錄的是commit順序)

那麼主庫此時表裡面有id=3的記錄,但是從庫是先插入再刪除,從庫裡面是沒有記錄的。

這就導致了主從資料不一致。

為了解決這個bug,所以RR等級引入了間隙鎖定。

【相關推薦:mysql影片教學

#

以上是什麼是MVCC,為什麼要設計間隙鎖?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:jianshu.com。如有侵權,請聯絡admin@php.cn刪除