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的引用。