MySQL中RR級別下的MVCC

2021-10-04 18:08:53 字數 1799 閱讀 3412

眾所周知mysql中innodb的可重複讀是通過mvcc實現的。

mvcc是由哪些元素構成?

mvcc的讀 又叫快照讀,在mysql中不可能把整個表的資料拷貝乙份來提供這個快照。它通過

1、undolog

innodb增刪資料時除了redo log外還會記錄undo log。

以update舉例: undolog->修改記憶體中資料頁->redolog prepare->binlog-> commit; 修改資料時 undo log記錄原始資料。用於以後或許會發生的回滾操作。

2、表中的的隱藏列 data_trx_id,data_roll_pt

一張表中有三個隱藏列

rows_id: mysql給予行的乙個標識。如果表中沒有主鍵,那麼就會使用row_id來組織資料。

data_trx_id: 事務id,建立乙個新的事務,會分配乙個自增的全域性唯一的data_trx_id。

需要說明的是:begin/start transaction 命令並不是乙個事務的起點,在執行到它們之後的第乙個操作 innodb 表的語句,事務才真正啟動。

data_roll_pt: 回滾指標,這個指標指向undo log中的一行記錄原始記錄。

3、read view陣列

建立事務時,innodb為事務建立了乙個read view的陣列用來記錄建立事務時刻的當前活躍事務data_trx_id。

低水位:建立當前事務時刻活躍事務中最小的data_trx_id。很多人認為是已提交事務的最大data_trx_id,這樣理解之後存在乙個問題。

比如 現在已提交事務有 1 3 ,2為活躍事務。按已提交事務的最大id來理解,低水位應該為3。與mysql判斷 小於低水位為已提交事務,就出現了矛盾。 

高水位:建立當前事務時刻未分配的最小data_trx_id。

以上三部分來實現。

mvcc怎麼工作的?

當讀取到一行資料

0、是否是當前事務修改,是當前事務修改,當前事務可見。

1、這行資料data_trx_id與低水位比較,小於低水位,則事務已提交,當前事務可見。否則判斷是否大於高水位。

2、這行資料data_trx_id與高水位比較,大於高水位,則是在當前事務建立之後的事務,當前事務不可見。

3、這行資料data_trx_id與高水位比較,小於高水位,則判斷read view中是否包含此data_trx_id。如果包含則表示

當前事務建立時,data_trx_id為活躍事務,當前事務不可見。

4、read view中不含此data_trx_id則表示當前事務建立時,data_trx_id為已提交事務,當前事務可見。

舉個栗子:現在已提交事務有 1 3 ,2為活躍事務,當前事務data_trx_id為4。低水位為2,高水位5。

此時read view中為 2 4。當讀到data_trx_id為3的行時,

1、3<2?

2、3>5?

3、read view包含3?

最後得出3對4可見。

跟undolog有什麼關係?

沿用上面的例子, 新起乙個事務update對原來為data_trx_id為3的已提交事務進行操作。記錄undolog,將data_trx_id由3改為5,並且data_roll_pt指向undolog中為data_trx_id為3的記錄。

當data_trx_id為4的事務,讀取到data_trx_id為5的行時,data_trx_id不滿足條件則通過data_roll_pt查詢undolog中是否有滿足條件的行,可以查詢到data_trx_id為3的行。

InnoDB在MySQL預設隔離級別下解決幻讀

在rr的隔離級別下,innodb使用mvvc和next key locks解決幻讀,mvvc解決的是普通讀 快照讀 的幻讀,next key locks解決的是當前讀情況下的幻讀。事務a,先執行 update table set name hh where id 3 結果為 ok row xx 表名...

mysql中rc級別下表上無索引主鍵的鎖測試

session 1 mysql begin query ok,0 rows affected 0.00 sec mysql delete from test where table name columns query ok,256 rows affected 0.07 sec session 2 ...

針對mysql的RR級別的幻讀問題的分析與理解

由於最近被這個幻讀的問題給困擾,所以想整明白點,主要就是幻讀和不可重複讀的區別以及幻讀的實際使用場景。翻了一些文章,眾說紛紜,我大概抽了幾篇我覺得不錯的文章來說。不可重複讀主要還是說的update和delete,他針對的是同一次查詢的資料,而幻讀則針對的是insert t1第一次查沒有這條記錄然後準...