MySQL之ACID实现原理

(/≧▽≦)/~┴┴ 嗨~我叫小奥 ✨✨✨
👀👀👀 个人博客:小奥的博客
👍👍👍:个人CSDN
⭐️⭐️⭐️:Github传送门
🍹 本人24应届生一枚,技术和水平有限,如果文章中有不正确的内容,欢迎多多指正!
📜 欢迎点赞收藏关注哟! ❤️

文章目录

  • MySQL之ACID实现原理
  • 1. MySQL事务
  • 2. 事务四大特性
  • 3. 如何实现ACID
    • 3.1 原子性
    • 3.2 持久性
    • 3.3 隔离性
      • (1)隔离级别
      • (2)并发事务问题
      • (3)锁机制
      • (4)MVCC
        • 三个隐式字段
        • undo log版本链
        • ReadView
    • 3.4 一致性

MySQL之ACID实现原理

1. MySQL事务

事务是一组操作的集合,它是一个不可分割的最小的工作单位,事务会把所有的操作作为一个整体一起向系统提交或者撤销操作请求,即这些操作要么同时成功,要么同时失败。

MySQL中关于事务操作的命令如下:

select @@autocommit; # 查看事务的提交方式
set @@autocommit; # 设置事务的提交方式
commit; # 提交事务
rollback; # 回滚事务
start transaction; # 开启事务
begin; # 开启事务

2. 事务四大特性

事务的四大特性其实就是我们常说的ACID,对于它们的解释如下:

(1)原子性(atomicity):一个事务必须被视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚。事务是操作的最小单位,不可再分。

(2)一致性(consistency):数据库总是从一个一致性转换到另一个一致性。即事务发生前和事务发生后,数据的完整性必须保持一致。

(3)隔离性(isolation):多个事务之间的数据是相互隔离的,当并发访问数据库时,一个正在执行的事务的修改对其他事务时不可见的。

(4)持久性(durability):一个事务一旦被提交或者回滚,它对数据库中的数据的改变是永久性的。即使出现错误,事务也不允许撤销,只能通过“补偿性事务”。

3. 如何实现ACID

原子性:通过undo log来保证的。

持久性:通过redo log来保证的。

隔离性:通过MVCC或者锁机制来保证的。

一致性:通过持久性 + 原子性 + 隔离性来保证的。

3.1 原子性

事务的原子性是通过undo log来实现,undo log回滚日志,用于记录数据被修改前的信息。(保证事务的原子性)

undo log和redo log记录物理日志不一样,它是逻辑日志。可以认为当delete一条记录时,undo log中会记录一条对应的insert记录,反之亦然,当update一条数据时,它会记录一条对应相反的update记录。当rollback执行时,就可以从undo log中的逻辑记录读取到相应的内容并进行回滚。

  • Undo log销毁:undo log在事务执行时产生,事务提交时,并不会立即删除undo log,因为这些日志还可能用于MVCC。
  • Undo log存储:undo log采用段的方式进行管理和记录,存放在rollback segment回滚段中,内部包含1024个undo log segment。

Undo log的作用有两个:

  • 保证数据的原子性,记录事务发生之前的版本,用于回滚。
  • 通过MVCC+undo log版本链实现InnoDB事务中可重复读和读已提交隔离级别。

3.2 持久性

事务的持久性是通过redo log实现的redo log是重做日志,记录的是事务提交时数据页的物理修改。(解决事务的持久性)

该日志由两部分组成:重做日志缓冲(redo logo buffer)以及重做日志文件(redo log file),前者是在内存中,后者在磁盘中。当事务提交之后会把所有的修改信息全部存到该日志文件中,用于在刷新脏页到磁盘中,发生错误时,进行数据恢复使用。

在这里插入图片描述

为什么每次提交要把redo log直接刷新到磁盘中?

如果每次提交直接把Buffer Pool中的数据刷新到磁盘文件中,会存在严重的性能问题。因为通常在事务中,会进行多条操作,这些操作都是随机去操作数据页的,这时候就会涉及到大量的随机磁盘IO。

如果是在事务提交的时候,不把脏页数据直接刷新到磁盘IO,而是先把redo log日志文件异步刷新到磁盘中,由于日志文件都是以追加的方式写入磁盘的,那么这时候就是顺序磁盘IO,性能是比随机IO高的,这也被称为WAL(Write-Ahead Logging)。

3.3 隔离性

事务的隔离性通过MVCC+锁来实现的。

(1)隔离级别

