MySQL 事务的ACID特性

MySQL事务是什么,它就是一组数据库的操作,是访问数据库的程序单元,事务中可能包含一个或者多个 SQL 语句。这些SQL 语句要么都执行、要么都不执行。我们知道,在MySQL 中,有不同的存储引擎,有的存储引擎比如MyISAM 是不支持事务的,所以说MySQL 事务实际上是发生在 存储引擎部分

事务主要有四大特性,分别是原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和 持久性(Durability)。它实际上是从四个方面来阐述MySQL 事务的特点,下面就分别来看MySQL 通过什么方式来实现这些特性。

一、原子性

1. 原子性定义

原子性就是指事务的不可分割性,对于一个事务而言,就是要么都执行,要么都不执行。在MySQL 中是通过回滚来实现,比如事务中的一个 SQL 语句失败了,那么该事务的所有SQL 语句必须都进行回滚,退回到事务前的状态。

2. InnoDB 中原子性的实现

上面说到,MySQL 中原子性是通过回滚的方式来实现,那么回滚是怎么实现的?这就涉及到MySQL 中的Undo 日志,原子性就是通过 Undo log 来实现的。

具体是Undo log 会在一个事务中,记录当前 SQL 语句的上一个语句成功的执行状态,如果在执行当前 SQL 语句失败后,就可以通过 Undo log 来回滚到 SQL 语句执行前的状态,这样就能保证事务的原子操作。举个例子,比如插入一条记录:insert into test values(1,'刘备','蜀')实际上得到的记录图如下,中间的 roll_pointer 是指向undo log的指针。

undo log 在事务提交后,undo log 日志也就会被回收。

二、持久性

1.持久性定义

持久性是指事务一旦提交,它对事务的改变是永久性的,哪怕系统发生了故障,也不会改变其提交的结果。持久性是通过 Redo log 来实现的。

2.InnoDB 中持久性的实现

在讲持久性之前,先介绍一下MySQL 中 Buffer pool,我们知道MySQL 数据是存储在磁盘中,为了实现快速读写数据,我们会在内存中设置一个 Buffer pool 缓冲池,数据库可以直接与 Buffer Pool 进行读取交互,定期再将 Buffer Pool 数据存储到磁盘中,这样会大大提高数据库的读写效率。

但是如果系统断电或者宕机,内存是无法保存信息的,而此时刚好Buffer Pool 数据没有同步到磁盘上,就会造成数据丢失。因此就需要 redo log 来对更新和修改操作进行记录,使得在系统重启时能够恢复到原来的状态。

Redo log 是一种预写式日志(write-Ahead Log),它记录的是在某个数据页上做了什么修改。当有记录需要更新时,InnoDB 引擎会先把记录写到 redo log 中,在系统空闲时,再将操作记录更新到磁盘中。redo log 结构如下图所示:

  • write pos 是当前记录的位置
  • checkpoint 当前要擦除的位置
  • write pos 和 check point 之间是 redo 内存区域中还空着的部分,用于记录新的操作。

redo log 只需要记录真正修改的部分,它的同步效率要比 buffer 同步数据快的多。那么 redo log 何时会同步到磁盘中去,主要是 innodb_flush_log_at_trx_commit这个参数的设置:

  • 0:表示当提交事务时,并不将缓冲区的 redo log 写入磁盘的日志文件,而是等待主线程每秒刷新
  • 1:在事务提交时将缓冲区的 redo log 同步写到磁盘中,保证一定会写入成功
  • 2:在事务提交时将缓冲区的redo 日志异步写入到磁盘中,即不能完全保证 commit 时肯定会写入到 redo 日志文件,只是有这个动作。

建议这个参数设置为1 ,同步写入磁盘中。

3.Binlog 和 Redo log

binlog 和 redo log 日志的区别

我们知道 redo log 是InnoDB 存储引擎的事务日志,那么对于 server 层是否也存在事务日志,答案是确定的,server 层的事务日志就是 binlog (归档日志)。为啥会出现两种事务日志,是因为最开始的 MySQL 中并没有 InnoDB 引擎,MySQL 自带的引擎是 MyISAM ,用的就是 binlog 日志来实现事务。那么两者具体有什么区别呢:

  • redo log 是InnoDB 引擎特有的,binlog 是 server 层实现,所有的存储引擎都可以使用
  • redo log 是物理日志,它存储的是在数据页上的修改;binlog 是逻辑日志,存储的是sql 语句的原始逻辑
  • redo log 空间是固定的,会使用完并覆盖原来的日志。binlog 可以追加写入,不会覆盖原来的日志
binlog 和 redo log 日志的两阶段提交

