加入收藏 | 设为首页 | 会员中心 | 我要投稿 东莞站长网 (https://www.0769zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长资讯 > 外闻 > 正文

InnoDB秒级快照原理

发布时间:2021-04-18 13:36:26 所属栏目:外闻 来源:互联网
导读:到的结果是事务A查询的结果为1,事务B查询的结果是2,但是为什么事务B查询后为3呢?? 需要注意的是,在 MySQL 里,有两个视图的概念: 1、一个是view,它是一个用查询语句定义的虚拟表,在调用的时候执行查询语句并生成结果。创建视图的语法是 create view ,

到的结果是事务A查询的结果为1,事务B查询的结果是2,但是为什么事务B查询后为3呢??

需要注意的是,在 MySQL 里,有两个视图的概念:

1、一个是view,它是一个用查询语句定义的虚拟表,在调用的时候执行查询语句并生成结果。创建视图的语法是 create view … ,而它的查询方法与表一样。

2、另一个是 InnoDB 在实现 MVCC(Multi-Version Concurrency Control,多版本并发控制)时用到的一致性读视图,即 consistent read view,用于支持 RC(Read Committed,读提交)和 RR(Repeatable Read,可重复读)隔离级别的实现。

InnoDB创建秒级快照原理

本文的首图即是MVCC的实现原理,在可重复读隔离级别下,事务在启动的时候就”拍了个快照”。注意,这个快照是基于整库的。如果一个库有 100G,那么我启动一个事务,MySQL就要拷贝 100G 的数据出来,这个过程得多慢啊。可是平时的事务执行起来很快啊,实际上,我们并不需要拷贝出这 100G 的数据。我们先来看看这个快照是怎么实现的:

InnoDB 里面每个事务有一个唯一的事务 ID,叫作 transaction id。它是在事务开始的时候向 InnoDB 的事务系统申请的,是按申请顺序严格递增的。而每行数据也都是有多个版本的。每次事务更新数据的时候,都会生成一个新的数据版本,并且把 transaction id 赋值给这个数据版本的事务 ID,记为 row trx_id。同时,旧的数据版本要保留,并且在新的数据版本中,能够有信息可以直接拿到它。也就是说,数据表中的一行记录,其实可能有多个版本 (即row中的每个数据),每个版本有自己的 row trx_id。

如所示,就是一个记录被多个事务连续更新后的状态个虚线箭头,就是 undo log(回滚日志);而 V1、V2、V3 并不是物理上真实存在的,而是每次需要的时候根据当前版本和 undo log 计算出来的。比如,需要 V2 的时候,就是通过 V4 依次执行 U3、U2 算出来。

按照可重复读的定义,一个事务启动的时候,能够看到所有已经提交的事务结果。但是之后,这个事务执行期间,其他事务的更新对它不可见。

因此,一个事务只需要在启动的时候声明说,“以我启动的时刻为准,如果一个数据版本是在我启动之前生成的,就认;如果是我启动以后才生成的,我就不认,我必须要找到它的上一个版本”。如果是这个事务自己更新的数据,它自己还是要认的。

在实现上, InnoDB 为每个事务构造了一个数组,用来保存这个事务启动瞬间,当前正处于启动了但还没提交的所有事务ID。数组里面事务 ID 的最小值记为低水位,当前系统里面已经创建过的事务 ID 的最大值加1记为高水位。这个视图数组和高水位,就组成了当前事务的一致性视图(read-view)而数据版本的可见性规则,就是基于数据的 row tr

(编辑:东莞站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读