您現在的位置是:首頁 > 網路遊戲首頁網路遊戲

MySQL資料庫的核心MVCC詳解

簡介MVCC 模型在 MySQL 中的具體實現則是由 3 個隱式欄位,undo 日誌 ,Read View 等去完成的,具體可以看下面的 MVCC 實現原理4.MVCC的好處首先我們要清楚資料庫中的併發場景有三種,分別是:在這裡插入圖片描述然後

資料系統的核心是什麼

MySQL資料庫的核心MVCC詳解

本文給大家詳細的類介紹下MVCC的內容,MVCC對大家的工作和麵試都是非常重要的內容。

一、前置內容

1.ACID

在看MVCC之前我們先補充些基礎內容,首先來看下事務的ACID。

MySQL資料庫的核心MVCC詳解

2.MySQL的核心日誌

在MySQL資料庫中有三個非常重要的日誌binlog,undolog,redolog。

MySQL資料庫的核心MVCC詳解

舉例演示為:

3.隔離級別

MySQL的事務隔離級別有四個,分別為:

事務隔離級別指的是一個事務對資料的修改與另一個並行的事務的隔離程度,當多個事務同時訪問相同資料時,如果沒有采取必要的隔離機制,就可能發生以下問題:

問題描述髒讀一個事務讀到另一個事務未提交的更新資料,所謂髒讀,就是指事務A讀到了事務B還沒有提交的資料,比如銀行取錢,事務A開啟事務,此時切換到事務B,事務B開啟事務——>取走100元,此時切換回事務A,事務A讀取的肯定是資料庫裡面的原始資料,因為事務B取走了100塊錢,並沒有提交,資料庫裡面的賬務餘額肯定還是原始餘額,這就是髒讀幻讀是指當事務不是獨立執行時發生的一種現象,例如第一個事務對一個表中的資料進行了修改,這種修改涉及到表中的全部資料行。同時,第二個事務也修改這個表中的資料,這種修改是向表中插入一行新資料。那麼,以後就會發生操作第一個事務的使用者發現表中還有沒有修改的資料行,就好象 發生了幻覺一樣。不可重複讀在一個事務裡面的操作中發現了未被操作的資料 比方說在同一個事務中先後執行兩條一模一樣的select語句,期間在此次事務中沒有執行過任何DDL語句,但先後得到的結果不一致,這就是不可重複讀隔離級別描述READ_UNCOMITTED讀未提交(髒讀)最低的隔離級別,一切皆有可能。READ_COMMITED讀已提交,ORACLE預設隔離級別,有幻讀以及不可重複讀風險。REPEATABLE_READ可重複讀,解決不可重複讀的隔離級別,但還是有幻讀風險。SERLALIZABLE序列化,最高的事務隔離級別,不管多少事務,挨個執行完一個事務的所有子事務之後才可以執行另外一個事務裡面的所有子事務,這樣就解決了髒讀、不可重複讀和幻讀的問題了

MySQL資料庫的核心MVCC詳解

在這裡插入圖片描述資料庫的併發場景:

讀讀:不會存在任何問題,也不需要併發控制

讀寫:有執行緒安全問題,可能會造成事務隔離性問題,可能遇到髒讀,幻讀,不可重複讀,需要MVCC控制

寫寫:有執行緒安全問題,可能會存在更新丟失問題,比如第一類更新丟失,第二類更新丟失

二、MVCC

1.什麼是MVCC

MVCC

(Multi-Version Concurrency Control):多版本併發控制,是一種併發控制的方法,一般在資料庫管理系統中,實現對資料庫的併發訪問,在程式語言中實現事務記憶體。

MVCC

在 MySQL InnoDB 中的實現主要是為了提高資料庫併發效能,用更好的方式去處理讀-寫衝突,做到即使有讀寫衝突時,也能做到不加鎖,非阻塞併發讀。

2.什麼是當前讀和快照讀

在學習 MVCC 多版本併發控制之前,我們必須先了解一下,什麼是 MySQL InnoDB 下的當前讀和快照讀。

MySQL資料庫的核心MVCC詳解

MySQL資料庫的核心MVCC詳解

在這裡插入圖片描述

其實MVCC 就是為了實現讀-寫衝突不加鎖,而這個讀指的就是快照讀, 而非當前讀,當前讀實際上是一種加鎖的操作,是悲觀鎖的實現。

3.三者關係

當前讀,快照度和MVCC的關係是如何的呢?

MVCC 多版本併發控制是(維持一個數據的多個版本,使得讀寫操作沒有衝突) 的概念,只是一個

抽象概念

,並非實現

因為 MVCC 只是一個抽象概念,要實現這麼一個概念,MySQL 就需要提供具體的功能去實現它,(快照讀就是 MySQL 實現 MVCC 理想模型的其中一個非阻塞讀功能)。而相對而言,當前讀就是悲觀鎖的具體功能實現

要說的再細緻一些,快照讀本身也是一個

抽象概念

,再深入研究。MVCC 模型在 MySQL 中的具體實現則是由 3 個隱式欄位,undo 日誌 ,Read View 等去完成的,具體可以看下面的 MVCC 實現原理