既然在MySQL 中存在两种日志,那么为了让两份日志之间的逻辑一致,就需要两阶段提交来实现这一任务。具体怎么实现的,我们以这个语句update T set c=c+1 where ID = 2来看:

  • 1.执行器先通过执行引擎查找 ID=2 这一行,如果数据在内存Buffer Pool 中直接返回。如果在磁盘中,则先从磁盘中读取到内存中,然后再返回。
  • 2.对取到的数据进行操作,将值加1后得到新的数据,再调用引擎写入数据,更新内存。
  • 3.同时将对数据页的修改记录到 redo log 中,这个时候 redo log 处于第一个阶段 prepare。
  • 4.执行器生成对于这个操作的 binlog ,并将 binlog 写入磁盘中
  • 5.执行器调用提交事务接口,把刚刚写入的 redo log 修改成 commit 状态,更新到此完成。

三、隔离性

1.隔离性定义

隔离性是指事务内部的操作与其他事务是隔离的,并发过程中的各个事务之间不能互相干扰。对于事务的操作,主要分成两种:读操作与写操作之间的影响、写操作与写操作之间的影响。

2.隔离性的实现

上面我们说到了事务之间的影响主要分成两个方面,那么MySQL 中是如何处理这两种情况的呢?

  • 写操作与写操作:就像 java 中的锁一样,通过锁来解决(MySQL 锁后续会出一篇文章详细介绍)
    • 幻读
  • 写操作与读操作:主要是通过 MVCC 机制来解决(MVCC 后续会出一篇文章进行介绍)
    • 脏读
    • 不可重复读
写操作与写操作的隔离实现

我们可以通过锁的方式,来保证同一时刻的一个数据的写操作只能被一个事务所执行。

在MySQL 中,根据加锁范围,大致可以分成三类:全局锁、表级锁和行级锁。 在一个事务修改数据前,需要获取对应的锁才能修改对应的数据。其他事务想要修改该数据,必须要等到之前的事务提交或回滚释放锁后,才能抢这个锁来修改数据。

锁的概况可以通过以下语句进行查询:

# 锁的概况
select * from information_schema.innodb_locks;
# InnoDB 整体状态,也包括锁的情况
show engine innodb status
写操作与读操作的隔离实现

为了保证性能,我们不能把所有操作都进行上锁,对于写操作和读操作,可以使用不加锁的方式来实现事务隔离。主要就是通过MySQL 中的 MVCC 机制来解决。

四、一致性

一致性的定义与实现

一致性的实现就是在前面三个特性实现的基础上而来的,没有前面三个特性的实现,也就达不到最后数据库事务的一致性。

参考资料

https://time.geekbang.org/column/article/68963

https://www.cnblogs.com/kismetv/p/10331633.html

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

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

相关文章

凸优化 2:如何判定凸函数?

凸优化 2:如何判定凸函数? 如何判断一个目标函数是凸函数?如果是凸函数,那ta的定义域是凸集合 一个函数求俩次梯度,大于等于0,那这个函数就是一个凸函数在同样条件下,怎么设计为凸函数模型&…

使用 Elasticsearch 检测抄袭 (二)

我在在之前的文章 “使用 Elasticsearch 检测抄袭 (一)” 介绍了如何检文章抄袭。这个在许多的实际使用中非常有意义。我在 CSDN 上的文章也经常被人引用或者抄袭。有的人甚至也不用指明出处。这对文章的作者来说是很不公平的。文章介绍的内容针对很多的…

【星海出品】Keepalived 使用基础案例 (二)

keepalived 使用 [rootmaster ~]# cat /etc/keepalived/keepalived.conf ! Configuration File for keepalivedglobal_defs { //全局配置notification_email { //定义报警收件人邮件地址acassenfirewall.locfailoverfirewall.locsysadminfirewall.loc}notification_…

ECMAScript基础入门:从语法到应用

在此之前我以及发布过关于JavaScript基础知识点大家也可以参考 大家有关于JavaScript知识点不知道可以去 🎉博客主页:阿猫的故乡 🎉系列专栏:JavaScript专题栏 🎉ajax专栏:ajax知识点 🎉欢迎关注…

redis常见数据类型

目录 1.基本全局命令 2.数据结构和内部编码 3.单线程架构 1.基本全局命令 Redis有5种数据结构,但它们都是键值对种的值,对于键来说有一些通用的命令。 KEYS 返回所有满足样式(pattern) 的key。支持如下统配样式。 h?llo 匹配 hello, hallo和hxllo h*llo匹配h…

机场信息集成系统系列介绍(6):机场协同决策支持系统ACDM

目录 一、背景介绍 1、机场协同决策支持系统是什么? 2、发展历程 3、机场协同决策参与方 4、相关定义 二、机场协同决策ACDM的建设目标 (一)机场协同决策支持系统的宏观目标 1、实现运行数据共享和前序航班信息透明化 2、实现地面资源…

Linux常用基本命令(三)