事务的隔离级别有四种:

  • 读未提交(read uncommitted):指一个事务还没提交时,它做的变更就能被其他事务看到。读未提交的数据,称之为脏读(Dirty Read)。
  • 读已提交(read committed):指一个事务提交之后,它做的变更才能被其他事务看到。这种隔离级别支持不可重复读(Nonrepeatable Read),因为同一事务在不同时期读取到的数据可能是不一样的。
  • 可重复读(repeatable read):指一个事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的,MySQL InnoDB 引擎的默认隔离级别。但是会产生幻读的问题,当前事务读取某一范围的数据时,另一个事务又在该范围内插入了新行,用户再次读取时,会出现新的“幻影”。
  • 可串行化(serializable ):会对记录加上读写锁,在多个事务对这条记录进行读写操作时,如果发生了读写冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。

查看隔离级别

select @@transaction_isolation;

设置隔离级别

set session transaction isolation level read uncommitted;

(2)并发事务问题

脏读:脏读指的是读到了其他事务未提交的数据,未提交意味着这些数据可能会回滚,也就是可能最终不会存到数据库中,也就是不存在的数据。

不可重复读:对比可重复读,不可重复读指的是在同一事务内,不同的时刻读到的同一批数据可能是不一样的,可能会受到其他事务的影响,比如其他事务改了这批数据并提交了。通常针对数据更新操作。

幻读:幻读是针对数据插入操作来说的。假设事务A对某些行的内容作了更改,但是还未提交,此时事务B插入了与事务A更改前的记录相同的记录行,并且在事务A提交之前先提交了,而这时,在事务A中查询,会发现好像刚刚的更改对于某些数据未起作用,让用户感觉感觉出现了幻觉,这就叫幻读。

可重复读:可重复读指的是在一个事务内,最开始读到的数据和事务结束前的任意时刻读到的同一批数据都是一致的。

不可重复读与幻读的区别

不可重复度侧重于读取到其他事务修改的数据,描述的通常是数据更新操作下的问题;

幻读侧重于读取到其他事务新增或者删除的数据,描述的通常是数据插入操作下的问题。

(3)锁机制

MySQL锁机制的基本工作原理就是:事务在修改数据库之前,需要先获得相应的锁,获得锁的事务才可以修改数据;在该事务操作期间,这部分的数据是锁定,其他事务如果需要修改数据,需要等待当前事务提交或回滚后释放锁。

  • 排它锁解决脏读:在RC隔离级别下,事务A只有在对数据修改时才加排它锁,但直到事务 commit 时才释放锁。因此,同时进行的事务B希望读取同一行数据时,会被事务A的排它锁堵塞,所以解决了脏读的问题。
  • 共享锁解决不可重复读:在RR隔离级别下,除了执行读已提交的排它锁方式,还会在读取一行数据时,为这行数据添加共享锁直至事务 commit。例如,事务A读取ID=1这一行数据,然后为ID=1添加共享锁,事务B同时希望update ID=1,此时获取写锁失败,因此在事务A执行完之前,没有其他任何事务可以对ID=1这一行做修改,因此解决了重复读的问题。
  • 临建锁解决幻读:默认情况下,InnoDB在RR事务隔离级别运行,InnoDB使用next-key锁进行搜索和索引扫描,以防止幻读。

(4)MVCC

全称Multi-Version Concurrency Control,多版本并发控制。指维护一个数据的多个版本,使得读写操作没有冲突,快照读为MySQL实现MVCC提供了一个非阻塞读功能。MVCC的具体实现,还需要依赖于数据库记录中的三个隐式字段undo log日志readView

学习MVCC之前我们先来了解一下两个基本的概念。

当前读

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

对于我们日常的操作,如

  • select... lock in share mode(共享锁)
  • select ... for update
  • updateinsertdelete(排他锁)

快照读

简单的select(不加锁)就是快照读,快照读,读取的时记录数据的可见版本,有可能是历史数据,不加锁,是非阻塞读。

  • Read Commited 读已提交:每次select,都生成一个快照读。
  • Repeatable Read 可重复读:开启事务后的第一个select语句才是快照读的地方。
  • Serializable 可串行化 :快照读会退化为当前读。
三个隐式字段
  • DB_TRX_ID:最近修改事务ID,记录插入这条记录或者最后一次修改该记录的事务ID。
  • DB_ROLL_PTR:回滚指针,指向这条记录的上一个版本,用于配置undo log,指向上一个版本。
  • DB_ROW_ID:隐藏主键,如果表结构没有指定主键,将会生成该隐式字段。
    // 查看数据库文件,在表结构字段中就可以看到隐式字段的相关信息
    ibd2sdi xx.ibd
undo log版本链

undo log就是回滚日志,在insert、update、delete的时候产生的便于数据回滚的日志。

  • 在insert的时候,产生的undo log日志只在回滚的时候需要,在事务提交后,可被立即删除。
  • 而update、delete的时候,产生的undo log日志不仅在回滚时需要,在快照读时也需要,不会立即被删除。

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

在这里插入图片描述

ReadView

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

