聊聊MySQL中的事务,MVCC

news2024/11/15 8:17:15

事务


  • 我们知道,事务具有四大特性——ACID

  • A atomicity 指的是原子性

  • C consistency 指的是一致性

  • I isolation 指的是隔离性

  • D durability 指的是持久性

四大特性的实现原理


原子性

  • 原子性在这指的是整个事务操作,要么同时成功要么同时失败。让它变成一个整体。

  • 同时成功这好办,难办的是同时失败。

  • 想要实现同时失败,就需要恢复之前的数据,如何恢复旧版本数据呢? undolog回滚日志

  • undolog回滚日志是实现事务原子性的关键。它保存了数据修改之前的历史数据。当我们的事务中有insert操作时,他会反向的记录一个delete,反之亦然。

隔离性


  • 隔离性指的是当由多个活动事务的时候,每一个事务应该是相互独立的整体。也就是说它们互不干扰。

  • 隔离性实现是基于MVCC多版本数据并发控制实现的。

持久性


  • 持久性指的是,当我的事务提交,事务里面涉及修改的数据都会得到持久性。而不会因为某些特殊原因导致我的修改数据没有更新到磁盘里面去。

  • 持久性的实现是由redolog重做日志完成的。

  • 当我们对数据做增删改的时候,会经历这样的过程:

  • 修改缓冲池里面的数据

  • 写入缓冲池的redolog

  • 提交事务

  • 同步更新磁盘中的redolog

  • 等待后台线程刷新脏数据,完成持久化。

一致性


  • 一致性指的是发生增删改操作时,数据库从一个一致性的状态进入另一个一致性状态。

  • 其实上面三个特性就是为了实现一致性。

  • 举例说:

  • 我的钱包里有1000块钱,买了一包烟花掉100块钱。

  • 那么此时的一致性应该是这样:

  • 我的钱包从1000变成了900.

  • 烟店老板的钱包从N 变成了N+100

redolog


redolog是innodb存储引擎提供的一个日志机制,它可以保证事务的持久性特性。

redolog解决什么问题


  • 首先要知道,mysql的存储结构是包含内存结构和硬盘结构。

  • 内存结构中主要的结构就是缓冲池,当我们增删改一条数据的时候,会从缓冲池里面寻找这条数据,如果没有则从硬盘读取。在对数据做修改的时候,如果不是唯一索引条件的修改,那么会先把缓存池里的数据先修改,为了保证性能,修改完之后并不会马上同步到硬盘里。此时存在缓冲池里面这条不一致的数据就是脏数据。

  • 脏数据会等待一段时间由后台线程刷新到磁盘中。

  • 假如没有redolog,在刷新到磁盘的过程中出现问题了,那么就会出现一致性问题。

  • redolog就是为了解决这个问题。

redolog啥时候用


  • 当我们对数据做修改时,此时就会记录这条修改数据的redolog,此时事务尚未提交,记录的是redolog的内存部分。

  • 当事务提交的时候,便会将内存中的redolog同步到磁盘中去。

  • 搞得这么麻烦,为啥不直接在事务提交的时候将脏页刷新过去?

  • 这是因为数据的修改,写入磁盘顺序是随机的。而写入日志文件,则是顺序写入磁盘,在性能上要远强于直接写入数据。在写入数据之前先写入日志,这个叫做WAL(Write Ahead Logging)

  • 当脏页成功刷盘之后,redolog就可以被销毁了。

redolog会不会有一致性问题


  • 不会

  • 从上面也知道,redolog 是在事务提交的时候,同步写入硬盘。如果此时提交事务这条线程宕机了,那么原事务也会撤销掉。也就是说由于持久化redolog这个动作是同步的,所以不会有一致性问题。

redolog如何保证持久性


  • 如果真的发生宕机,redolog如何保证事务提交之后仍然可以将脏页持久到磁盘。

  • 这个部分,则是由redolog的两阶段提交做保证。

  • redolog在写入磁盘的时候,并不是写进去就完事的。

  • 它是有两个状态,跟Binlog做配合。

  • 刚刚写入磁盘,此时是repare准备阶段,当Binlog接收到时,此时才是真正的commit状态。

  • 只有commit状态的redolog才会被看作事务真正完成了,如果是prepare状态则代表这条日志还没有被处理完。

