MySQL-事务、日志

news2024/12/25 14:48:32

事务

特性

原子性

是指事务开始后,必须成功执行完所有的操作才会结束,否则会回滚到事务刚开始前。

拿转账来说,一个成功的 A向B转账100元的过程 会涉及如下过程:

A:从数据库读取A的余额;A的余额-100;将A修改后的余额更新到数据库里

B:从数据库读取B的余额;B的余额+100;将B修改后的余额更新到数据库里

 若这个步骤任何一个没有执行成功,A向B转账100就无法成功,A的余额与B的余额都不会变化。

一致性

是指事务操作前后,数据库保持一致状态。

比如,用户A和用户B的账户分别有800元和600元,总共1400,用户A向用户B转账100元,分为两个步骤,从A账户扣除100元,B账户增加100元。一致性要求转账操作完成后,两个人账户总额依然是1400。

拿 A向B转账100元来说,执行完后,A的余额会减100,B的余额会加100,不会出现A的余额不变化等错误。

持久性

事务的改变是持久的,事务处理结束后,对数据的修改时永久的,即便系统故障也不会丢失。

隔离性

数据库允许多个并发事务同时对其数据进行读写和修改,隔离性很好的防止了多个事务并发执行而导致数据不一致的情况。每个事务都有一个完整的数据空间,对其他并发事务是隔离的,不会相互干扰;一个事务对另一个事务是否可见以及可见的程度。

购买商品来举例,消费者购买商品这个事务,是不影响其他消费者购买的。

并行事务回引发哪些问题

脏读

如果一个 事务 读到 另一个未提交事务 修改过的数据,就意味着发生脏读现象。

举例:如果一个B事务读到了另一个 未提交的A事务 修改过的数据,会发生脏读现象,因为A事务还未提交,随时可能发生回滚操作,那么B事务刚才读到的数据就是过期的数据。

不可重复读:

一个事务内多次读取同一个数据,会出现前后两次读到的数据不一样的情况,就意味着发生了不可重复读现象。

举例:事务A从数据库中读取余额,读到的数据是100,然后继续执行代码逻辑,此时,B更新了余额(设置余额为200),并提交了事务,那么当A事务再次读取数据时,就会发现前后两次读到的数据不一致,这种现象被称为不可重复读。

幻读

在一个事务内,多次查询某个符合查询条件的记录数量,如果出现前后两次查询的记录数量不一样的情况,就意味着发生了幻读现象。

举例:事务B在查询账户余额大于100元的账户数量,查询到5条记录,接下来,事务A插入了一条余额超过100元的账户,并提交了事务,此时数据库超过100的账户数量为6,然后B事务再次查询账户余额大于100元的记录,此时查到的记录数量为6,发现和前一次读到的记录数量不一样,就感觉发生了幻觉,这种现象被称为幻读。

事务隔离

当多个事务并发执行肯可能会遇到脏读、不可重复读、幻读现象,如何规避呢?

  • 脏读:B事务读到了A事务修改后未提交的数据
  • 不可重复读:同一个事务内,前后读取的数据不一致
  • 幻读:事务读取数据库中的前后记录数量不一样

解决脏读              :用读已提交、可重复读、串行化;

解决不可重复读   :用可重复读、串行化

解决幻读              :用串行化

四种隔离级别读未提交、串行化、读已提交、可重复读

四种隔离级别是如何实现的

读未提交

定义:指一个事务还没提交时,它做的变更就被其他事务看到;

实现:因为可以读到未提交事务的修改,所以直接读取最新的数据;

可能发生"脏读、不可重复读、幻读"问题:
  • 脏读:B事务读到了A事务修改后未提交的数据
  • 不可重复读:同一个事务内,前后读取的数据不一致
  • 幻读:事务读取数据库中的前后记录数量不一样
产生问题举例——读未提交产生脏读

上图中,事务A与事务B开启后,事务B将name改为“关羽”,事务未提交,但是如果事务A读到了name为“关羽”,而sessionB未提交随时可能发生回滚,那么事务A相当于读到了一个不存在的数据,即脏读。读到了一条数据。

串行化

定义:会对事务加上读写锁,在多个事务对这条记录进行读写操作时,如果发生了读写冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行;

实现:通过加读写锁的方式来避免并行访问;

读已提交

定义:指一个事务提交后,它做的变更才能被其他事务看到;