ReadView中包含四个核心字段:

  • m_ids:当前活跃的事务ID集合。
  • min_trx_id:最小活跃事务ID。
  • max_trx_id:预分配事务ID,当前最大事务ID + 1,因为事务ID是自增的。
  • creator_trx_id:ReadView创建者的事务ID。

版本链访问规则

我们假设当前事务ID为trx_id,则

trx_id == creator_trx_id,可以访问该版本,因为数据操作是当前事务完成的。

trx_id < min_trx_id,可以访问该版本,因为min_trx_id事务已经在当前事务之前提交了,数据修改已经提交了。

min_trx_id <= trx_id <= max_trx_id, 如果当前事务trx_id不在m_ids中是可以访问该版本的,因为数据修改已经提交了。

读视图的生成规则

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

  • Read Committed:在事务中每执行一次快照读时生成ReadView。
  • Repertable Read:仅在事务中第一次执行快照读时生成ReadView,后续复读该ReadView。

3.4 一致性

事务的一致性是通过 原子性+持久性+隔离性 来实现的,也就是说,一致性才是最终事务的目的。

  • 原子性:语句要么全执行,要么全不执行,是事务最核心的特性,事务本身就是以原子性来定义的,主要基于undo log实现。
  • 持久性:保证事务提交后不会因为宕机等原因导致数据丢失,主要基于redo log实现。
  • 隔离性:保证事务执行尽可能不受其他事务影响;InnoDB默认的隔离级别是RR,RR的实现主要基于锁机制(包含next-key lock)、MVCC(包括数据的隐藏列、基于undo log的版本链、ReadView)。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

政安晨:【TensorFlow与Keras实战演绎机器学习】专栏 —— 目录

政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras实战演绎机器学习 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff01; 本篇是作者政安晨的专栏《TensorFlow与Keras…

Appium Inspector 展示设备当前页面

定位元素需要使用appium inspector&#xff0c;之前每次都是从登录页开始&#xff0c;后来发现连接设备的时候只需要去掉appPackage、appActivity即可。 { "platformName": "Android", "platformVersion": "6", "deviceNa…

制作CHM格式的Java学习笔记

1.相关制作工具 Markdown写作工具&#xff1a;Typro 写作md学习笔记 CHM制作工具&#xff1a;妙网电子书制作大师 导出书刊&#xff1a;选CHM格式 2.为什么选择CHM 无限分级性能保证 CHM的本质是HTML&#xff0c;也就是说无论制作的CHM文档中包括了多少内容&#xff0c;打开…

全国土壤阳离子交换量CEC空间分布数据

土壤阳离子交换量&#xff0c;简称CEC&#xff0c;是指土壤胶体所能吸附各种阳离子的总量。土壤阳离子交换量 cation exchange capacity 即CEC 是指土壤胶体所能吸附各种阳离子的总量&#xff0c;其数值以每千克土壤中含有各种阳离子的物质的量来表示&#xff0c;即mol/kg。 中…

景联文科技上新高质量大模型训练数据!

在过去的一年中&#xff0c;人工智能领域呈现出了风起云涌的态势&#xff0c;其中模型架构、训练数据、多模态技术、超长上下文处理以及智能体发展等方面均取得了突飞猛进的发展。 在3月24日举办的2024全球开发者先锋大会的大模型前沿论坛上&#xff0c;上海人工智能实验室的领…

mfc140.dll丢失的解决方法,快速修复win10系统dll问题

在Windows 10操作系统环境下&#xff0c;如果发现系统中关键的动态链接库文件mfc140.dll丢失&#xff0c;可能会引发一系列运行问题。mfc140.dll是Microsoft Foundation Class Library&#xff08;微软基础类库&#xff09;的重要组成部分&#xff0c;对于许多基于该库开发的应…

藏区特产销售平台设计与实现|SpringBoot+ Mysql+Java+ B/S结构(可运行源码+数据库+设计文档)

本项目包含可运行源码数据库LW&#xff0c;文末可获取本项目的所有资料。 推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 2024年56套包含java&#xff0c;…

xilinx FPGA 除法器ip核(divider)的学习和仿真(Vivado)

在设计中&#xff0c;经常出现除法运算&#xff0c;实现方法&#xff1a; 1、移位操作 2、取模取余 3、调用除法器IP核 4、查找表 简单学习除法器IP。 网上很多IP翻译文档&#xff0c;不详细介绍&#xff0c;记录几个重要的点&#xff1a; 1、三种算法模式(不同模式所消耗的资…

短视频矩阵系统---开发源头交付

短视频矩阵系统---开发源头交付 短视频矩阵系统的核心开发步骤包括以下几个方面&#xff1a; 1. 系统设计&#xff1a;根据需求分析&#xff0c;设计出相应的系统架构&#xff0c;包括数据库设计、系统功能模块设计等。 2. 开发基础功能&#xff1a;基础功能包括短视频的上传、…

