MySQL-事务、日志

事务

特性

原子性

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

拿转账来说,一个成功的 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.mfbz.cn/a/802242.html

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

相关文章

Pytorch学习笔记day1—— 安装教程

这里写自定义目录标题 Pytorch安装方式 工作需要&#xff0c;最近开始搞一点AI的事情。但是这个国产的AI框架&#xff0c;实话说对初学者不太友好 https://www.mindspore.cn/ 比如说它不支持win下的CUDA&#xff0c;可是我手里只有3070Ti和4060也不太可能自己去买昇腾就有点绷不…

C. Alternating Subsequence[双指针,贪心]

题目描述&#xff1a; 思路分析&#xff1a;题目俩要求&#xff0c;最长&#xff0c;值最大&#xff0c;异号&#xff0c;保证异号的情况是找到最长而且尽可能大&#xff0c;其实很容易想到&#xff0c;一开始先把第一个数单独放进去&#xff0c;保证不浪费任何一个元素&#…

迈克尔的44岁:时间的感悟与人生的智慧

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

【JavaEE】HTTP(2)

&#x1f921;&#x1f921;&#x1f921;个人主页&#x1f921;&#x1f921;&#x1f921; &#x1f921;&#x1f921;&#x1f921;JavaEE专栏&#x1f921;&#x1f921;&#x1f921; &#x1f921;&#x1f921;&#x1f921;下一篇文章&#xff1a;【JavaEE】HTTP协议(…

短链接day8

短链接监控 开发访问单个短链接监控统计功能 不知道是哪里复制错了&#xff0c;反正就是一顿报错&#xff0c;改了这个又改那个&#xff0c;还是报错。。暂时不管了。 记录短链接访问日志 logdo新增networt、device、local属性。 分页查询短链接访问日志 分页查询短链接今…

Qt 多语言

记录Qt多语言的实现过程 目录 1.项目配置文件.pro配置 2.程序中的字符串用tr()封装 3.生成翻译文件 4.使用Qt语言家修改翻译文件 4.1使用Qt语言家打开 4.2 .更改文件配置 5. 生成qm文件 6.代码执行切换语言 6.1入口处 6.2 事件执行 0.效果 1.项目配置文件.pro配置 T…

集合媒体管理、分类、搜索于一体的开源利器:Stash

Stash&#xff1a;强大的媒体管理工具&#xff0c;让您的影音生活井井有条- 精选真开源&#xff0c;释放新价值。 概览 Stash是一个专为个人媒体管理而设计的开源工具&#xff0c;基于 Go 编写&#xff0c;支持自部署。它以用户友好的界面和强大的功能&#xff0c;满足了现代用…

2024华为数通HCIP-datacom最新题库(变题更新⑥)

请注意&#xff0c;华为HCIP-Datacom考试831已变题 请注意&#xff0c;华为HCIP-Datacom考试831已变题 请注意&#xff0c;华为HCIP-Datacom考试831已变题 近期打算考HCIP的朋友注意了&#xff0c;如果你准备去考试&#xff0c;还是用的之前的题库&#xff0c;切记暂缓。 1、…

ModuleNotFoundError: No module named ‘_cffi_backend‘的二中情况解决方案

1、问题概述? 创作时间:2024年7月 在pycharm中执行python脚本出现如下问题: No module named _cffi_backend 主要说明二中情况: 第一种原因:最常见的原因就是没有安装cffi模块,我们通过命令安装就可以了。 第二种原因:不常见的原因,如果你在pycharm中运行了别人的…

【UE5.1】NPC人工智能——02 NPC移动到指定位置

效果 步骤 1. 新建一个蓝图&#xff0c;父类选择“AI控制器” 这里命名为“BP_NPC_AIController”&#xff0c;表示专门用于控制NPC的AI控制器 2. 找到我们之前创建的所有NPC的父类“BP_NPC” 打开“BP_NPC”&#xff0c;在类默认值中&#xff0c;将“AI控制器类”一项设置为“…

