MySQL 8.0:InnoDB中大對象的MVCC
在本文中,我將解釋MySQL InnoDB存儲引擎中大對象(LOB)設計的多版本并發控制(MVCC) 。 MySQL 8.0有一個新功能,允許用戶部分更新大型對象,包括JSON文檔 。 使用此部分更新功能,當LOB部分更新時,MVCC對LOB的工作方式已發生變化。 對于正常更新(完整更新),MVCC將像以前的版本一樣工作。 讓我們看一下MVCC在不涉及部分更新時的工作原理,然后考慮對LOB進行部分更新的用例。
MVCC 常規更新
我使用術語常規更新來指代不是部分更新的更新。 我將通過一個例子解釋MVCC如何用于常規更新大對象。 我將為此目的使用以下mtr(1)測試用例:
| create table t1 ( f1 int primary key , f2 longblob ) engine = innodb ; insert into t1 values ( 1 , repeat ( 'a' , 65536 ) ) ; start transaction ; update t1 set f2 = repeat ( 'b' , 65536 ) where f1 = 1 ; -- echo # Connection con1: -- 對于使用MySQL客戶端的用戶,可能需要通過另開一個終端窗口建立新鏈接, 下同。 connect ( con1 , localhost , root , , ) ; -- echo # Must see the old value 'aaaaaaaaaa' select f1 , right ( f2 , 10 ) from t1 order by f1 ; -- echo # Connection default: connection default ; disconnect con1 ; commit ; drop table t1 ; |
為了理解下面的解釋,仔細理解上述測試用例非常重要。
測試場景如下:
最初,表t1包含單個記錄(R1)。
事務trx1將記錄更新為新值。
當trx1仍處于活動狀態時,另一個事務trx2正在讀取記錄。 它將讀取舊值。
表t1僅包含一個記錄(R1)。 但是trx1和trx2會看到兩個不同的值。 該表實際上只包含最新值(trx1所見的值),而trx2看到的值或記錄是從撤消日志記錄中獲得的。 讓我們看下面的圖片來更好地理解它。
初始狀態:更新操作之前
下圖顯示了更新操作之前的情況。 撤消日志為空。 表的聚簇索引包含一行。 表中有一個LOB。 聚簇索引記錄包含對LOB的引用。

最終狀態:更新操作后
現在讓我們看一下更新操作后的情況。

以下是一些重要的觀察:
用戶表空間中有兩個LOB - 舊的LOB和新的LOB。 舊的LOB只能通過撤消日志訪問。 聚集索引記錄指向新LOB。
更新操作已創建包含更新向量的撤消日志記錄。 此撤消日志記錄指向舊LOB。
聚簇索引記錄通過DB_ROLL_PTR系統列指向撤消日志記錄。 此滾動指針指向撤消日志記錄,該記錄可用于構建聚簇索引記錄的先前版本。
新聞熱點
疑難解答