CI/CD 搭建jenkins基础测试环境构建项目(一)

Jenkins是一个开源的持续集成工具&#xff0c;可以帮助开发团队自动化构建、测试和部署他们的软件项目。通过Jenkins&#xff0c;开发团队可以实现快速、高效地交付软件&#xff0c;并及时发现和解决问题&#xff0c;从而提高团队的生产力和软件质量。持续集成/持续交付&#x…

极光笔记|极光消息推送服务的云原生实践

摘要 极光始终秉承“以开发者为中心”的战略导向&#xff0c;极光推送&#xff08;JPush&#xff09;是国内领先的消息推送服务。极光推送&#xff08;JPush&#xff09;本质上是一种软件付费应用程序&#xff0c;结合当前主流云厂商基础施设&#xff0c;逐渐演进成了云上SaaS…

AP5127 是一款 PWM 工作模式,高效率、外围简单、内置功率管

产品描述 AP5127 是一款 PWM 工作模式,高效率、外围简单、内置功率管&#xff0c;适用于 12-100V 输入的高精度降压 LED 恒流驱动芯片。输出最大功率可达25W&#xff0c;最大电流 2.5A。 AP5127 可实现全亮/半亮功能切换&#xff0c;通过MODE 切换&#xff1a;全亮/半亮/循环模…

基于深度学习的OCR,如何解决图像像素差的问题?

基于深度学习的OCR技术在处理图像像素差的问题时确实面临一定的挑战。图像像素差可能导致OCR系统无法准确识别文本&#xff0c;从而影响其精度和可靠性。尽管已经有一些方法如SRN-Deblur、超分SR和GAN系列被尝试用于解决这个问题&#xff0c;但效果并不理想。然而&#xff0c;这…

前端删除列表数据后页码重置逻辑

问题描述 需要调整页码的例子&#xff1a; 列表一共有10页数据&#xff0c;用户把第10页数据全部删除后&#xff0c;需要把数据重置成上一页&#xff0c;也就是第9页 不用调整页码的例子&#xff1a; 列表一共有1页数据&#xff0c;用户把本页数据全部删除后&#xff0c;页码…

【考研数学二】线性代数重点笔记

目录 第一章 行列式 1.1 行列式的几何意义 1.2 什么是线性相关&#xff0c;线性无关 1.3 行列式几何意义 1.4 行列式求和 1.5 行列式其他性质 1.6 余子式 1.7 对角线行列式 1.8 分块行列式 1.9 范德蒙德行列式 1.10 爪形行列式的计算 第二章 矩阵 2.1 初识矩阵 2…

Git基础(24):分支回退

文章目录 前言放弃已修改的内容分支回退到指定commit 前言 将分支回退到之前的某个版本 开发中&#xff0c;可能开发某个功能不需要了&#xff0c;或者想要回退到之前历史的某个commit&#xff0c; 放弃后来修改的内容。 放弃已修改的内容 如果未提交&#xff0c;直接使用 …

申请GeoTrust数字证书

GeoTrust介绍&#xff1a; 大家应该都不陌生&#xff0c;作为最老资格的一批国际大牌证书&#xff0c;GeoTrust的品牌效益和使用群体非常庞大。在数字证书领域也是当之无愧的龙头地位&#xff0c;作为Symantec和Digicert的子品牌&#xff0c;证书安全性能方面毋庸置疑&#xf…

Android内存优化项目经验分享 兼顾效率与性能

背景 项目上线一段时间后,回顾重要页面 保证更好用户体验及生产效率&#xff0c;做了内存优化和下载导出优化&#xff0c;具体效果如最后的一节的表格所示。 下面针对拍摄流程的两个页面 预览页 导出页优化实例进行介绍&#xff1a; 一.拍摄前预览页面优化 预览效果问题 存在…

TrackballControls是Three.js中的一个相机控件,它允许用户通过鼠标拖拽、滚轮缩放以及键盘移动相机,实现类似于球形的相机旋转操作。

demo案例 TrackballControls是Three.js中的一个相机控件&#xff0c;它允许用户通过鼠标拖拽、滚轮缩放以及键盘移动相机&#xff0c;实现类似于球形的相机旋转操作。这个控件可以用于3D场景中&#xff0c;以提供更好的用户体验。以下是对TrackballControls的入参、出参、方法…

由浅到深认识Java语言(25):正则表达式

该文章Github地址&#xff1a;https://github.com/AntonyCheng/java-notes 在此介绍一下作者开源的SpringBoot项目初始化模板&#xff08;Github仓库地址&#xff1a;https://github.com/AntonyCheng/spring-boot-init-template & CSDN文章地址&#xff1a;https://blog.c…