mysql mvvc原理 Mysql MVVC筆記

2021-10-19 21:33:30 字數 2635 閱讀 8471

什麼是mvvc,為什麼要用它

在mysql的也就是讀不會加鎖。

舉個不是很準確的例子,有兩個事務t1,t2,它們的id分別是1,2。由於事務id是遞增唯一的,因此可以認為t2在邏輯上是後於t1發生的,當t2想要查詢(select)某一行,這行的trx_id(最後修改本行資料的事務id)為1,那麼我們就可以認為這一行對t2是可見的,因此返回改行資料。

其實這個例子問題很大,這也是為什麼要寫這篇文章記錄一下

前置知識

在innodb中,每個行後面都有一些額外的字段,主要要知道db_trx_id(最近修改行的事務id),db_roll_ptr(指向該行被修改的前乙個狀態),delete_version(行是否被刪除)。

當某個事務t對一行r做update操作時,若r對t是可見的(判斷方法放在後面講),將該行的delete_version置為t的id,並將改行放入undo log中,而在表中會插入一條新的行r』,r』的db_trx_id為t的id,delete_version為空,db_roll_ptr指向剛剛被打入undo log的那行

修改前↓

修改後↓

read view

其實readview可以理解成資料庫中某個時間戳所有未提交事務的快照,readview類有這麼幾個引數:

m_ids:當前時間戳所有未提交的事務

min_trx_id:m_idx中最小的事務id

creator_trx_id:當前事務id

當建立乙個readview物件時,也就知道了這個時間點上未提交事務的所有資訊,從而能夠通過這些資訊實現鎖的作用甚至增強。

有了這個readview,這樣在訪問某條記錄時,只需要按照下邊的步驟判斷記錄的某個版本是否可見:

如果被訪問版本的trx_id屬性值與readview中的creator_trx_id值相同,意味著當前事務在訪問它自己修改過的記錄,所以該版本可以被當前事務訪問。

如果被訪問版本的trx_id屬性值小於readview中的min_trx_id值,表明生成該版本的事務在當前事務生成readview前已經提交,所以該版本可以被當前事務訪問。

如果被訪問版本的trx_id屬性值大於或等於readview中的max_trx_id值,表明生成該版本的事務在當前事務生成readview後才開啟,所以該版本不可以被當前事務訪問。

如果被訪問版本的trx_id屬性值在readview的min_trx_id和max_trx_id之間,那就需要判斷一下trx_id屬性值是不是在m_ids列表中,如果在,說明建立readview時生成該版本的事務還是活躍的,該版本不可以被訪問;如果不在,說明建立readview時生成該版本的事務已經被提交,該版本可以被訪問。

正題

首先會建立乙個readview物件r:

r.m_ids=[t2,t3,t5],

r.min_trx_id=2,

r.max_trx_id=7

由於該行db_trx_id=2, 而2!

如果該行是這樣子的:

由於1又如果是:

那就最後的改動就是在t6中進行的,也是對t6可見。

亦或是

cpu排程嘛,人家雖然後來的但也可能先你下手了 。因此由於8>=r.max_trx_id=7,所以該行對t6不可見,找一下db_roll_ptr指向的行,由於是空,返回0行。(如果不為空,那麼對所指向的行對同樣的可見性判斷)

再者:

雖然r.min_trx.id<=4

copy的,tmin,tmax,tid0分別對應r.min_trx.id,r.max_trx_id,db_trx_id。

回到開頭

有些部落格寫的是

如果以小於或等於當前事務版本號為依據來判斷行的可見性,那麼就會漏掉依然活躍未提交的事務,在rr隔離級別下會產生不可重複度(離譜)。

rr和rc的區別

read committed —— 每次讀取資料前都生成乙個readview

repeatable read —— 在第一次讀取資料時生成乙個readview

featrue plus

其實在這樣的mvvc下,innodb在rr隔離級別下就能避免了幻讀,原因是不管是後面新的事務還是已經存在的未提交事務,他們新增的資料行對當前事務都是不可見的,而已提交的事務又不可能新增行,妙啊

mvcc readview介紹

mysq比較時間

在oracle中使用時間函式to date習慣了,在oracle中時間的加減也非常簡單,直接加減即可。在mysql中時間的函式很多,非常自由。在專案中經常用到的就是時間的加減。比如60天前,oracle中直接就是sysdate 60,mysql中就不行。對時間加減的函式是 加adddate 減sub...

mysq基礎優化

skip name resolve skip locking skip innodb skip bdb key buffer 1g記憶體推薦設定為256m,2g記憶體推薦設定為512m wait timeout 3或者5 2g記憶體推薦設定為5 max connections 如果訪問量很大可以設定...

mysq索引類別

索引都是在儲存引擎層面實現的 1.btree索引 使用b tree資料結構建立的索引,索引值都是按順序存放的,儲存引擎不需要再全表掃瞄,取而代之的是從索引的根節點開始掃瞄,根節點存放了子節點的指標,隨著向下層查詢,隨著查詢值和節點值的比較 指標中右節點葉值的上下限 最終找到記錄。btree索引可以選...