MVCC

news/发布时间2024/5/16 14:40:57

你解释一下MVCC?

mvcc的意思是多版本并发控制。指维护一个数据的多个版本,使得读写操作没有冲突,

它的底层实现主要是依赖了数据库中的三个部分,隐藏字段,undo log日志和readView读视图

隐藏字段是指:在mysql中给每个表都设置了隐藏字段,有一个是最近修改事务的id,记录每一次操作的事务id,是自增的;另一个是回滚指针,指向上一个版本的事务版本记录地址;

undo log主要的作用是记录回滚日志,存储老版本数据,在内部会形成一个版本链,在多个事务并行操作某一行记录,记录不同事务修改数据的版本,通过回滚指针形成一个链表,链表头部就是最新修改的旧记录,尾部是最早修改的旧记录

readView读视图解决的是一个事务查询选择版本的问题,内部定义了一些匹配规则和当前的一些事务id判断该访问那个版本的数据,不同的隔离级别快照读是不一样的,最终的访问的结果不一样。RC隔离级别下,每一次执行快照读时生成ReadView,RR隔离级别仅在事务中第一次执行快照读时生成读视图,后续复用该读视图

MVCC

多版本并发控制。指维护一个数据的多个版本,使得读写操作没有冲突

多个事物并发的情况下到底该访问哪个版本

底层实现

  • 隐藏字段:

    • trx_id(事务id),记录每一次操作的事务id,是自增的
    • roll_pointer(回滚指针),指向上一个版本的事务版本记录地址
    • row_id,隐藏主键
  • undo log:

    • 回滚日志,存储老版本数据
    • 版本链:多个事务并行操作某一行记录,记录不同事务修改数据的版本,通过roll pointer指针形成一个链表
  • readView解决的是一个事务查询选择版本的问题

    • 根据readView的匹配规则和当前的一些事务id判断该访问那个版本的数据

    • 不同的隔离级别快照读是不一样的,最终的访问的结果不一样

      • RC:每一次执行快照读时生成ReadView
      • RR:仅在事务中第一次执行快照读时生成ReadView,后续复用

undo log

回滚日志,在insert、update、delete时产生的便于数据回滚的日志

insert产生的undo log只在回滚时需要,事物提交后可立即被删除

update、delete产生的日志不仅在回滚时需要,MVCC版本访问也需要,不会被立即删除

不同事物或相同事物对同一条记录进行修改,会导致该记录的undo log生成一条记录版本链,链表头部是最新的旧记录,链表尾部是最早的旧记录

ReadView

读视图,是快照读SQL执行时MVCC提取数据的依据,记录并维护系统当前活跃的事物未提交的id

其中

  • Read Committed:RC隔离级别下每次select都生成一个快照读
  • Repeatable Read:RR隔离级别下,开启事物后的第一个select才是快照读

ReadView包含四个核心字段:

字段 含义
m_ids 当前活跃的事务ID集合
min_trx_id 最小活跃事务ID
max_trx_id 预分配事务ID,当前最大事务ID+1(因为事务ID是自增的)
creator_trx_id ReadView创建者的事务ID

版本链数据访问规则

trx_id: 代表是当前事务ID。

  1. trx_id == creator_trx_id?---->可以访问该版本--------->说明数据是当前这个事务更改的。
  2. trx_id < min_trx_id?---->可以访问该版本--------->成立,说明数据已经提交了。
  3. trx_id >max_trx_id?---->不可以访问该版本--------->成立,说明该事务是在ReadView生成后才开启。
  4. min_trx_id <= trx_id <= max_trx_id? ---->如果trx_id不在m_ids中是可以访问该版本的---->成立,说明数据已经提交。

一个一个比,有一个成立就可以读到

不同隔离级别下,生成ReadView的时机不同

  • RC隔离级别下,在事物中每一次执行快照读时生成ReadView

  • RR隔离级别下,记载事物中第一次执行快照读时生成ReadView,后续复用该ReadView

当前读

读取的是记录的最新版本,读取时还要保证其他并发事物不能修改当前记录,会对读取的记录进行加锁

一般的日常操作select(共享锁)、update、insert、delete(排他锁)都是一种当前读

快照读

读取的是记录数据的可见版本,有可能是历史数据,不加锁,是非阻塞读

简单的select不加锁就是快照读

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ulsteruni.cn/article/07500382.html

如若内容造成侵权/违法违规/事实不符,请联系编程大学网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

NGINX Ingress Controller 设置未配置过的域名增加默认路由

背景 k8s 集群对应的公网 slb ip 经常被人绑定域名,监控侧经常会收集到 502 相关状态码的异常告警,着手处理这种bad case策略 1. 所有没有在ingress 配置过的域名要进行处理,即不是公司的、非法绑定到slb 上的域名要加上一条策略 2. NGINX Ingress Controller 设置未配置过…

centos7 安装 Mysql 5.7.28,详细完整教程

https://cloud.tencent.com/developer/article/18863391. 下载 MySQL yum包wget http://repo.mysql.com/mysql57-community-release-el7-10.noarch.rpm 复制2.安装MySQL源rpm -Uvh mysql57-community-release-el7-10.noarch.rpm 复制3.安装MySQL服务端,需要等待一些时间yum ins…

golang+kafka

目录1. 安装JDK、Zookeeper、Scala、kafka2. 启动kafka3. 创建topics4. 查看topics5. 打开一个producer6. 打开一个consumer7. 测试发送和接收消息Windows下安装Kafka 1. 安装JDK、Zookeeper、Scala、kafka 安装Kafka之前,需要安装JDK、Zookeeper、Scala。Kafka依赖Zookeeper,…

Python-数字取证秘籍(三)

Python 数字取证秘籍(三)原文:zh.annas-archive.org/md5/941c711b36df2129e5f7d215d3712f03 译者:飞龙 协议:CC BY-NC-SA 4.0第六章:阅读电子邮件和获取名称的配方 本章涵盖了以下配方:解析 EML 文件查看 MSG 文件订购外卖盒子里有什么?解析 PST 和 OST 邮箱介绍 一旦计…

一个.NET内置依赖注入的小型强化版

前言 .NET生态中有许多依赖注入容器。在大多数情况下,微软提供的内置容器在易用性和性能方面都非常优秀。外加ASP.NET Core默认使用内置容器,使用很方便。 但是笔者在使用中一直有一个头疼的问题:服务工厂无法提供请求的服务类型相关的信息。这在一般情况下并没有影响,但是…