MySQL(四)事务原理及分析

MySQL系列文章

MySQL(一)基本架构、SQL语句操作、试图
MySQL(二)索引原理以及优化
MySQL(三)SQL优化、Buffer pool、Change buffer
MySQL(四)事务原理及分析
MySQL(五)缓存策略
MySQL(六)主从复制
数据库三范式


文章目录

  • MySQL系列文章
  • 前言
  • ACID特性
    • 原子性(A)
    • 隔离性(I)
    • 持久性(D)
    • 一致性(C)
  • 隔离级别
    • READ UNCOMMITTED
    • READ COMMITTED
    • REPEATABLE READ
    • SERIALIZABLE
  • 共享锁&排他锁
  • MVCC
    • read view
    • redo
    • undo


前言

背景:之前提到MySQL可以并发操作,即多个MySQL客户端操作一个服务端中的数据库,因此涉及到并发访问的问题,所以就有事务的概念。


定义:事务的本质是并发控制的单元,是用户定义一系列数据库操作的集合。这些操作要么都做,要么都不做,是一个不可分割的工作单位。


组成:事务可由一条非常简单的 SQL 语句组成,也可以由一组复杂的 SQL 语句组成;MySQL innodb 下,单条语句都具备事务;可以通过 autocommit = 0; 设置当前会话手动提交;

事务具有ACID特性,即原子性、一致性、隔离性和持久性。

ACID特性

原子性(A)

事务操作要么都做(提交),要么都不做(回滚);事务是访问并更新数据库各种数据项的一个程序执行单元,是不可分割的工作单位;通过 undolog 来实现回滚操作。undolog 记录的是事务每步具体操作,当回滚时,回放事务具体操作的逆运算;
事务包含的全部操作是一个不可分割的整体,要么全部执行,要么全部不执行;

虽然说事务要保持原子性,例如完整的串行执行就可以保证事务中指令执行的原子性;但是这种方式的性能是非常低的,因此Mysql通常会通过事务与事务之间指令的交叉执行来提高性能。

隔离性(I)

描述:各个事务之间互相影响的程度;防止多个并发事务交叉执行导致的数据不一致,通过锁和MVCC实现。
目的:主要规定多个事务访问同一数据资源,各个事务对该数据资源访问的行为,不同的隔离性是应对不同的现象(脏读、不可重复读、幻读)
事务的隔离性要求每个读写事务的对象对其他事务的操作对象能相互分离,并发事务之间不会相互影响,设定了不同程度的隔离级别,通过适度破环一致性,得以提高性能;通过 MVCC 和 锁来实现;MVCC 是多版本并发控制,主要解决一致性非锁定读,通过记录和获取行版本,而不是使用锁来限制读操作,从而实现高效并发读性能。锁用来处理并发 DML 操作;数据库中提供粒度锁的策略,针对表(聚集索引 B+ 树)、页(聚集索引 B+ 树叶子节点)、行(叶子节点当中某一段记录行)三种粒度加锁;

持久性(D)

事务一旦完成,要将数据所做的变更记录下来,包括数据存储和多副本的网络备份;
事务提交后,事务 增删改操作将会持久化(写入 redolog 磁盘文件 哪一个页 页偏移值 具体数据);即使发生宕机等故障,数据库也能将数据恢复。redolog 记录的是物理日志;

一致性(C)

事务的前后,所有的数据都保持一个一致的状态,不能违反数据的一致性检测(完整性约束检查);
一致性指事务将数据库从一种一致性状态转变为下一种一致性的状态,在事务执行前后,数据库完整性约束没有被破坏;一个事务单元需要提交之后才会被其他事务可见。例如:一个表的姓名是唯一键,如果一个事务对姓名进行修改,但是在事务提交或事务回滚后,表中的姓名变得不唯一了,这样就破坏了一致性;一致性由原子性、隔离性以及持久性共同来维护的。

隔离级别

在多个事务并发执行时,需要考虑隔离级别,即不同的隔离性。ISO 和 ANIS SQL 标准制定了四种事务隔离级别的标准,隔离级别越高,性能越低
READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ、SERIALIZABLE前三种的隔离级别会导致不同的并发读异常,即脏读、不可重复读、幻读场景。


不同的隔离级别产生的不同的并发读异常情况:
脏读:一个事务读到另一个未提交事务修改的数据;
不可重复读:一个事务两次读取同一个数据不一样;
幻读:一个事务内两次读到同一范围内的记录得到的结果集不一样;

区别
脏读和不可重复读的区别在于,脏读是读取了另一个事务未提交的数据,而不可重复读是读取了另一个事务提交之后的修改;本质上都是其他事务的修改影响了本事务的读取;
不可重复读和幻读比较类似;不可重复读是两次读取同一条记录,得到不一样的结果;而幻读是两次读取同一个范围内的记录得到的结果集不一样(可能不同个数,也可能相同个数内容不一样,比如x一行后又添加新行);不可重复读是因为其他事务进行了 update 操作,幻读是因为其他事务进行了 insert或者 delete 操作。


