首页 > 数据库 >MySQL,MVCC详解,快照读在RC、RR下的区别

MySQL,MVCC详解,快照读在RC、RR下的区别

时间:2022-10-24 21:33:59浏览次数:64  
标签:快照 RR 事物 MVCC undo MySQL

MySQL,MVCC详解,快照读在RC、RR下的区别  

 

一、什么是MVCC

我们在操作数据库的时候总是这四大类 读读 读写 写读 写写,读读肯定是没有任务数据问题的,但对事物有了解的同学就会知道,读写、写写操作很容易就会导致数据不一致。

在此之前解决这类问题的常用方式就是加锁,听名字就知道这是个很复杂、很耗性能的操作,所以大神们不满足这个操作,从而在MySQL里面实现了MVCC。

MVCC并不是MySQL独有的,它是一个理念,百度百科解释如下

Multi-Version Concurrency Control 多版本并发控制,MVCC 是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问;在编程语言中实现事务内存。

MVCC里面有一些关键词,理解这些关键词,你就明白了什么是MVCC。MVCC是解决读写、写读导致数据不一致的问题,写写问题还是需要加锁来解决。

所以我们可以使用 MVCC + 锁(乐观锁/悲观锁)来解决全部的问题。


二、当前读、快照读

当前读就是读取最新的数据,为了保证读取的是最新且准确的数据,所以它在读取的时候会加锁,防止其它事物操作。

快照读是不加锁的方式,当一个事物要操作数据库的时候,会在这个事物的基础上形成一个快照,其它的操作就读取这个快照。

MVCC就是基于快照读来实现的,在MySQL里面的快照读是基于这样几个关键点来实现的

  • 三个隐藏参数 (DB_ROW_ID 隐藏主键id、DB_ROLL_PTR 回滚指针、DB_TRX_ID 事物id)
  • undo log 日志
  • read view

三、隐藏字段

假如我们有一张表,里面有两个字段,name、age,但实际上我们表里的数据是这样的

在这里插入图片描述

3-1、隐藏主键

6byte,隐含的自增ID(隐藏主键),如果数据表没有主键,InnoDB会自动以DB_ROW_ID产生一个聚簇索引

聚簇索引:数据存储和索引是存在一起的,逻辑上和物理上都是一起的,一个表只能有一个聚簇索引。

注:理解聚簇索引可以很好的理解MySQL的索引规则,感兴趣的可以看看这个 MySQL索引详解


3-2、事物id

记录这条记录最后一次操作的事物id


3-3、回滚指针

回滚指针,指向这条记录的上一个版本(存储于rollback segment里),用于配合下面的 undo log。


四、undo log

undo log 日志分为两种

  • insert undo log 数据库在插入数据的时候产生,只有在当前事物回滚的时候才有用,所以在当前事物结束的时候它就没用了,就会被删除。
  • update undo log 数据库在更新、删除的时候产生,除了当前事物会使用,在快照读的时候也会使用,所以不能随便删除,只有在快速读或事务回滚不涉及该日志时,对应的日志才会被purge线程统一清除

假设我们的隐藏主键是从1、2、3…, 事物主键、回滚指针也是这样生成的 (事实上不是这样的规则),那么我们对上面的表进行操作,将会形成如下的链式结构。

插入数据

image.png

修改张三为李四

image.png

修改年纪为25

image.png

注:这里的指针是指向这条数据,而不是里面的 主键。


五、Read View

什么是读视图呢?数据库的操作都是多个事物同时进行的,有读有写。假如当前有两个事物,A事物读取,B事物正在更新数据。

在A事物开始的时候,就形成当前数据库的一个快照,记录并维护系统当前活跃事务的ID。read view 主要是用来做可见性判断的,它会判断每条记录的的数据,这条数据可能是真实的数据,也可能是undo log 中的数据。

read view 用一个可见性的算法,来判断当前是读取真实的数据,还是undo log的数据。这里可以简单理解read view 内部维护了一个事物id列表,里面有最大值和最小值,可以判断其它事物的id是否在这个可见范围内。


N、其它

N-1、快照读在RC和RR下的区别

  • RC (read-committed)读已提交, 可能会导致 不可重复读、幻读
  • RR (repeatable-read)可重复读,可能会导致 不可重复读

幻读 : 事物A查询数据库查询出来了20条数据,然后事物B删除了2条数据,这时候事物A再去查询发现只有18条了,从而产生了幻觉。

我们知道在RR级别下面不会产生幻读,之所以不会产生幻读,是快照读在RC和RR下的生成的策略不一样。

RC隔离级别下,是每个快照读都会生成并获取最新的Read View;而在RR隔离级别下,则是同一个事务中的第一个快照读才会创建Read View, 之后的快照读获取的都是同一个Read View。


N-2、关于高性能的MySQL

在《高性能的MySQL》里面所讲解的MVCC和上面完全不一样,这也给我带来了很大的困扰。

后面在网上看到人家说《高性能的MySQL》里面讲的是PostgreSQL 里面MVCC实现方式。

 

转载:https://www.xdx97.com/article/904462077442129920

标签:快照,RR,事物,MVCC,undo,MySQL
From: https://www.cnblogs.com/wugh8726254/p/16823056.html

相关文章