一、显示命令 1. cat 通式:cat 选项 文件名 只能看普通的文本文件 缺点:如果内容过多会显示不全 选项效果-n显示行号包括空行-b跳过空白行编号-s讲所有的连续的多个空行替换为一个空行(压缩成一个空行)-A显示隐藏字符 三个标准文件…

十四、W5100S/W5500+RP2040之MicroPython开发<MQTTThingSpeak示例>

文章目录 1. 前言2. 平台操作流程3. WIZnet以太网芯片4. 示例讲解以及使用4.1 程序流程图4.2 测试准备4.3 连接方式4.4 相关代码4.5 烧录验证 5. 注意事项6. 相关链接 1. 前言 在这个智能硬件和物联网时代,MicroPython和树莓派PICO正以其独特的优势引领着嵌入式开发…

使用PE信息查看工具和Dependency Walker工具排查因为库版本不对导致程序启动报错问题

目录 1、问题说明 2、问题分析思路 3、问题分析过程 3.1、使用Dependency Walker打开软件主程序,查看库与库的依赖关系,查看出问题的库 3.2、使用PE工具查看dll库的时间戳 3.3、解决办法 4、最后 VC常用功能开发汇总(专栏文章列表&…

【数据结构】线性表

一.线性表 1.定义: n个同类型数据元素的有限序列,记为 L为表名,i为数据元素在线性表中的位序,n为线性表的表长,n0时称为空表。 2.数据元素之间的关系: 直接前驱和直接后继 3.抽象数据类型线性表的定义…

PADS Layout安全间距检查报错

问题: 在Pads Layout完成layout后,进行工具-验证设计安全间距检查时,差分对BAK_FIXCLK_100M_P / BAK_FIXCLK_100M_N的安全间距检查报错,最小为3.94mil,但是应该大于等于5mil;如下两张图: 检查&…

SpringBoot的配置高级

🙈作者简介:练习时长两年半的Java up主 🙉个人主页:程序员老茶 🙊 ps:点赞👍是免费的,却可以让写博客的作者开心好久好久😎 📚系列专栏:Java全栈,…

【JMeter】使用内网负载机(Linux)执行JMeter性能测试

一、背景 ​ 在我们工作中有时候会需要使用客户提供的内网负载机进行性能测试,一般在什么情况下我们需要要求客户提供内网负载机进行性能测试呢? 遇到公网环境下性能测试达到了带宽瓶颈。那么这时,我们就需要考虑在内网环境负载机下来执行我们…

使用C语言将ASCII明文编码为GSM短信体格式

一、背景介绍 GSM(Global System for Mobile Communications)是全球移动通信系统的简称,而GSM 03.38是GSM系统中用于短信编码的标准。GSM 03.38字符集采用7-bit编码,与ASCII的8-bit编码有所不同。为了将ASCII编码的文本转换为GSM…

【JavaWeb学习笔记】13 - JSP浏览器渲染技术

项目代码 https://github.com/yinhai1114/JavaWeb_LearningCode/tree/main/jsp JSP 一、JSP引入 1.JSP现状 1.目前主流的技术是前后端分离(比如: Spring Boot Vue/React),我们会讲的.[看一下] 2. JSP技术使用在逐渐减少,但使用少和没有使用是两个意思&#xff…

DB207S-ASEMI迷你贴片整流桥DB207S

编辑:ll DB207S-ASEMI迷你贴片整流桥DB207S 型号:DB207S 品牌:ASEMI 封装:DBS-4 最大平均正向电流:2A 最大重复峰值反向电压:1000V 产品引线数量:4 产品内部芯片个数:4 产品…

Spring security之授权

前言 本篇为大家带来Spring security的授权,首先要理解一些概念,有关于:权限、角色、安全上下文、访问控制表达式、方法级安全性、访问决策管理器 一.授权的基本介绍 Spring Security 中的授权分为两种类型: 基于角色的授权&…

2024最新苹果手机APP软件下架了,怎么安装?

如果你是一个iPhone用户,你可能会遇到这样的情况:你想下载或更新一个软件,但发现它已经从APP Store上消失了。这可能是因为软件违反了苹果的规则,或者开发者主动撤下了软件。那么,这种情况下,你还能安装或使…

OpenCV | 霍夫变换:以车道线检测为例

霍夫变换 霍夫变换只能灰度图,彩色图会报错 lines cv2.HoughLinesP(edge_img,1,np.pi/180,15,minLineLength40,maxLineGap20) 参数1:要检测的图片矩阵参数2:距离r的精度,值越大,考虑越多的线参数3:距离…

Unreal5.3 PCG 笔记

目录 ElectricDreams场景功能移动中间山体向周围随机生成倒下的树干树干上随机生成的植被 ElectricDreams场景功能 移动中间山体向周围随机生成倒下的树干 配置内容 中心山体Spline周围沟渠Spline(土堆)PCG规则 主要功能节点 SplineSample(…