实现:通过Read View实现,是在每个语句执行前都会重新生成Read View;同一个事务中两次相同的读取操作可能会看到不同的数据,因为其他事务可能在两次读取之间提交了数据。

过程:

  1. 去找除本身事务之外的其他活跃的事务ID(read view)
  2. 遍历undo log

 Read View:

确定哪些版本的数据对当前事务可见,维护了除本身事务之外的其他活跃的事务ID,看到的是未提交(活跃)的事务;

  • 事务ID列表:包括了在创建 read view 时,所有未提交的事务ID
  • 最小事务ID:在创建 read view 时,系统中已经提交的最小事务ID。这个ID之前的所有事务的修改对当前事务都是可见的。
  • 当前事务ID:创建 read view 的事务的ID。
可能发生不可重复读和幻读的问题:
  • 不可重复读:同一个事务内,前后读取的数据不一致
  • 幻读:事务读取数据库中的前后记录数量不一样
 产生问题举例——读已提交产生不可重复读

在图,SessionA启动后,Session第一次读到name值是“刘备”;SesssionB自动启动后,修改name为“关羽”,并自动提交了事务,SessionA第二次读到name值是“关羽”,两次读到的数据不一样,发生了不可重复读;SessionB再次更新name,为“张飞”,并自动提交了事务,SessionA第三次读到的name值为“张飞”,对于同一个name,SessionA三次读到的值都不一样,发生了不可重复读问题。

 产生问题举例——读已提交产生幻读

 在图中,SessionA启动后,查到了name为“刘备”的记录,之后SessionB插入了name为“曹操”的记录,并自动提交了事务,session再次查找记录,在与第一次相同的条件(number>0)下,读到了name为“刘备”和“曹操”两条记录。

可重复读

定义:指一个事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的;

实现:启动事务时生成一个Read View,然后整个事务期间都在用这个Read View,之后读取操作都会使用这个read view,保证了在同一个事务中多次读取同一数据时,看到相同的数据版本。

过程:

  1. 去找除本身事务之外的其他活跃的事务ID(read view)
  2. 遍历undo log

 Read View

确定哪些版本的数据对当前事务可见,维护了除本身事务之外的其他活跃的事务ID,看到的是未提交(活跃)的事务;

  • 事务ID列表:包括了在创建 read view 时,所有未提交的事务ID
  • 最小事务ID:在创建 read view 时,系统中已经提交的最小事务ID。这个ID之前的所有事务的修改对当前事务都是可见的。
  • 当前事务ID:创建 read view 的事务的ID。
可能发生“幻读”问题:
  • 幻读:事务读取数据库中的前后记录数量不一样
 Read View

确定哪些版本的数据对当前事务可见,维护了除本身事务之外的其他活跃的事务ID,看到的是未提交(活跃)的事务;

  • 事务ID列表:包括了在创建 read view 时,所有未提交的事务ID
  • 最小事务ID:在创建 read view 时,系统中已经提交的最小事务ID。这个ID之前的所有事务的修改对当前事务都是可见的。
  • 当前事务ID:创建 read view 的事务的ID。
可重复读与已提交的工作过程
  1. 去找除本身事务之外的其他活跃的事务ID(read view)
  2. 遍历undo log

举例

读已提交:每次都重复找

可重复读:延用第一次的

 日志

undo log回滚日志

是innodb存储引擎层生成的日志,实现了事务的原子性,主要用于事务回滚;记录了数据被修改之前的状态,以便在事务回滚或者需要读取旧版本数据时能够恢复到之前的状态;发生回滚时,就读取undo log里的数据,然后做原先相反的操作。

每次操作产生的undo log格式都有roll_pointer指针可以将这些undo log串成一个链表,trx_id知道该记录时被哪个事务修改的。

 插入操作:在插入一条记录时,把这条记录的主键值记到undo log中,这样回滚时只需把这个主键值对应的记录删掉就好。

删除操作:删除一条记录时,要把记录中的内容对记到undo log中,回滚时把由这些内容组成的记录(通过roll_pointer找到之前版本中delete_mask为0的记录)插入到表中就好。

