什么是ReadView,什么樣的ReadView可見 ?
一、定義
ReadView 是 InnoDB 中一個至關(guān)重要的概念,它是實現(xiàn)MVCC的基礎(chǔ),同時他也是支持不同的事務(wù)隔離級別的基礎(chǔ),同時提高系統(tǒng)的并發(fā)能力和性能。
它到底是干啥的?簡單來說,其實就是一句話:讀視圖(Read View) 主要來幫我們解決可見性的問題的, 即它會來告訴我們本次事務(wù)能看到哪個 undolog版本,不能看到哪個undolog版本
我們都知道,MySQL中用不同的事務(wù)隔離級別,比如我們常見的 RR 和 RC,RR要求在一個事務(wù)中,多次讀取的結(jié)果是保持一致的,而RC則要求每次都要讀取到最新的值。
那么,具體如何實現(xiàn)的RR和RC的讀數(shù)據(jù)的時候的不同現(xiàn)象,就是這個快照
在可重復(fù)讀(Repeatable Read)級別下,讀視圖(ReadView)會在事務(wù)中第一次 select 語句執(zhí)行時生成,在本事務(wù)中第二次 select 語句時會復(fù)用第一次的讀視圖(ReadView),只有在本事務(wù)中對數(shù)據(jù)進行更改才會更新讀視圖
在讀已提交(Read Committed)級別下,每次讀取都會重新生成一個讀視圖(ReadView),總是讀取行的最新版本
在mysql5.6中的 ReadView 的定義更加直觀:

也就是說,在 Read View 中有幾個重要的屬性:
-
trx_ids,表示在生成 ReadView 時當(dāng)前系統(tǒng)中活躍的讀寫事務(wù)的 事務(wù)id 列表
-
low_limit_id,應(yīng)該分配給下一個 事務(wù)的id 值
-
up_limit_id,未提交的事務(wù)中最小的事務(wù) id
-
creator_trx_id,創(chuàng)建這個 Read View 的事務(wù)id
trx_ids 中包含了 low_limit_id 和 up_limit_id 的信息,其實 trx_ids = [up_limit_id,low_limit_id)
(但是需要注意,它并不一定連續(xù),只是會包含 up_limit_id,并且小于 low_limit_id,比如他可能是5, 7, 8, 11),
并且你沒看錯,up_limit_id 就是表示最低水位,low_limit_id 就是表示最高水位
網(wǎng)上還有些資料這里有 min_trx_id、max_trx_id、m_ids等的說法,我翻了下源碼5.6、5.7、8.0,并沒有找到出處。就先不糾結(jié)了,以源碼為準(zhǔn)。
也就是說,每一次讀取數(shù)據(jù)的時候(RC情況下),都會生成一個 ReadView,并且在其中記錄上 trx_ids(包含了[up_limit_id, low_limit_id))和 creator_trx_id
那么,一個事務(wù)能看到哪個 undolog版本,不能看到哪個undolog版本該如何判斷呢 ?
假如一個 ReadView 的內(nèi)容為:
trx_ids = [5,6,8)
low_limit_id = 8
up_limit_id = 5
creator_trx_id = 7
假設(shè)當(dāng)前事務(wù)要讀取某一個undolog版本的記錄行,該記錄行的事務(wù)id為:db_trx_id,那么,就有以下幾種情況了:
-
1、db_trx_id < up_limit_id,即小于5的事務(wù),說明該事務(wù) db_trx_id 在生成ReadView之前就已經(jīng)提交了,那么該事務(wù)的結(jié)果就是可見的
-
2、db_trx_id > low_limit_id,即大于8的事務(wù),說明該事務(wù)db_trx_id 在生成 ReadView 后才生成,所以該事務(wù)的結(jié)果就是不可見的
-
3、up_limit_id < db_trx_id < low_limit_id,即大于等于5,小于8,這種情況下,會再拿事務(wù)id 和 Read View 中的 trx_ids 進行逐一比較
-
如果,事務(wù)id 在 trx_ids 列表中,如6,那么表示在當(dāng)前事務(wù)開啟時,這個事務(wù)還是活躍的,那么這個記錄對于當(dāng)前事務(wù)來說應(yīng)該是不可見的
-
如果,事務(wù)id 不在 trx_ids 列表中,如7,那么表示的是在當(dāng)前事務(wù)開啟之前,其他事務(wù)對數(shù)據(jù)進行修改并提交了,所以,這條記錄對當(dāng)前事務(wù)就應(yīng)該是可見的
-
當(dāng)然這里有個例外情況,那就是這個 db_trx_id = creator_trx_id,說明當(dāng)前undolog版本的記錄行是由創(chuàng)建這個 Read View 的事務(wù)提交的,那么就肯定是可見的
-
總結(jié)一下就是,一個事務(wù),能看到的是在它開始之前就已經(jīng)提交的事務(wù)的結(jié)果,而未提交的結(jié)果都是不可見的。

浙公網(wǎng)安備 33010602011771號