mysql中的mvcc解讀

2022-05-17 15:11:23 字數 2516 閱讀 5924

對於mvcc想必大家也看到了不少原始碼層的解讀,最大特點就是分析的是比較深入了,但是卻不大好理解,最後有種不明覺厲的感覺,以至於在面試中經常翻船。

我們換個角度來解讀一下, 在表設計中,我們有一種策略,那就是盡可能保留資料變化的

歷史,比如在資料發生變化時我們不會直接刪除資料,而是把它轉換為兩類操作。

比如修改乙個賬戶的餘額,這是敏感資訊,屬於狀態型資料,在更新時需要保留完整的資料

變化歷史,那麼把餘額從100變化為200的過程,會轉化為1條 update 語句,1條 insert 語句。

如下的操作是我們預期的結果:

可以把這個過程改造為:

有的同學說,這個和 mvcc 有什麼關係呢,其實 mvcc 的實現原理也是類似的方式,我們就以

這種方式作為例子來解釋,在這種情況下,第1行 update 語句對應的資料可以理解為是之前

的資料映象,而第2行則是資料處理後的結果。

如果存在大量的併發讀寫,我們可以把讀的壓力分擔出來,即資料的查詢可以指向映象,而

資料的修改指向當前的變化資料,這樣兩者是乙個互補的關係。

這種情況類似下面的方式,比如 t1,t2,t3三個順序時間裡發生了三次請求,分別是一次寫

請求和兩次讀請求.

那麼在 mysql 中會先在 t1時間生成乙個快照,比如資料標識是90,然後在這個基礎上進行

資料修改,資料標識為100,但是事務未提交。

在 t1寫資料的事務內,t2時間的讀請求會讀取 t1時間生成的快照資料,讀取的資料標識

依舊是 90,t3時間的讀請求也是類似。所以mvcc本身還是比較接地氣的,只是我們理解的方式有些高大上,消化不了了。我們小結一下:

1.表設計中資料生命週期的管理是一種體系化的管理方式,原理和思路是通用的。2.資料生命週期管理有兩個重要的標識,乙個是標識資料變化的,乙個是標識資料可用狀態的。

明白了這些,理解 innodb 的 mvcc 就很簡單了,我們使用類似的思路來做下解讀,假設在每

行記錄後面儲存兩個隱藏的列來實現的,這兩個列,分別儲存了這個行的建立時間,乙個保

存的是行的刪除時間。這裡儲存的是系統版本號,會自動遞增,我們按照 dml 的幾個維度進

行闡述。

1)、首先是 insert 操作, 事務 id 假設是1

id name create version delete version

1 test 1

2)、update 操作,會先把當前記錄標識為已刪除,然後新增一列資料,寫入相應的版本號,

在這裡就是2,和上一條的 delete_version 是一致的,比如把字段 name 修改為 new_test

id name create version delete version

1 test 1 2

1 new_test 2

3)delete 操作,就是把當前記錄標識為已刪除

id name create version delete version

1 new_value 2 3

此外需要考慮的是上面的實現方式中,如果事務發生回滾該如何處理,這個是我們需要重點

考慮的,也是對資料週期管理流程的乙個補充,這裡我們就要引出 innodb 層的實現 undo.

我們來設想乙個問題,原有的映象資料在表中存放顯然是難以維護的,而且從儲存上也是一

筆不小的開銷,所以從價效比考慮,這部分的內容應該是獨立存放的,這個存放的地方就是

undo 日誌裡面,一旦出現了事務回滾,我們可以把已有的資料狀態通過逆向應用保證事務

的 acid 特性。

要實現這個細粒度的操作,在 innodb 的設計中,實際上所有行資料會增加三個內部屬性列:

(1)db_trx_id,6位元組,記錄每一行最近一次修改它的事務 id;

(2)db_roll_ptr,7位元組,記錄指向回滾段 undo 日誌的指標;

(3)delete bit,標識該記錄是否被刪除,不是真正的刪除資料;

把這三個列組合起來,就可以標記資料的週期性,並定位到相應的事務,在需要的時候進行

回滾。比如一張表 test (id,name)主鍵為 id 列

 insert 的資料在 redo 中順序記錄 insert 操作,同時生成 undo 記錄,為逆操作 delete

 delete 的資料在 redo 中順序記錄 delete 操作,同時生成 undo 記錄,為逆操作 insert

 update 的資料在 redo 中順序記錄 update 操作,同時生成 undo 記錄,為逆操作 update,

原來是從 id=1 變成 id=3,則逆操作為 id =3,變成 id=1

對於 innodb 來說,無論是更新,刪除,都只是設定行記錄上的 deleted version 標記位,

而不是真正的刪除記錄,後續這些記錄的清理,是通過 purge 後台程序實現的。

此外,需要說明的是只有在隔離級別 read-committed 和 repeatable-read 才能使用 mvcc,

read-uncommited 由於是讀到未提交的,所以不存在版本的問題,而 serializable 則會對

所有讀取的行加鎖。

關於mysql 中 mvcc的探索

關於mvcc的探索與研究 之前沒有仔細研究過mysql的mvcc的具體實現,網上的大多數資料都是在講readview在當前讀和快照讀的情況下,mysql讀取的規則與邏輯,只講了在乙個是事務中,mysql如何實現可重複讀的 沒有說明mysql在併發事務中,更新時,會如何處理併發的資料,並且最後怎麼樣保...

詳細解讀mysql 詳細解讀MySQL中的許可權

一 前言 很多文章中會說,資料庫的許可權按最小許可權為原則,這句話本身沒有錯,但是卻是一句空話。因為最小許可權,這個東西太抽象,很多時候你並弄不清楚具體他需要哪些許可權。現在很多mysql用著root賬戶在操作,並不是大家不知道用root許可權太大不安全,而是很多人並不知道該給予什麼樣的許可權既安全...

mysql 關於innodb中MVCC的一些理解

mvcc multiversion concurrency control 即多版本併發控制技術,它使得大部分支援行鎖的事務引擎,不再單純的使用行鎖來進行資料庫的併發控制,取而代之的是把資料庫的行鎖與行的多個版本結合起來,只需要很小的開銷,就可以實現非鎖定讀,從而大大提高資料庫系統的併發效能 讀鎖 ...