首页 > 编程知识 正文

经典MVC模式,mvcc多版本并发控制

时间:2023-05-06 16:10:49 阅读:166606 作者:2200

根据《高性能mysql》的书籍,mvcc的实现应该大致如下。

1、每行数据后面有两个隐藏字段。 一个字段为更新标识,一个字段为删除标识,记录内容为更新/删除时的系统版本号。

2、在选择过程中,根据当前事务版本号过滤以下数据:

3、update操作实际上不是增加一行记录,修改为原始数据。

4、delete也不是物理删除,而是在删除识别字段中附加版本号。

看起来很好,但innodb的mvcc实现却不是这样!

在innodb中,两个隐藏字段分别为DATA_TRX_ID和DATA_ROLL_PTR。 如果没有主键,还会添加一个隐藏的主键列。

DATA_TRX_ID

用6个字节记录最近更新此行记录的事务ID

DATA_ROLL_PTR

表示指向该行中“回退段”(rollback segment )的指针。 大小为7个字节,InnoDB从该指针中查找以前版本的数据。 该行记录中的所有旧版本都在还原中以链表的形式组织。 在网上搜索后发现,大致以以下形式记录了每个版本修改后的数据,不是操作的逆操作。

因此,每次实际执行update操作时,都不会创建新副本。 而是将的数据行copy放入还原日志中,然后更改数据行,从而更改DATA_TRX_ID和DATA_ROLL_ID。

既然我们已经讨论了支持mvcc功能的列结构,我们来看看mysql的四个事务隔离级别与mvcc之间的关系。

1 .脏读

无论mvcc如何,每次选择最新的数据时,如果另一个事务的数据已被物理写入或修改,它都会去读取并忽略下一个DATA_TRX_ID。

2 .提交阅读

在mvcc的使用中,innodb引入了ReadView这一方式。 生成ReadView时,所有当前活动事务(所有未提交的事务)的版本号都将收集到一个队列中的m_ids中,当前系统版本号1也将添加到队列中。 可以找到版本号的最小值up_limit_id和最大值low_limit_id。 在选择过程中,对于单个数据,与m_ids进行比较将产生以下结果:

如果小于up_limit_id,则表示事务是有效数据,因为在ReadView打开之前已提交该事务。

如果大于low_limit_id,则表示该事件是在ReadView打开后提交的,并且是无效数据。 在这种情况下,它将沿着还原日志链表向上移动,直到找到有效的内容

对于up_limit_id

当在PS.undolog中进行搜索时,只有data_trx_id小于up_limit_id才有效,并且可以满足条件c。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。