首页 > 解决方案 > 当主键更改时,mvcc 如何工作?

问题描述

在 MVCC 文档中,它说当“选择查询”找到记录时,它会将 transactionId 与自己的 id 进行比较,以判断是否可以看到数据以及是否应该从重做日志中重建历史记录。我的问题是如果找不到原始记录怎么办,如何保持一致的阅读?

考虑以下示例:

create table tb_a (id bigtint not null primary key auto_increment, name varchar(100) not null default "");
 // isolation level is RR

// transaction 1
select * from tb_a where id = 1;  // it returns (1, "a")

// transaction 2
// another trx update the first line with its primary key
update tb_a set id = 3 where id = 1;
commit;

// transaction 1
select * from tb_a where id = 1; // still gets (1, "a")

过滤器 id = 1 的主键找不到该行,因为历史记录在重做日志中,并且 innodb 中的更新发生在原地。那么innodb是如何对待这种事情的,并且仍然保持一致性呢?

标签: innodb

解决方案


更改 PK 列可能是旧记录的“删除”和新行的“插入”。我认为这意味着有些东西留在了表中,但被标记为已删除(直到两个事务提交后的清理)。

类似的UNIQUE关键变化。其他事务需要能够看到已删除的行以检查 dup 键。

每行的每个版本(旧/新)都有一个事务 ID。所以...

可重复阅读:

当一个事务开始时,它被分配一个“事务ID”。这是一个单调递增的序列号,用于标识可能被修改的行。对于事务隔离 = RR,查询只能“看到”具有该 trx id(或更早)的行。这解释了为什么你的决赛SELECT看到它做了什么。而且,请注意,该查询实际上(据我所知)是重新执行的。

您的其他 txn 具有更高的 trx id。它创建了该行的“更新”副本。因此,该行至少有两个副本漂浮在周围。隔离模式加上 trx id 控制每个事务可以“看到”哪一行。


推荐阅读