首页 > 编程知识 正文

mvcc,elasticsearch原理图

时间:2023-05-03 05:08:42 阅读:166622 作者:2647

1、什么是MVCC

mvcc多版本同时控制。

在mysql innodb中,mvcc主要以更好的方式处理读/写冲突,以便在存在读/写冲突的情况下,可以在没有电缆或块的情况下同时进行读取,从而提高数据库的并发性。

2、实现原理:

通过保存某个时间点的数据快照,实现mvcc。 这意味着,无论运行多长时间,所有东西看到的数据都是一致的。

3、mvcc会解决那些问题吗?

同时执行事务可能会导致以下问题:

脏读:读取其他事务未提交的数据。 不可重新读取:当一个事务读取数据时,另一个事务修改该数据并将其提交给事务,导致重新读取时出现数据不匹配。 一个事务读取某个范围内的数据,另一个事务添加该范围内的数据,然后重新读取时发生了两次结果不匹配。 mvcc可以解决脏读、不可重复读,使用快照读解决了部分幻读问题,但由于修改时使用的是当前读,存在幻读问题,幻读问题最终通过间隙锁解决

4、当前导线和快照导线

当前读取:当前读取操作包括共享锁、独占锁和对DML操作的独占锁。 当前读取的数据都是最新的,在读取数据时将其锁定,以防止其他人修改当前记录。

快照读取—快照读取中的数据可能不是最新的,而是早期版本的数据。

如何区分当前读取和快照读取

所有未锁定的简单选择都是快照读取; 与此相对应的是现在的读法,在select上加上共享锁,再加上排他锁。

5、mvcc底层实现要素

在此之前,您必须知道MVCC仅适用于两个隔离级别:可重复读(REPEATABLE READ )和读命令。

mvcc的实现原理是通过隐藏字段(创建时的版本号、回滚指针、删除版本号)、还原日志和读视图来实现的。

5.1、隐藏字段

在Innodb存储引擎中,如果存在聚簇索引,则每行记录将隐藏两个字段;如果没有聚簇索引,则具有6byte的隐藏主键。

创建版本号:创建记录事务ID

删除版本号:删除/更改记录的事务ID。 这里只需将字段标记为删除状态。

回滚指针:指向记录的上一个版本

5.2、还原日志

undo log是为了实现原子性而实现回滚操作,另一个作用是实现MVCC的多版本控制。

还原日志细分为两种:插入时发生的还原日志、更新和删除时发生的还原日志

Innodb中insert生成的还原日志将在提交事务后删除。 新插入的数据没有历史版本,因此不需要维护还原日志。

update和delete操作生成的undo log都是类型,在事务回滚时需要,在快照读取时也需要,并且需要维护多个版本信息。 只有在快照读取和事务回滚不涉及日志的情况下,purge线程才会批量删除相应的日志。

purge线程清理还原日志的历史版本,还清理del flag标记的记录。

还原日志在mvcc中的作用是还原日志保存版本链。 也就是说,上述回滚指针字段已连接。

当数据库执行select语句时,它会尝试一致地读视图。

read view是查询时未提交的所有事务ID的数组,该数组中的最小事务ID由min_ID组成,创建的最大事务ID由max_id组成。 必须将查询的数据结果与read-view进行比较以获得快照结果。

因此,还原日志在mvcc中的作用是根据保存的事务ID和一致性视图进行比较,以获得快照结果。

5.3、读视图

执行SQL语句查询将生成一致性视图或读视图。 read-view由执行查询时尚未提交的所有事务ID数组和已创建的最大事务ID组成。

将该数组中最小的事务ID称为min_ID,最大的事务ID称为max_id,将查询的数据结果与读视图进行比较以获得快照结果。

因此,产生了使用当前记录的trx_id与read-view进行比较的比较规则。 比较规则如下。

5.3.1、版本链比较规则

如果落入trx_idmin_id,则此版本由已提交的事务生成,并且由于事务已提交,因此将显示数据

如果跌落到trx_idmax_id,则意味着此版本将由将来开始的事务生成,并且不显示

如果min_id=trx_id=max_id

如果row的trx_id位于数组中,则表示此版本由尚未提交的事务生成,并且是不可见的。 但是,如果当前自己的事务可见,row的trx_id不在数组中,则表示它是已提交的事务生成的版本。 在这里,您可以看到,对于删除的数据,在以前的还原日志中介绍时,也有update和delelect这样的特殊情况。

删除数据会复制版本链上的最新数据

份,然后将trx_id修改为删除时的trx_id,同时在该记录的头信息中存在一个delete flag标记,将这个标记写上true,用来表示当前记录已经删除。

在查询时按照版本链的规则查询到对应的记录,如果delete flag标记位为true,意味着数据已经被删除,则不返回数据。

小结

在同一个事务中进行查询,会沿用第一次查询语句生成的read-view(前提是隔离级别是在可重复读)

通过以上的四个案例,在版本链寻找过程中,可以总结出一个小技巧

技巧图

根据这个小技巧你可以很快的得知此版本是否可见。

如果当前的事务ID在绿色部分,是已经提交事务,则数据可见如果当前的事务ID在蓝色部分,会有俩种情况,如果当前事务ID在read-view数组内,是没有提交的事务不可见,如果不在数组内数据可见如果落在红色部分,则不考虑,对于未来的事情不去想即可。

总结

本文内容从浅到深,从什么是mvcc到mvcc的底层实现,一步一步地陈述了mvcc的实现原理。

本文简单总结

mvcc在不加锁的情况下解决了脏读、不可重复读和快照读下的幻读问题,一定不要认为幻读完全是mvcc解决的对当前读、快照读理解,简单点说加锁就是当前读,不加锁的就是快照读。mvcc实现的三大要素俩个隐式字段、回滚日志、read-view俩个隐式字段:DB_TRX_ID:记录创建这条记录最后一次修改该记录的事务ID,DB_ROLL_PTR:回滚指针,指向这条记录的上一个版本undo log在更新数据时会产生版本链,是read-view获取数据的前提read-view当SQL执行查询语句时产生的,是由为提交的事务ID组成的数组和创建的最大事务ID组成的版本链规则看第五节的小结即可

 

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