更新操作:在更新一条记录时,把更新列的旧值记到undo log中,回滚时把这些列的更新为旧值(通过roll_pointer找到上一个版本的数据(旧值)就好了。每次修改时,都会生成一个新的undo log记录,并且这个指针会通过roll_pointer指针与之前的undo log记录相连,形成一个版本链,通过roll_pointer找到上一个版本的数据。

redo log重做日志:是innodb存储引擎层生成的日志,实现了事务的持久性,主要用于解决掉电等故障恢复;

binlong归档日志:是server层生成的日志,主要用于数据备份和主从复制

索引的类别

按照实现的数据结构区分

B+树索引

Hash索引

为什么不采用Hash/HashMap这种存储结构而选择B+树呢?

B+树支持按顺序存储和范围查询,而hash结构不支持范围查询,因为Hash是基于Hash函数计算的无序存储结构;B+树的内部节点和叶子节点形成有序链表,这使得在执行顺序访问时非常高效,Hash机构没有内在顺序,无法提供顺序访问性能。

按照约束区分

普通索引

唯一索引(UNIQUE修饰)

MySQL在进行插入操作时,普通索引和唯一索引哪个的效率高?

普通索引更快,因为它不需要唯一性检查。普同索引允许索引键值重复,而唯一索引不允许重复,用唯一索引插入时会检查索引键值是否重复,不重复才插入,若重复则失败。

MySQL在进行查找操作时,普通索引和唯一索引哪个的效率高?

唯一索引更快,保证数据唯一性使得查找的时候索引通过键就能定位符合条件数据行,而普通索引的索引键存在重复,会定位多个数据行,接下来还要遍历数据才能查找到符合条件的数据行。

按照索引列的数量区分

单列索引

联合索引(最左匹配原则)

最左匹配原则是按什么顺序实现的?

从小到大的顺序,如按第一列从小到大的顺序排列,若出现相同的数值,则比较相同数值的下一列,依然是按照从小到大的顺序,后面同理。

联合索引为什么要满足最左匹配原则?

如(A,B,C),从A字段开始匹配才能保证索引的有序性。对于查询,如果跳过A字段直接查询B或C字段,那么这些字段在索引中可能是无序的,从而加速查询过程。

按照存储的内容区分

聚簇索引:B+树的叶子结点存放的是实际数据,索引就是数据,以主键为索引;

非聚簇索引:B+书的叶子结点存放主键值,存储了索引列与主键,除主键外的其他字段为索引;通过非聚簇索引找到了符合条件的数据行,根据存储在索引中的主键,再去访问实际的数据行,这个过程被称为“回表”。

回表:需要检索两颗B+树,先在二级索引的B+树找到对应的叶子结点,获取主键值,然后用获取的主键值在聚簇索引中的B+树检索到对应的叶子结点,然后获取要查询的数据;

索引注意事项

1.ORDER BY子句里使用索引列,但是order by后字段的排序不一致(增减性相反索引失效)就不能使用;

2.为用于搜索、排序或分组的列创建索引;

3.列的区分度大的列创建索引,重复数据多的字段不应设为索引

4.联合索引,区分度大的放在第一位

5.只有索引列在比较表达式中单独出现才可以适用索引

6.为了尽可能少的让聚簇索引发生 页面分裂和记录移位的情况,建议让主键拥有AUTO_INCREMENT属性,让主键自增,防止页分裂(会使插入速度变慢)。

7.尽量使用覆盖索引进行查询,避免回表带来的性能损耗

8.使用IN查询,IN的数量不能太大(<=2000,若大于,则全表扫描就可以),避免mysql走错索引

9.更新频繁的列不应设置索引(索引也需要维护)

索引失效
  • 当我们使用左或者左右模糊匹配的时候,也就是 like %xx 或者 like %xx%这两种方式都会造成索引失效;
  • 当我们在查询条件中对索引列使用函数,就会导致索引失效。
  • 当我们在查询条件中对索引列进行表达式计算,也是无法走索引的。
  • MySQL 在遇到字符串和数字比较的时候,会自动把字符串转为数字,然后再进行比较。如果字符串是索引列,而条件语句中的输入参数是数字的话,那么索引列会发生隐式类型转换,由于隐式类型转换是通过 CAST 函数实现的,等同于对索引列使用了函数,所以就会导致索引失效。
  • 联合索引要能正确使用需要遵循最左匹配原则,也就是按照最左优先的方式进行索引的匹配,否则就会导致索引失效。
  • 在 WHERE 子句中,如果在 OR 前的条件列是索引列,而在 OR 后的条件列不是索引列,那么索引会失效。

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

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

相关文章

速度与质量的碰撞——对抗扩散蒸馏 (ADD) 如何彻底改变图像生成

引言 DigiOps 与人工智能是最新和最令人兴奋的进步之一&#xff0c;它是一种将速度和质量融为一体的图像生成技术。 ADD 的发展经历了几个关键阶段。最初&#xff0c;图像生成方法非常基础&#xff0c;而且经常产生不令人满意的结果。生成对抗网络&#xff08;GAN&#xff09…

[A-04] ARMv8/ARMv9-Cache的相关策略

ver0.3 前言 前面我们已经通过三篇文章反反复复的讲Cache的概念、结构、架构&#xff0c;相信大家对Cache已经大概有了初步的了解。这里简单归纳一下: (1) Cache从硬件视角看&#xff0c;是连接PE-Core和主存的一种存储介质&#xff0c;存储的数据是主存中数据的副本&#xf…

17098 广告牌最佳安放问题

这个问题可以通过动态规划来解决。我们可以定义一个数组d&#xff0c;其中d[i]表示到第i个广告牌地点时可以选择放置广告牌的最大效益值。然后我们可以通过遍历所有可能的j&#xff08;1 < j < i && x[i] - x[j] > 5&#xff09;&#xff0c;然后更新d[i]为ma…

Ubuntu22 Qt6.6 ROS 环境搭建

Ubuntu22.04; Qt6.6; Qt Creator 13.01; ROS2 1. 安装 Qt ROS 插件 1.下载地址&#xff1a; https://github.com/ros-industrial/ros_qtc_plugin/releases 选择对应 Qt Creator 版本的安装包。 2. Qt Creator中&#xff0c;“Help - 关于插件”–>“install Plugin…

十五、C++11常用新特性—Lambda表达式

1.基本 这个好像是很好用的&#xff0c;其有以下有点&#xff1a; 声明式的编程风格&#xff1a;直接匿名定义目标函数或函数对象&#xff0c;不需要额外写一个命名函数或函数对象。简洁&#xff1a;避免了代码膨胀和功能分散&#xff0c;让开发更加高效。在需要的时间和地点…

AI算法17-贝叶斯岭回归算法Bayesian Ridge Regression | BRR

贝叶斯岭回归算法简介 贝叶斯岭回归&#xff08;Bayesian Ridge Regression&#xff09;是一种回归分析方法&#xff0c;它结合了岭回归&#xff08;Ridge Regression&#xff09;的正则化特性和贝叶斯统计的推断能力。这种方法在处理具有大量特征的数据集时特别有用&#xff…

SIP消息结构详解

SIP协议的消息由三部分构成&#xff0c;分别是起始行&#xff08;请求行状态行)、消息头和消息体&#xff08;正文&#xff09; 一&#xff0e;起始行 1. 请求消息起始行 起始行&#xff1a;由方法名、请求URI和协议版本组成&#xff0c;自身内部用逗号分割&#xff0c;三者之…

​小语种AI翻译技术新成果,传音荣获WMT 2024国际机器翻译大赛三项冠军

近日,由国际计算语言学协会(The Association for Computational Linguistics,ACL)举办的WMT 2024国际机器翻译比赛结果揭晓。传音TEX AI中心翻译团队在小语种领域再获佳绩,斩获三项翻译赛道的机器自动评测冠军,一项亚军。 WMT(Conference on Machine Translation)大赛是机器翻译…

每日一练 - IEEE 802.1Q中STP协议

01 真题题目 关于设备 SWC 的上述配置说法正确的是 (多选) A.SWC 为根交换机 B.stp instance 1 priority 4096 是配置交换机在实例 1 中的优先级为 4096&#xff0c; 该优先级默认为0 C.gtp edged-port enable 该命令是启用交换机 5WC 的 Ethernet 1/0/2 为边缘端口 D.sto …

手把手教你,如何利用积木易搭3D扫描仪完成文物三维建模?

当前&#xff0c;文物三维建模主要技术手段主要有摄影测量技术、三维激光扫描技术、结构光扫描技术。其中&#xff0c;积木易搭的MagicScan作为一款先进的3D扫描仪&#xff0c;是正是运用了结构光扫描技术的精髓&#xff0c;它巧妙地融合了点云相机的高精度空间数据采集能力、纹…

解析DDD开发框架Axon

在微服务架构盛行的当下&#xff0c;领域驱动设计&#xff08;DDD&#xff09;也得到了崭新的发展。在DDD中包含了聚合、领域事件等核心概念&#xff0c;也需要引入CQRS、事件溯源等架构模式。对于开发人员而言&#xff0c;如何简单而高效的实现这些核心概念和架构模式是一大痛…

C++11之constexpr

注&#xff1a;大前提&#xff0c;本篇文章是在介绍C11中的constexpr&#xff0c;自C14以来constexpr有了非常大的改动&#xff0c;如在实验中遇见与本文不符的地方还先请查阅其他资料&#xff0c;确定为本文错误后可留言&#xff0c;我会虚心接受并改正。 constexpr定义编译…

惠海H5112A降压恒流芯片IC 60V72V80V100V转24V36V48V多路共阳输出景观LED点光源

H5112A是一款外围电路简单的多功能平均电流型LED恒流驱动器&#xff0c;适用于5-90V电压范围的非隔离式大功率恒流LED驱动领域。芯片采用了平均电流模式控制&#xff0c;输出电流精度在士3%;输出电流对输入输出电压以及电感不敏感;芯片内部集成了环路补偿&#xff0c;外围电路更…

学习测试9-接口测试 2-抓包工具Fiddler

Fiddler 抓包工具的使用 怎么找接口信息&#xff0c;可以通过浏览器的开发者工具 Fiddler 是一个 HTTP 协议调试代理工具 File 菜单&#xff1a; Capture Traffic&#xff08;或 F12&#xff09;&#xff1a;是个开关&#xff0c;可以控制是否把 Fiddler 注册为系统代理。当把…

Mac系统能装虚拟机吗 Mac装双系统虚拟机详细教程 macos可以用虚拟机装windows吗

随着科技的进步和用户需求的多样化&#xff0c;越来越多的用户希望在一台设备上运行多个操作系统。特别是对于Mac用户来说&#xff0c;安装虚拟机或者双系统已成为常见需求。这不仅可以满足用户在不同操作系统工作的需求&#xff0c;也可以让开发人员在不同的操作系统上进行测试…

【题目/训练】二叉树的创建遍历(递归非递归)

一、根据二叉树创建字符串 思路&#xff1a;在正常前序递归遍历的基础上&#xff0c;单独加上一个考虑到右子树为空的情况&#xff0c;如下&#xff1a;其结果为 1&#xff08;2&#xff08;4&#xff08;5&#xff09;&#xff08;6&#xff09;&#xff09;&#xff09;&…

财伯乐伯乐遇马税务师事务所品牌发布会圆满落幕!

7月14日 &#xff0c;由财伯乐主办&#xff0c;伯乐遇马集团、HRS卓玥学社联合主办的财伯乐&伯乐遇马税务师事务所品牌发布会在上海闵行区隆重召开。这场盛会不仅标志着财伯乐品牌的正式亮相&#xff0c;更预示着企业服务领域的一次创新和突破。来自行业的领袖、合作伙伴共…

React+TS前台项目实战(二十九)-- 首页构建之性能优化实现首页Echarts模块数据渲染

文章目录 前言Echart模块源码功能分析数据渲染一、HashRateEchart统计图1. 功能分析2. 代码详细注释 二、BlockTimeChart统计图1. 功能分析2. 代码详细注释 三、使用方式四. 数据渲染后效果如下 总结 前言 还记得之前我们创建的 高性能可配置Echarts组件 吗&#xff1f;今天我…

【刷题汇总 -- 乒乓球筐、组队竞赛、删除相邻数字的最大分数】

C日常刷题积累 今日刷题汇总 - day0141、乒乓球筐1.1、题目1.2、思路1.3、程序实现 2、组队竞赛2.1、题目2.2、思路2.3、程序实现 3、删除相邻数字的最大分数3.1、题目3.2、思路3.3、程序实现 -- dphash 4、题目链接 今日刷题汇总 - day014 1、乒乓球筐 1.1、题目 1.2、思路 …

RflySim工具链常见问题解答

7月10日&#xff0c;卓翼飞思实验室暑期公益培训首场直播圆满落幕&#xff0c;共吸引2400余名学员参与。本期直播培训以“RflySim-智能无人集群系统快速开发与验证工具链”为主题&#xff0c;对RflySim工具链的功能和资源框架进行了全面详细的介绍。本文将针对使用RflySim工具链…