undolog


undolog跟redolog不同,它是逻辑日志。当有修改操作发生时,它记录的时与它相反的动作。undolog保证了事务的原子性特性。

undolog解决什么问题


  • 作为回滚日志,它主要解决的就是如何实现事务的同时失败。

  • undolog用于记录数据被修改前的信息。

  • 当insert的时候,他会记录相反的操作delete;反之亦然。当Update的时候则会记录一条相反的数据。

undolog啥时候用


  • undolog是在修改数据的时候生成的。

  • undolog在事务提交之后不会马上删除,因为它还可以用于MVCC。

undolog版本链


  • insert产生的undolog 只在回滚需要,在事务提交后可被立即删除。

  • update,delete的时候产生的undolog不仅在回滚是需要,在快照读的时候也需要,不会立即删除。因为它记录了数据之前的版本是什么样子。

  • 当有活动事务的时候,undolog版本链就不能被删除。

  • 不同的事务或者相同事务对同一条记录进行修改,会导致这条记录的undolog生成一条记录版本链表,链表的头部都是最新的旧纪录,链表尾部是最早的旧纪录.

MVCC


基本概念


全称 Multi-Version Concurrency Control,多版本并发控制。指维护一个数据的多个版本,使得读写操作没有冲突。数据库隔离级别读已提交、可重复读 都是基于MVCC实现的,事务的隔离性也是基于MVCC实现。相对于加锁简单粗暴的方式,它用更好的方式去处理读写冲突,能有效提高数据库并发性能。MVCC的具体实现,还需要依赖于数据库记录中的三个隐式字段、undo log日志、readView。

当前读

  • 当前读读的是最新的数据,在读取的时候给这一行数据加上共享锁,增删改加的是排他锁,它们也是当前读。

  • 例如select ... for share mode, delete ,insert ,update

快照读

  • 简单的select 就是快照读,快照读读取的是记录数据的可见版本。有可能是历史版本,也可能是最新版本。

  • 读取的时候不加锁,非阻塞读。

  • 在RR(可重复读)的隔离级别下,事务中的第一次读是快照读,后续读到的数据都是第一次快照读的版本。所以它可以解决不可重复读。

  • 而RC(读已提交)的隔离级别下,事务中每一次读取数据都是快照读,所以不可以解决不可重复读,可以解决读已提交。

三个隐藏字段

  • MVCC的实现原理依赖于三个隐藏字段,undolog,readView

  • 三个隐藏字段分别为,事务ID,回滚指针,行ID(有可能不需要)

隐藏字段

含义

DB_TRXID

最近修改事务D,记录插入这条记录或最后一次修改该记录的事务D。

DB ROLL PTR

回滚指针,指向这条记录的上一个版本,用于配合undo log,指向上一个版本。

DB ROW ID

隐藏主键,如果表结构没有指定主键,将会生成该隐藏字段。

ReadView


  • readView(读视图)是快照读SQL执行的时候MVCC提取数据的依据,记录并且维护系统当前活跃的事务id

  • readView包含四个核心字段

字段

含义

m_ ids

当前活跃的事务D集合

min_ trx id

最小活跃事务ID

max_ trx id

预分配事务D 当前最大事务ID+1(因为事务D是自增的)

creator trx_ id

ReadView创建者的事务D

MVCC的实现原理


  • 前面提到,MVCC的实现依赖于三个隐藏字段+undolog+ReadView

  • 那么具体是怎么利用他们完成多版本并发控制的呢?

  • RreadView版本链数据的访问规则 + 不同隔离级别下快照读的时机

  • readView规定了版本链数据的访问规则,这套规则就是实现MVCC的关键。

条件

是否可以访问

说明

trx_id == creator_trx_id

可以访问该版本

成立,说明数据是当前这个事 务更改的。

trx_id< min_trx_id

可以访问该版本

成立,说明数据已经提交了。

trx_id> max_trx_id

不可以访问该版本

成立,说明该事务是在 ReadView生成后才开启。

min_trx_id<= trx_id <= max_trx_id

如果trx_id不在m_ids中, 是可以访问该版本的