记录些MySQL题集(8)

ACID原则、事务隔离级别及事务机制原理 一、事务的ACID原则 什么是事务呢&#xff1f;事务通常是由一个或一组SQL组成的&#xff0c;组成一个事务的SQL一般都是一个业务操作&#xff0c;例如聊到的下单&#xff1a;「扣库存数量、增加订单详情记录、插入物流信息」&#xff0…

gradle学习及问题

一、下载安装 参考&#xff1a;https://blog.csdn.net/chentian114/article/details/123344839 1、下载Gradle并解压 安装包&#xff1a;gradle-6.7-bin.zip 可以在idea的安装目录查看自己适配的版本 路径&#xff1a;D:\IDEA2021.3\plugins\gradle\lib 下载地址&#xff1a…

idea中使用maven

默认情况下&#xff0c;idea会自动下载并安装maven&#xff0c;这不便于我们管理。 最好是自行下载maven&#xff0c;然后在idea中指定maven的文件夹路径

VMware安装CentOS 7

在虚拟机中安装无论是Windows还是Linux其实都差不多&#xff0c;主要还是需要熟悉VMware的使用&#xff0c;多新增几次就熟悉了&#xff0c;可以反复删除再新增去练习… 如下是安装CentOS 7 安装过程&#xff1a; VMare Workstation 16 PRO 中安装CentOS 7 CentOS 7 下载推荐…

工业三防平板可优化工厂流程管理

在当今高度自动化和数字化的工业生产环境中&#xff0c;工业三防平板正逐渐成为优化工厂流程管理的关键工具。其强大的功能和卓越的性能&#xff0c;为工厂带来了更高的效率、更低的成本以及更出色的质量控制。 工业三防平板&#xff0c;顾名思义&#xff0c;具备防水、防尘、防…

在AWS创建一台Windows主机并登录

正文共&#xff1a;1111 字 21 图&#xff0c;预估阅读时间&#xff1a;1 分钟 因为之前微软云Azure免费&#xff0c;我们还做了简单的测试&#xff08;白嫖党618福利&#xff01;来Azure领200美刀&#xff01;外加云主机免费用一年&#xff01;&#xff09;&#xff1b;并且通…

linux中.a和.so库文件

区别 在Linux系统中&#xff0c;.a和.so文件是两种常见的库文件格式&#xff0c;它们在功能、使用方式及编译链接过程中存在显著的区别。以下是这两类文件的具体区别&#xff1a; 1. 文件类型与功能 .a文件&#xff1a; 类型&#xff1a;归档库文件&#xff0c;也称为静态库。…

46 mysql 客户端拿不到具体的错误信息

前言 这是最近碰到的一个问题 同样的一个 环境的问题, 在正常的 mysql 环境会返回 具体的错误信息, 然后 在我的另外一个环境里面 只能返回一些 unknown error 之类的 十分抽象的环境 然后 我们这里 来看一下 具体的情况 我们这里从 错误的环境 往前推导 来查看 并解决这个…

微软研究人员为电子表格应用开发了专用人工智能LLM

微软的 Copilot 生成式人工智能助手现已成为该公司许多软件应用程序的一部分。其中包括 Excel 电子表格应用程序&#xff0c;用户可以在其中输入文本提示来帮助处理某些选项。微软的一组研究人员一直在研究一种新的人工智能大型语言模型&#xff0c;这种模型是专门为 Excel、Go…

MongoDB常用命令大全

文章目录 一、MongoDB简介二、服务启动停止备份三、数据库相关四、集合操作五、文档操作六、其他常用命令 一、MongoDB简介 MongoDB是一款流行的NoSQL数据库&#xff0c;以其灵活的文档模型、高可用性、易于扩展等特性而受到广泛关注。 MongoDB 是由C语言编写的&#xff0c;是…