MySQL innodb默认支持的隔离级别是 REPEATABLE READ;

READ UNCOMMITTED

读未提交;该级别下读操作不加锁,写操作加排他锁,写锁在事务提交或回滚后释放锁;所以可能会读到事务回滚前的数据,会产生脏读。

READ COMMITTED

读已提交(RC);该隔离级别下读取历史版本的最新数据,所以读取的是已提交的数据;会产生不可重复读的现象。

REPEATABLE READ

可重复读(RR);此时读取操作读取事务开始时的版本数据;会产生幻读的现象。可以用当前读,即给读加锁来解决幻读现象。

SERIALIZABLE

可串行化;该级别下给读加了共享锁;所以事务都是串行化的执行;此时隔离级别最严苛;

共享锁&排他锁

为了解决并发读异常问题,数据库引入了锁机制。锁分为共享锁和排他锁,共享锁允许多个事务同时读取同一份数据,但不能进行修改;排他锁则只允许一个事务修改数据。

MVCC

MVCC是一种多版本并发控制技术,可以通过不加锁的情况下用于解决并发读异常和幻读问题。MVCC通过为每个事务创建一个独立的版本来实现隔离性,每个版本都包含该事务执行时所见到的所有数据。当多个事务同时访问同一份数据时,系统会根据每个事务的版本号来判断是否允许访问。

多版本主要依赖Undo-log日志来实现,而并发控制则通过表的隐藏字段+ReadView快照来实现

详细内容参考:https://maimai.cn/article/detail?fid=1760762705&efid=UVf-Pw63L4lRkESvTUv1AQ

read view

在 read committed 和 read repeatable 隔离级别下,MVCC 采用 read view 来实现的,它们的区别在于创建 read view 时机不同:

read committed 隔离级别会在事务中每个 select 都会生成一个新的 read view,也意味着在同一个事务多次读取同一条数据可能出现数据不一致;存在不可重复读情况。因为在多次读取期间可能有其他事务修改了该条记录,并提交了;
read repeatable 隔离级别是启动事务时生成一个 read view,在整个事务读取数据才使用这个 read view,这样保证了在事务期间读到的数据都是事务启动前的记录,解决了不可重复读。

redo

redo 日志用来实现事务的持久性;内存中包含 redo log buffer,磁盘中包含 redo log file;
当事务提交时,必须先将该事务的所有日志写入到重做日志文件进行持久化,待事务的commit 操作完成才完成了事务的提交;
redo log 顺序写,记录的是对每个页的修改(页、页偏移量、以及修改的内容);在数据库运行时不需要对 redo log 的文件进行读取操作;只有发生宕机的时候,才会拿redo log 进行恢复;

undo

undo 日志用来帮助事务回滚以及 MVCC 的功能;存储在共享表空间中;undo 是逻辑日志,回滚时将数据库逻辑地恢复到原来的样子,根据 undo log 的记录,做之前的逆运算;比如事务中有 insert 操作,那么执行 delete 操作;对于 update 操作执行相反的 update 操作;
同时 undo 日志记录行的版本信息,用于处理 MVCC 功能;

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

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

相关文章

Netty网络编程

参考文档 https://zhuanlan.zhihu.com/p/550956053 https://zhuanlan.zhihu.com/p/514448867 BIO 读取数据有两个阶段 等待数据就绪,数据到达内核缓冲区读取数据(系统调用),从内核缓冲区,拷贝至用户缓冲区 BIO两个阶段都会阻塞 BIO编程时&…

分布式数据库HBase,它到底是怎么组成的?

原文链接:http://www.ibearzmblog.com/#/technology/info?id3f432a2451f5f9cb9a14d6e756036b67 前言 大数据的核心问题无非就是存储和计算这两个。Hadoop中的HDFS解决了数据存储的问题,而HBase就是在HDFS上构建,因此Hbase既能解决大数据存…

青岛大学_王卓老师【数据结构与算法】Week05_11_栈与递归_学习笔记

本文是个人学习笔记,素材来自青岛大学王卓老师的教学视频。 一方面用于学习记录与分享, 另一方面是想让更多的人看到这么好的《数据结构与算法》的学习视频。 如有侵权,请留言作删文处理。 课程视频链接: 数据结构与算法基础…

[sqoop]导入数据

一、覆盖导入 例如维度表,每次导入的数据需要覆盖上次导入的数据。 hive-overwrite参数:实现覆盖导入 hive-import参数:表示向hive表导入 hive-table参数:指定目标hive库表 sqoop import \ --connect jdbc:mysql://hadoop1:3…

哈希表的原理

哈希概念 线性表、树结构的查找方式都是以关键字的比较为基础,查找效率比较低,顺序表的时间复杂度是O(n),平衡树中为树的高度,即O(logn),搜素的效率取决于搜索过程的元素…

Spring-Interceptor拦截器

使用步骤 申明拦截器bean,并实现HandlerInterceptor接口 true为放行,false为拦截 2.定义配置类,继承WebMvcConfigurationSupport,实现addInterceptors方法,该方法调用具体的拦截器进行拦截 也可以在配子类通过实现W…