成立,说明数据已经提交。

  • 简单来说,这套规则会让那些可以被访问的数据是别的事务已经提交的数据。

  • 同时,不同的隔离级别,生成readView的时机也是不同的

  • READ COMMITTED :在事务中每一次执行快照读时生成ReadView。

  • REPEATABLE READ:仅在事务中第一次执行快照读时生成ReadView,后续复用该ReadView。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

若依管理系统搭建运行环境--基于SpringBootVue前端分离版

若依框架搭建运行环境-如何下载一、技术支持&#xff1a;二、Redis安装及运行三 目录结构四、导入数据库五 修改配置文件1.application-druid.yml文件 &#xff08;路径&#xff1b;RuoYi-Vue-master\ruoyi-admin\src\main\resources\application-druid.yml&#xff09;2.appli…

越界访问数组

越界访问是指访问&#xff08;操作修改&#xff09;了不属于自己的空间 我们以如下代码为例&#xff1a;此代码在vs中进行 #include <stdio.h> int main() {int i 0;int arr[] {1,2,3,4,5,6,7,8,9,10};for(i0; i<12; i){arr[i] 0;printf("hello\n");}r…

阿里云平台与MQTTX软件通信

阿里云平台与MQTTX软件通信 上一篇文章介绍了如何创建阿里云物联网平台以及MQTT.fx软件通信配置&#xff1a;https://blog.csdn.net/weixin_46251230/article/details/128993864 但MQTT.fx软件需要许可证才能使用&#xff0c;所以使用另一款软件MQTTX来代替 MQTTX软件下载 官…

【C++】类与对象(二)

前言 在前一章时我们已经介绍了类与对象的基本知识&#xff0c;包括类的概念与定义&#xff0c;以及类的访问限定符&#xff0c;类的实例化&#xff0c;类的大小的计算&#xff0c;以及C语言必须传递的this指针&#xff08;C中不需要我们传递&#xff0c;编译器自动帮我们实现&…

CSP-《I‘m stuck!》-感悟

题目 做题过程 注&#xff1a;黄色高亮表示需要注意的地方&#xff0c;蓝色粗体表示代码思路 好久没有写过代码了&#xff0c;今天做这道编程题&#xff0c;简直是灾难现场。 上午编程完后发现样例没有通过&#xff0c;检查发现算法思路出现了问题&#xff1a;我计数了S不能到…

【每日一题Day116】LC1138字母板上的路径 | 模拟

字母板上的路径【LC1138】 我们从一块字母板上的位置 (0, 0) 出发&#xff0c;该坐标对应的字符为 board[0][0]。 在本题里&#xff0c;字母板为board ["abcde", "fghij", "klmno", "pqrst", "uvwxy", "z"]&…

BFS的使用(acwing提高课之搜索)

bfsBFS1. 多源bfs2.最小步数模型1.魔板2.八数码问题3.双端队列广搜4.双向广搜5.A*算法BFS bfs是搜索算法里面最基础的算法&#xff0c;对于队首的点&#xff0c;每次搜索其周围所有的点&#xff0c;然后将其入队。队列里面的点具有两个特性&#xff1a; &#xff08;1&#xf…

OpenWrt路由器设置IPv6域名动态解析,同时实现IPv4设备访问IPv6节点

文章目录0、前言1、准备工作2、详细步骤2.1、OpenWrt路由器软件包安装2.2、防火墙放行入站数据&#xff08;修改为“接受”并保存应用&#xff09;2.3、路由器做好ipv6设置&#xff08;略&#xff09;2.4、域名解析服务商对域名的解析设置2.5、路由器中动态域名插件的设置3、关…

23.2.12 LC每日一题 —— 极尽地高效利用题目中所提供的有效信息

文章目录23.2.12 LC每日一题 —— 极尽地高效利用题目中所提供的有效信息题目链接&#xff1a;题目大意&#xff1a;注意&#xff1a;示例&#xff1a;参考代码&#xff08;py3&#xff09;&#xff1a;总结23.2.12 LC每日一题 —— 极尽地高效利用题目中所提供的有效信息 题目…

Redis内存存储效率问题

