數據庫的隔離級別和 MVCC

MVCC (Multi-Version Concurrency Control),多版本併發控制。數據庫實現併發訪問請求,就是基於 MVCC 實現的。

首先了解下數據庫事物的隔離級別。

隔離級別

  • Read Uncommiteed 讀未提交
    讀取未提交的數據,即其他事物已經修改但還未提交的數據,這是最低的隔離級別。
  • Read committed 讀已提交
    讀取已提交的數據。在一個事物中,對同一條數據,可能會出現讀取不一致現象。
  • Repeatable Read 可重複讀
    可重複讀取,在一個事物中,對同一條數據,確保多次讀取的結果一樣。(Mysql 默認隔離級別)
  • Serializable 序列化
    串行執行,數據庫中的事物都是串行執行,不能並行執行,效率最差。

隔離級別主要是爲了實現讀操作不需要加鎖, 從而提高數據庫的性能。

不同隔離級別出現的問題

隔離級別 髒讀 幻讀 不可重複讀
讀未提交
讀已提交
可重複度
序列化

Read Uncommiteed 和 Serializable 不需要使用多版本控制技術就可實現。
Read Uncommiteed :直接修改原始數據即可,其他事物查看數據的時候直接可以查看到,無須其他操作即可實現。
Serializable: 所有的事物都是串行執行的,只需要一個獨佔鎖即可實現。

其中Read committed 和 Repeatable Read 兩種事物隔離使用到 MVCC 進行實現的。

MVCC 實現原理

MVCC (Multi-Version Concurrency Control),多版本併發控制。MVCC 對每行數據維護多個版本。可以實現讀操作不需要加鎖,即可實現在同一個事物中多次讀取一條數據,結果都是一致的。

MySql InnoDB存儲引擎爲例,InnoDB 在表中增加了兩個隱藏字段。每個事物都是一個事物ID,其中一個列存儲了修改時的事物ID,另一個列存儲的是刪除這條數據的事物ID。每開啓一個事物都會生成一個自增的事物ID,當查詢一條數據時,都會用當前的事物ID,和隱藏列中的事物ID進行對比,然後根據不同的事物隔離級別來決定是否返回該行數據。

下面對 Select、Delete、 Insert、 Update 四種操作了解 MVCC 的實現原理

創建一個表,表中有兩個字段 id、name。MVCC 中增加兩個隱藏列 update_version、delete_version。
update_version: 存儲修改時,當前事物的ID
delete_version: 存儲刪除時,當前事物的ID。

Insert

假設當前事物的ID=1

插入一條數據時,update_version 存儲當前事物的ID,。

id name update_version delete_version
1 張三 1

Update

當前事物ID=2

修改一條數據時,會新把原來的行復制一份,並把之前的那條數據delete_version 列設置成當前的事物ID 2,標記當前數據爲刪除,新插入的數據 update_version 設置成當前事物ID 2。

id name update_version delete_version
1 張三 1 2
1 張小三 2

Delete

當前事物ID=4

刪除數據時,直接把 delete_version 這個字段設置爲當前的事物ID 4.

id name update_version delete_version
1 張三 1 2
1 張小三 2 4

Select

查詢必須滿足以下兩種條件才能返回:

  • 行的 update_version 版本號小於等於當前事物ID
  • 行的 delete_version 版本無值或大於當前事物ID
Select 示例一

比如事物ID=3, 查詢 id=1 的數據

id name update_version delete_version
1 張三 1 2
1 張小三 2

查詢條件爲:id=1 and update_version<=3 and delete_version>3
查詢出來的數據應該是 “張小三” 這條數據。

Select 示例二

假設,事物ID 3 執行的查詢時間比較長,這時事物4開始刪除這條數據,並提交,然後事物ID=3 的查詢纔開始執行,應該是能查詢到 id=1 的數據。

事物ID=4 刪除後的數據。

id name update_version delete_version
1 張三 1 2
1 張小三 2 4

查詢條件爲:id=1 and update_version<=3 and delete_version>3
查詢結果應該爲 “張三” 這條數據。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章