MySql–MVCC[通俗易懂]

MySql–MVCC[通俗易懂]一、MVCC是什么? Multi-Vesrion Concurrency Control多版本并发控制,MVCC是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问。 你可以把MVC…

	MySql--MVCC[数据库教程]

一、MVCC是什么?

 

Multi-Vesrion Concurrency Control多版本并发控制,MVCC是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问。

你可以把MVCC看作一种行级别锁的妥协,在很多情况下避免了锁的使用,同时可以提供更小的开销。根据不同的实现,可以允许非阻塞式读,在写操作时只锁定必要的记录

 MVCC只在REPEATABLE READREAD COMMITTED两个隔离级别下工作。其他两个隔离级别都和MVCC不兼容,因为READ UNCOMMITTED总是读取最新的数据行,而不是符合当前事务版本的数据行,而SERIALIZABLE会对所有读取到的行都加锁。

 

优势:

使用MVCC多版本并发控制比锁定模型的主要优点是在MVCC里,对检索(读)数据的锁要求与写数据的锁要求不冲突,所以读不会阻塞写写也不会阻塞读

恰当的使用MVCC会提供比锁更好的性能。

 

二、MVCC的底层原理

 

InnDB内部结构

 为了实现MVCC机制,InnDB内部为每一行添加了两个隐藏列:DB_TRX_IDDB_ROLL_PTR(MySQL另外还有一个隐藏DB_ROW_ID,这是在InnoDB表没有主键的时候会用来作为主键)。

 DB_TRX_ID:长度为6字节,存储了插入或更新语句的最后一个事务的事务ID。

 DB_ROLL_PTR:长度为7字节,称之为:回滚指针。回滚指针指向写入回滚段的undo log记录,读取记录的时候会根据指针去读取undo log中的记录。(正因为MySQL中undo log中会维护一个历史数据记录,所以我们应该养成定期提交事务的习惯,否则回滚段会越来越   大,甚至占满了表空间。)

 read-view: 当执行查询sql时会生成一致性试图read-view,它由执行查询时所有未提交事务id数组([DB_TRX_ID,DB_TRX_ID]已创建的最大事务id组成(数组里最小id:min_id,最大id:max_id),查询的数据结果需要跟read-view做比对从而得到快照结果。

 

快照读

 快照读是针对上下文的当前读而言,指的是在RR隔离级别下,在不加锁的情况下MySql会根据回滚指针选择从undo log记录中获取快照数据,而不总是获取新的数据,这也就是为什么另一个事务提交了数据,在当前事务中看到的依然是另一个事务提交之前的数据。

 

版本链比较规则(重点):

1.如果落在绿色部分(trx_id<min_id),表示这个版本是已提交的事务生成的,这个数据是可见的。

2.如果落在红色部分(trx_id>max_id),表示这个版本是由将来启动的事务生成的,是肯定不可见的。

3.如果落在黄色部分(min_id<=trx_id<=max_id),那就包括两种情况

   a.若row在trx_id在数组中,表示这个版本是由还没提交的事务生成的,不可见,当前自己的事务是可见的

   b.若row的trx_id不在数组中,表示这个版本是已经提交的事务生成的,可见。

技术图片

 

下面逐步分析一下(RR隔离级别下

 

第一步:

有表:table1、table2。table2表中有字段:id、name、db_trx_id、db_roll_ptr(重点看table2)

事务100对table1进行了update(未提交)、事务200对table1进行了update(未提交)、事务300对table2进行了update操作(已提交)

技术图片

 

 

 

update前:版本链中有一条id=1、name=UZI、db_trx_id=60的数据

update中:先将版本链上最新的数据复制一份,然后将trx_id修改成update的trx_id,将db_roll_ptr指向原始数据。

update后:版本链中有两条数据,新数据用指针指向旧数据

技术图片

 

 

 注意:这时readview为[100,200],300,因为事务100未提交、事务200未提交,当前最大db_trx_id=300。

 当在select1中进行select时,trx_id在readview([100,200],300)的黄色区域,且不再数组中,所以name的结果为JackLove。(符合比较规则)

 

第二步:

技术图片

 

 

 事务100又对table2先后进行了两次update操作,在commit前,select1进行了一次select。

 这时版本链内的数据如下:

技术图片

 注意:这时readview也是[100,200],300,因为在一个事务中readview是不可变的,从第一次执行sql开始。

 当在select1中进行select时(trx_id=100),先判断第一条数据,发现在黄色区域且在数组内,则不符合。

 向下找第二条数据,发现也在黄色区域且在数组内,则不符合。

  向下找第三条数据,发现也在黄色区域且不在数组内,符合,所以还是返回name=”JackLove”。

 

第三步:

技术图片

 

 事务200分别进行了两次update,在commit前,select1和select2分别进行了一次select;

 这时版本链中的数据如下:

 技术图片

 

 

 

 这时select1(readview:[100,200],300)查询结果是:name=”JackLove”,

 select2进行select时,事务200未提交,最大max_id=300,所以readview=[200],300,trx_id=200,

 进行逐次比较,结果name=”Rookie”

 

对于删除操作:

 对于删除的情况可以认为是update的特殊情况,会将版本链上最新的数据复制一份,然后将trx_id修改成删除操作的trx_id,同时在该条记录的头信息(record header)里的(deleted flag)标记未写上true,来表示当前记录已经被删除,在查询时按照上面的规则查到对应的   记录,如果delete_flag标记为true,意味着记录已被删除,则不返回数据。

 

总结:

MVCC解决了什么问题?

  就是解决了Repeatable Read和Read Committed两个隔离级别下读同一行和写同一行的两个事务的并发。

 

MySql–MVCC

原文地址:https://www.cnblogs.com/BounceGuo/p/13441073.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/6860.html

(0)
上一篇 2023-04-01 09:00
下一篇 2023-04-01

相关推荐

  • 5分钟搞定ORACLE到ClickHouse数据迁移同步-CloudCanal实战[亲测有效]

    5分钟搞定ORACLE到ClickHouse数据迁移同步-CloudCanal实战[亲测有效]简述 ClickHouse 是一种流行的列式数据库,对于计算 uv、mv、pv 等聚合类数据相当友好,所以广泛使用于各类报表场景。 本文主要介绍如何使用 CloudCanal 快速构建一条稳定高效运行

    2023-06-03
    145
  • 使用Python实现整数保留运算

    使用Python实现整数保留运算在数学运算中,我们通常会遇到保留整数的情况。而在使用Python进行编程时,保留整数也很常见。Python的内置保留整数函数round()不仅可以对小数进行四舍五入,还可以对整数进行保留。

    2024-06-04
    50
  • CentOS8安装redis[通俗易懂]

    CentOS8安装redis[通俗易懂]一、工具说明 操作系统:CentOS8 Redis: 3.2.8 二、安装redis 下载redis [root@localhost ~]$ wget http://download.redis.i…

    2023-02-16
    158
  • 解析分页思想+分页实战「终于解决」

    解析分页思想+分页实战「终于解决」一、排除Top分页法(自命名,非规范) 思想:所谓“排除Top分页”,主要依靠“排除”和Top这个两大核心步骤。首先查询当前页码之前的数据,然后将该数据从总数据中排除掉,在从剩下的数据中获取前N条记录

    2023-03-22
    160
  • mysql slave 跳过_mysql多主多从

    mysql slave 跳过_mysql多主多从mysql正确关闭slave取消主从 转载 guoshaoliang789 最后发布于2019-01-10 10:31:39 阅读数 2912 收藏 展开 正确关闭slave步骤 执行STOP SL…

    2023-01-25
    153
  • Python按钮组件实现

    Python按钮组件实现按钮组件是GUI界面中最基础的组件之一,一般用于触发某些事件或者操作。Python作为一种高级编程语言,在界面开发上自然也不会落后。在Python中,有很多的GUI库可以供我们使用,如Tkinter、PyQt、wxPython等。下面我们主要介绍如何使用Tkinter来实现Python按钮组件。

    2024-01-13
    105
  • Python数据爬虫实战

    Python数据爬虫实战在当今社交网络和互联网极度发达的时代,无论是企业还是个人都需要从海量数据中获取关键信息来指导决策。但是获取这些关键信息的过程通常需要大量的人力和时间成本,因此数据爬虫技术在这个时代显得尤为重要。Python作为一种流行的程序语言具有着领先的数据爬取与处理功能,在企业和个人应用中得到了很广泛的应用。

    2024-07-23
    33
  • sql,group by_sql什么时候用having

    sql,group by_sql什么时候用having前言 group by的可以帮助我们在特定场景下查询到我们需要的数据,但group by的用法一直给人一种“飘忽”感,究其原因,还是对于该关键字缺乏深入理解。 下面通过一个例子,来简单解释group…

    2023-02-25
    146

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注