Mysql隔离性之Read View的用法说明

 更新时间:2021年03月25日 11:42:05   作者:Drogon Brother  
这篇文章主要介绍了Mysql隔离性之Read View的用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

当前事务能读取到哪个历史版本?

Read View是事务开启时,当前所有事务的一个集合,这个数据结构中存储了当前Read View中最大的ID及最小的ID。

这就是当前活跃事务列表,如下所示:

ct-trx --> trx11 --> trx9 --> trx6 --> trx5 --> trx3;

ct-trx 表示当前事务的id,对应上面的read_view数据结构如下,

read_view->creator_trx_id = ct-trx;
read_view->up_limit_id = trx3; 低水位
read_view->low_limit_id = trx11; 高水位
read_view->trx_ids = [trx11, trx9, trx6, trx5, trx3];

low_limit_id是“高水位”,即当时活跃事务的最大id,如果读到row的db_trx_id>=low_limit_id,说明这些id在此之前的数据都没有提交,如注释中的描述,这些数据都不可见。

if (trx_id >= view->low_limit_id) {
return(FALSE);
}

注:readview 部分源码

up_limit_id是“低水位”,即当时活跃事务列表的最小事务id,如果row的db_trx_id<up_limit_id,说明这些数据在事务创建id的时都已经提交,如注释中的描述,这些数据均可见。

if (trx_id < view->up_limit_id) {
return(TRUE);
}

row的db_trx_id在low_limit_id和up_limit_id之间,则查找该记录的db_trx_id是否在自己事务的read_view->trx_ids列表中,如果在则该记录的当前版本不可见,否则该记录的当前版本可见。

不同隔离级别ReadView实现方式

1. read-commited:

即:在每次语句执行的过程中,都关闭read_view, 重新在row_search_for_mysql函数中创建当前的一份read_view。这样就会产生不可重复读现象发生。

2. repeatable read:

在repeatable read的隔离级别下,创建事务trx结构的时候,就生成了当前的global read view。使用trx_assign_read_view函数创建,一直维持到事务结束。在事务结束这段时间内 每一次查询都不会重新重建Read View , 从而实现了可重复读。

补充:mysql的mvcc和readview

隔离级别标准定义:

read uncommited 一个事务读取到了另一个事务未提交的结果(可能发生回滚),叫脏读,这会带来脏读、幻读、不可重复读问题

read commited 一个事务a读取到了另一个事务b最新提交的结果,使得事务a两次读取的结果不同,其避免了脏读,会出现不可重复读,幻读,通过版本链(mvcc)和readview实现。

repeatable read(mysql的默认隔离级别) 一个事务第一次读过某条记录后,另一个事务修改提交了该条记录后,事务a读取到的还是第一次的值,这就是可重复读,同一个事务中多次读取相同的数据返回的结果是一样的。事务不会读到其他事务对已有数据的修改,即使其他事务已提交,也就是说,事务开始时读到的已有数据是什么,在事务提交前的任意时刻,这些数据的值都是一样的。但是,对于其他事务新插入的数据是可以读到的,这也就引发了幻读问题。其避免了脏读和不可重复读问题,但幻读依然存在。还是会出现幻读,(但是mysql解决了幻读的问题),通过版本链和readview实现

serializable 不允许对同一行记录的读和写的并发操作,必需串行执行,所以不会出现幻读,脏读现象

在mysql中读已提交和可重复读事务隔离级别是通过mvcc和readview实现的

mvcc即Multi-Version Concurrency Control,多版本并发控制,维护一个数据的多个版本,使得事务之间的读写按照隔离级别获取相应的结果,不发生冲突

对于隔离级别read committed,每次都生成一个新的readview

对于隔离级别repeatable read,只在事务开启时,生成一个readview,直到事务提交,不发生变化,所以可以保证可重复读。

生成readview时

m_ids:表示活跃事务id列表

min_trx_id:活跃事务中的最小事务id

max_trx_id:已创建的最大事务id

creator_trx_id:当前的事务id

对当前事务来说,按照以下规则从最新的版本开始遍历,获取对应的版本记录。

1、被访问的trx_id与readview中的creator_trx_id相同,表示当前事务在访问自己修改的记录,可见,返回;

2、被访问的trx_id小于min_trx_id,表明该版本已提交,可见,返回;

3、被访问的trx_id大于等于max_trx_id,表明该版本在生成readview时,还未开启,不可见,返回;

4、被访问的trx_id在min_trx_id和max_trx_id之间,判断是否在m_ids中,如果在,则说明生成readview时,该版本事务未提交,该版本不可见;如果不在,则说明生成readview时,该版本事务已提交可见,返回。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。如有错误或未考虑完全的地方,望不吝赐教。

相关文章

  • MySQL在哪些情况下不使用索引的示例

    MySQL在哪些情况下不使用索引的示例

    尽管索引可以显著提高数据库的查询性能,但在某些情况下,MySQL可能不会使用索引,本文就来介绍一下MySQL在哪些情况下不使用索引,具有一定的参考价值,感兴趣的可以了解一下
    2024-01-01
  • MySQL清理数据并释放磁盘空间的实现示例

    MySQL清理数据并释放磁盘空间的实现示例

    本文主要介绍了MySQL如何清理数据并释放磁盘空间,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • 详解Mysql基础语法的使用

    详解Mysql基础语法的使用

    MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品。这篇文章主要介绍了Mysql基础语法的使用,需要的朋友可以参考下
    2018-07-07
  • windows下mysql数据库主从配置教程

    windows下mysql数据库主从配置教程

    这篇文章主要为大家详细介绍了windows下mysql数据库主从配置教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-05-05
  • centos7利用yum安装mysql 8.0.12

    centos7利用yum安装mysql 8.0.12

    这篇文章主要为大家详细介绍了centos7利用yum安装mysql 8.0.12,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-08-08
  • SQL替换字符串值的5种常用方法

    SQL替换字符串值的5种常用方法

    这篇文章主要给大家介绍了关于SQL替换字符串值的5种常用方法,常用SQL的朋友应该知道,SQL中一般都会提供一些字符串处理函数,需要的朋友可以参考下
    2023-08-08
  • MySQL数据库之union,limit和子查询详解

    MySQL数据库之union,limit和子查询详解

    这篇文章主要为大家详细介绍一下MySQL数据库中union、limit和子查询的使用,文中的示例代码讲解详细,对我们学习MySQL有一定帮助,需要的可以参考一下
    2022-07-07
  • MySQL8设置自动创建时间和自动更新时间的实现方法

    MySQL8设置自动创建时间和自动更新时间的实现方法

    在实际应用中,我们时常会需要用到创建时间和更新时间这两个字段,下面这篇文章主要给大家介绍了关于MySQL8设置自动创建时间和自动更新时间的实现方法,需要的朋友可以参考下
    2023-03-03
  • MySQL表的增删改查之多表查询和联合查询功能

    MySQL表的增删改查之多表查询和联合查询功能

    这篇文章主要介绍了MySQL表的增删改查---多表查询和联合查询功能,这些约束条件在数据库中起着非常重要的作用,可以确保数据的完整性和一致性,本文给大家介绍的非常详细,需要的朋友可以参考下
    2024-04-04
  • 关于mysql left join 查询慢时间长的踩坑总结

    关于mysql left join 查询慢时间长的踩坑总结

    这篇文章主要介绍了关于mysql left join 查询慢时间长的踩坑总结,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09

最新评论