4.MVCC的好處

首先我們要清楚資料庫中的併發場景有三種,分別是:

MySQL資料庫的核心MVCC詳解

在這裡插入圖片描述

然後來看MVCC的好處:

多版本併發控制(MVCC)是一種用來解決讀-寫衝突的無鎖併發控制,也就是為事務分配單向增長的時間戳,為每個修改儲存一個版本,版本與事務時間戳關聯,讀操作只讀該事務開始前的資料庫的快照。所以 MVCC 可以為資料庫解決以下問題:

在併發讀寫資料庫時,可以做到在讀操作時不用阻塞寫操作,寫操作也不用阻塞讀操作,提高了資料庫併發讀寫的效能

同時還可以解決髒讀,幻讀,不可重複讀等事務隔離問題,但不能解決更新丟失問題

5.MVCC工作原理

MVCC 的目的就是多版本併發控制,在資料庫中的實現,就是為了解決讀寫衝突,它的實現原理主要是依賴記錄中的 3個隱式欄位,undo日誌 ,Read View 來實現的。

5.1 三個隱藏欄位

MySQL資料庫的核心MVCC詳解

在這裡插入圖片描述  DB_ROW_ID 是資料庫預設為該行記錄生成的唯一隱式主鍵,DB_TRX_ID 是當前操作該記錄的事務 ID ,而 DB_ROLL_PTR 是一個回滾指標,用於配合 undo日誌,指向上一個舊版本

舉例如:

MySQL資料庫的核心MVCC詳解

在這裡插入圖片描述

MySQL資料庫的核心MVCC詳解

在這裡插入圖片描述

MySQL資料庫的核心MVCC詳解

在這裡插入圖片描述

從上面,我們就可以看出,不同事務或者相同事務的對同一記錄的修改,會導致該記錄的undo log成為一條記錄版本線性表,既連結串列,undo log 的鏈首就是最新的舊記錄,鏈尾就是最早的舊記錄。

undolog:回滾日誌,儲存了事務發生之前的資料的一個版本,作用:

可以用於回滾

同時可以提供多版本併發控制下的讀(MVCC),也即非鎖定讀。

事務開始之前,將當前事務版本生成 undo log,undo log 也會產生 redo log 來保證 undo log 的可靠性。

當事務提交之後,undo log 並不能立馬被刪除,而是放入待清理的連結串列。

由 purge 執行緒判斷是否有其它事務在使用 undo 段中表的上一個事務之前的版本資訊,從而決定是否可以清理 undo log 的日誌空間。

5.2 ReadView

什麼是 Read View,說白了 Read View 就是事務進行快照讀操作的時候生產的讀檢視 (Read View),在該事務執行的快照讀的那一刻,會生成資料庫系統當前的一個快照,記錄並維護系統當前活躍事務的 ID (當每個事務開啟時,都會被分配一個 ID , 這個 ID 是遞增的,所以最新的事務,ID 值越大)

所以我們知道 Read View 主要是用來做可見性判斷的, 即當我們某個事務執行快照讀的時候,對該記錄建立一個 Read View 讀檢視,把它比作條件用來判斷當前事務能夠看到哪個版本的資料,既可能是當前最新的資料,也有可能是該行記錄的undo log裡面的某個版本的資料。

Read View遵循一個可見性演算法,主要是將要被修改的資料的最新記錄中的 DB_TRX_ID(即當前事務 ID )取出來,與系統當前其他活躍事務的 ID 去對比(由 Read View 維護),如果 DB_TRX_ID 跟 Read View 的屬性做了某些比較,不符合可見性,那就透過 DB_ROLL_PTR 回滾指標去取出 Undo Log 中的 DB_TRX_ID 再比較,即遍歷連結串列的 DB_TRX_ID(從鏈首到鏈尾,即從最近的一次修改查起),直到找到滿足特定條件的 DB_TRX_ID , 那麼這個 DB_TRX_ID 所在的舊記錄就是當前事務能看見的最新老版本。

MySQL資料庫的核心MVCC詳解

在這裡插入圖片描述

舉例說明:

MySQL資料庫的核心MVCC詳解

在這裡插入圖片描述

分析:

MySQL資料庫的核心MVCC詳解

在這裡插入圖片描述

第二種情況:

MySQL資料庫的核心MVCC詳解

在這裡插入圖片描述

分析:

MySQL資料庫的核心MVCC詳解

在這裡插入圖片描述

最後完成的繪圖:

MySQL資料庫的核心MVCC詳解

在這裡插入圖片描述

擴充套件閱讀:https://www。ixiera。com

總結

:能否看到事務修改的資料,取決於可見性演算法,可見性演算法比較的時候又取決於ReadView中的結果值!因為在不同隔離級別的時候,生成ReadView的時機是不同的RC:每次執行時快照讀都會重新生成新的ReadViewRR:只有當第一次事務進行快照讀的時候才會生成ReadView,之後的快照讀操作都會複用當前的ReadView 。

Top