目录 内存碎片是如何形成的&#xff1f; 如何判断是否有内存碎片&#xff1f; 如何清理内存碎片&#xff1f; INFO命令 实习期间&#xff0c;了解到&#xff0c;企业级开发中多个项目使用Redis&#xff0c;运行Redis实例的有可能是同一台物理机器&#xff0c;那么&#xff…

【水文模型】评价指标

水文模型模拟效果评价指标1 皮尔逊相关系数&#xff08;Pearson’s correlation coefficient, PCC&#xff09;2 百分比偏差&#xff08;Percent bias, Pbias&#xff09;3 纳什效率系数&#xff08;the Nash-Sutcliffe efficiency coefficient, NSE&#xff09;4 克林-古普塔效…

【大前端 合集】包管理工具差异性

包管理工具 这里会对市场上使用最多的包管理工具 yarn/ npm 以及新秀 pnpm 做一个横向分析 1. 前言 在做分析以及学习之前&#xff0c;最好可以读下 pnpm 官网。可以理解下 pnpm 的核心宗旨 当使用 npm 或 Yarn 时&#xff0c;如果你有 100 个项目&#xff0c;并且所有项目都有…

matlab搭建IAE,ISE,ITAE性能指标

目录前言准备IAEISEITAE前言 最近在使用matlab搭建控制系统性能评价指标模型&#xff0c;记录一下 准备 MATLAB R2020 IAE IAE函数表达式如下所示&#xff1a; IAE函数模型如下所示&#xff1a; ISE ISE函数表达式如下所示&#xff1a; ISE函数模型如下所示&#xff…

来看看你的是否会正确的使用索引

索引&#xff0c;可以有效提高我们的数据库搜索效率&#xff0c;各种数据库优化八股文里都有相关的知识点可背&#xff0c;不过单纯的被条目其实很容易忘记。 所以我想和大家聊一聊这个索引的正确使用方法&#xff0c;结合一些具体的例子来帮助大家理解索引优化。 1、索引列独…

Redis使用方式

一、Redis基础部分: 1、redis介绍与安装比mysql快10倍以上 *****************redis适用场合**************** 1.取最新N个数据的操作 2.排行榜应用,取TOP N 操作 3.需要精确设定过期时间的应用 4.计数器应用 5.Uniq操作,获取某段时间所有数据排重值 6.实时系统,反垃圾系统7.P…

开源、低成本的 Xilinx FPGA 下载器(高速30MHz)

目前主流的Xilinx下载器主要有两种&#xff1a;一种是Xilinx官方出品的Xilinx Platfom Cable USB&#xff0c;还有一个就是Xilinx的合作伙伴Digilent开发的JTAG-HS3 Programming Cable。 JTAG-HS系列最大支持30MHz下载速度&#xff0c;基于FTDI的FT2232方案。 JTAG-HS系列对比…

ipv6上网配置

一般现在的宽带都已经支持ipv6了&#xff0c;但是需要一些配置才能真正用上ipv6。记录一下配置过程。 当前测试环境为移动宽带&#xff0c;光猫下面接了一个路由器&#xff0c;家里所有的设备都挂到这个路由器下面的。 1. 光猫改桥接 光猫在使用路由模式下&#xff0c;ipv6无…

一款针对EF Core轻量级分表分库、读写分离的开源项目

更多开源项目请查看&#xff1a;一个专注推荐.Net开源项目的榜单 在项目开发中&#xff0c;如果数据量比较大&#xff0c;比如日志记录&#xff0c;我们往往会采用分表分库的方案&#xff1b;为了提升性能&#xff0c;把数据库查询与更新操作分开&#xff0c;这时候就要采用读写…

谈谈SpringBoot(三)

1. SpringBoot依赖管理 1.1 父依赖 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.8</version><relativePath/></parent> 点击进去&#xf…

Redis中的hash结构和扩容机制

1.rehash原理 hash包含两个数据结构为字典数组ht[0]和ht[1]。其中ht[0]用来存放数据&#xff0c;ht[1]在rehash时使用。 扩容时&#xff0c;ht[1]的大小为第一个大于等于ht[0].used*2的2的幂次方的数&#xff1b; 收缩时&#xff0c;ht[1]的大小为第一个大于等于ht[0].used的…