切換語言為:簡體

MVCC 是如何保持資料一致性的

  • 爱糖宝
  • 2024-07-30
  • 2097
  • 0
  • 0

MVCC(Multi-Version Concurrency Control)是一種併發控制機制,用於解決資料庫併發訪問中,資料一致性問題。它透過在讀寫操作期間儲存多個數據版本,以提供併發事務間的隔離性,從而避免了傳統的鎖機制所帶來的資源爭用和阻塞問題。

所謂的一致性問題,就是在併發事務執行時,應該看到那些資料和不應該看到那些資料。

在 MVCC 機制中,每個事務的讀操作都能看到事務開始之前的一致性資料快照,而不受其他併發事務的修改的影響。核心思想是透過建立多個數據版本,保持事務的一致性和隔離性

使用 MVCC 機制解決了 RR 隔離級別中,部分幻讀問題,但又沒把全部幻讀問題都解決。

  • MVCC 解決了 RR 隔離級別中,快照讀的幻讀問題。多次查詢快照讀時,因為 RR 級別是複用 Read View(讀檢視),所以沒有幻讀問題。

  • 但 MVCC 解決不了 RR 隔離級別中,如果遇到快照讀和當前讀(讀取當前最新的資料)中間發生過新增操作,那麼 Read View 不能複用,就出現了幻讀的問題。

# 快照讀和當前讀

快照讀:是指在一個事務中,讀取的資料版本是在事務開始時已經存在的資料版本,而不是最新的資料版本。這種讀取方式提供了事務在執行期間看到的資料檢視的一致性,select 查詢就是快照讀

當前讀:是指在事務中讀取最新的資料版本,以下幾種操作都是當前讀:

  • select ... for update;

  • select ... lock in share mode;

  • insert ...

  • update ...

  • delete ...

# MVCC 實現原理

MVCC 主要是依靠以下兩部分實現的:

  1. Undo Log 鏈

  2. Read View(讀檢視或者叫一致性檢視)

# Undo Log 鏈

我們知道 Undo Log 主要是用於資料庫中事務回滾的,但在 MVCC 機制中也發揮著重要的作用,那什麼是 Undo Log 鏈呢?

Undo Log 鏈是指在每個資料物件上維護的 Undo Log 記錄連結串列。每張表都會有與之相對應的 Undo Log 鏈,用於記錄修改前的資料資訊(以方便資料進行回滾)。

MVCC 是如何保持資料一致性的

# Read View

Read View(讀檢視)用於管理事務之間資料可見性的一種機制。Read View 在特定時刻為事務建立的一個快照,該快照包含了在該時刻所有未提交事務的事務識別符號,以及其他一些輔助資訊。

在 Read View 中包含了以下 4 個主要的欄位:

  1. m_ids:當前活躍的事務編號集合。

  2. min_trx_id:最小活躍事務編號。

  3. max_trx_id:預分配事務編號,當前最大事務編號+1。

  4. creator_trx_id:ReadView 建立者的事務編號。

RC 級別中,每次快照讀都會生成一個全新的 Read View,而 RR 級別中同一個事務會複用一個 Read View。

有了 Read View 和 Undo Log 鏈之後,併發事務在查詢時就知道要讀取那些資料了。

# 判斷方法

判斷方法是根據 Read View 中的 4 個重要欄位,先去 Undo Log 中最新的資料行進行比對,如果滿足下面 Read View 的判斷條件,則返回當前行的資料,如果不滿足則繼續查詢 Undo Log 的下一行資料,直到找到滿足的條件的資料為止,如果查詢完沒有滿足條件的資料,則返回 NULL。

# 判斷規則

  1. trx_id==creator_trx_id:先將 Undo Log 最新資料行中的 trx_id 和 ReadView 中的 creator_trx_id 進行對比,如果他們兩個值相同,則說明是在同一個事務中執行,那麼直接返回當前 Undo Log 的資料行即可,如果不相等,則繼續下面流程。

  2. trx_id<min_trx_id:如果 trx_id 小於 min_trx_id,則說明在執行查詢時,其他事務已經提交此行資料了,那麼直接返回此行資料即可,如果大於等於,則繼續下面流程。

  3. trx_id>max_trx_id:如果 trx_id 如果大於等於 max_trx_id,則說明該行資料比當前操作執行的晚,當前行資料不可見,繼續執行後續流程。

  4. min_trx_id<=trx_id<max_trx_id:trx_id 在 min_trx_id 和 max_trx_id 之間還分為以下兩種情況:

    1. trx_id 在 m_ids 中:說明事務尚未執行完,該行資料不可被訪問。

    2. trx_id 未在 m_ids 中:說明事務已經執行完,可以返回該行資料。

以上判斷規則從 Undo Log 最新的行資料,逐行對比,直到找到匹配的資料,否則查詢完未匹配上,則返回 NULL。

# 小結

MVCC 的實現主要依賴讀檢視 Read View 和 Undo Log 鏈,透過 Read View 中的 4 個欄位,判斷要讀取 Undo Log 中資料,從而解決了資料庫併發訪問中,資料一致性的問題。

MVCC 主要應用於 InnoDB 引擎中的 RC 事務隔離級別和 RR 隔離級別,其中 RC 隔離級別每次快照讀都會生成一個新的 Read View,而 RR 隔離級別只在第一次快照讀時生成 Read View,之後會複用 Read View,從而解決了(部分)幻讀問題。

0則評論

您的電子郵件等資訊不會被公開,以下所有項目均必填

OK! You can skip this field.