【Elasticsearch】DSL查询文档

目录 1.DSL查询文档 1.1.DSL查询分类 1.2.全文检索查询 1.2.1.使用场景 1.2.2.基本语法 1.2.3.示例 1.2.4.总结 1.3.精准查询 1.3.1.term查询 1.3.2.range查询 1.3.3.总结 1.4.地理坐标查询 1.4.1.矩形范围查询 1.4.2.附近查询 1.5.复合查询 1.5.1.相关性算分 …

Set与Map的使用 + 二叉搜索树与哈希桶的大白话讲解和图解+完整代码实现(详细注释)

文章目录 前言一、Set与Map概念及场景模型纯Key模型Key-Value模型 Map 的使用Set 的使用 二、二叉搜索树什么是二叉搜索树代码实现二叉搜索树查找操作插入操作删除操作(难点)cur这个节点没有左子树(cur.left null)cur这个节点没有右子树(cur.right null)cur这个节点没有左右子…

PyTorch深度学习实战(5)——计算机视觉

PyTorch深度学习实战(5)——计算机视觉 0. 前言1. 图像表示2. 将图像转换为结构化数组2.1 灰度图像表示2.2 彩色图像表示 3 利用神经网络进行图像分析的优势小结系列链接 0. 前言 计算机视觉是指通过计算机系统对图像和视频进行处理和分析,利…

记录两次问题排查过程

一、引入了一个第三方的jar包提供的能力,需要把三个官方的jar(transmittable、aspectJ等)引入项目,我放在了resource目录下,新建了一个lib。启动时对三个jar执行-javaagent命令。之前都没问题。同时该项目的测试和预发…

搜索旋转有序数组和处理重复元素的解题思路及代码(二分查找)

文章目录 介绍:目录:搜索旋转有序数组问题:题目描述:解题思路:解决方法:示例代码: 处理重复元素的搜索旋转有序数组问题:题目描述:解题思路:解决方法 结论&am…

【Python】正则表达式语法入门

目录 正则表达式 1、点:匹配所有字符 2、星号:重复匹配任意次 3、加号:重复匹配多次 4、花括号:匹配指定次数 5、贪婪模式和非贪婪模式 6、反斜杠:对元字符的转义 7、方括号:匹配几个字符之一 8、…

异地使用PLSQL远程连接访问Oracle数据库【内网穿透】

文章目录 前言1. 数据库搭建2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射 3. 公网远程访问4. 配置固定TCP端口地址4.1 保留一个固定的公网TCP端口地址4.2 配置固定公网TCP端口地址4.3 测试使用固定TCP端口地址远程Oracle 转载自cpolar极点云文章:公网远程连接…

cjson的内存泄漏案例

1、当我们使用下面这些创建json对象时,需要用cJSON_Delete();释放,(当然,释放父JSON对象后,子JSON对象也会被释放) 2、多次释放同一内存空间 在recv_write_property函数中的data,在Equipment_re…

Html基础知识学习——兼容问题与解决方法(十六)

文章目录 1.计算一定要精确,不要让内容的宽高超出我们设置的宽高,在IE6下内容会撑开设置好的宽高2.元素浮动,宽度需要内容撑开,就给里面的块元素都加浮动3.在ie6.ie7下元素要浮动并在同一行 就给这些元素都加浮动4.注意标签嵌套规…

【玩转Linux操作】Linux进程(进程基本介绍,父子进程,终止进程,进程树)

🎊专栏【玩转Linux操作】 🍔喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。 🎆音乐分享【Counting Stars 】 欢迎并且感谢大家指出小吉的问题🥰 文章目录 🍔进程的基本介绍🍔显示系统执行的进程⭐…

微服务 云原生:K8S 核心组件

参考 Kubernetes 官方文档,简要概述 Kubernetes 中的核心组件用途及部分原理。 一个 K8S 集群,可以分为两个部分: 控制平面(Control Plane)。它是一套管理系统,专门来管理集群节点和服务,为集群做出全局决策&#xff…

使用 @Autowired 为什么会被 IDEA 警告,应该怎么修改最佳?

# 问题原因 关于这个问题,其实答案相对统一,实际上用大白话说起来也容易理解。 1.初始化问题 先看一下Java初始化类的顺序:父类的静态字段 > 父类静态代码块 > 子类静态字段 > 子类静态代码块 > 父类成员变量 > 父类构造代码块…

Linux系统使用(超详细)

目录 Linux操作系统简介 Linux和windows区别 Linux常见命令 Linux目录结构 Linux命令提示符 常用命令 ls cd pwd touch cat echo mkdir rm cp mv vim vim的基本使用 grep netstat Linux面试题 Linux操作系统简介 Linux操作系统是和windows操作系统是并列…

数组与指针

博客内容:数组与指针 文章目录 一、 数组?指针?1.区别与联系大小赋值存储位置 二、指针数组、数组指针?二维数组和二级指针&数组名与数组的区别总结 一、 数组?指针? 数组 相同类型数据的集合 指针 指…