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://xiahunao.cn/news/3245336.html

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

相关文章

防火墙双机热备和带宽管理练习

目录 实验拓扑 实验需求 实验思路 实验步骤 需求12 需求13 需求14 需求15 需求16 实验拓扑 实验需求 12&#xff0c;对现有网络进行改造升级&#xff0c;将当个防火墙组网改成双机热备的组网形式&#xff0c;做负载分担模式&#xff0c;游客区和DMZ区走FW3&#xff0c…

网络原理(上)

前言&#x1f440;~ 上一章我们介绍了网络的一些基础知识&#xff0c;今天来讲解一下网络原理相关的知识点&#xff0c;分三篇进行阐述内容有点多​​​​​​​ 再谈协议分层 应用层 传输层&#xff08;重点&#xff09; UDP协议 TCP协议 TCP如何完成可靠传输&#xff…

Windows系统中MySQL的安装和卸载(详细包含msi和zip下载方式,以及完全卸载方法,易出现问题及解决方案等)

MySQL的安装: 第一种:msi安装(交简单,但是不能自定义安装路径) 下载地址:https://dev.mysql.com/downloads/installer/ 选择历史版本 选择安装版本,这里我选择的是8.0.37的版本,然后点击Download下载离线安装包 如下图即为下载好的版本,双击打开安装 出现如下情况,…

设计模式-领域逻辑模式-事务脚本(Transaction Script)

事务脚本的特点 多数应用可看成由多个事务组成事务脚本将多个业务逻辑组织成单个过程事务间相互修改各自产生的数据 事务脚本的运行机制 使用事务脚本时&#xff0c;领域逻辑主要通过系统所执行的事务来组织。例如&#xff1a;预定酒店过程。 事务脚本的组织 将整个事务脚本放…

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…

Redis-基础概念

目录 概念 Redis是什么 Redis 和 MySQL 的区别&#xff1f; Redis单线程有什么极端场景的瓶颈 Redis为什么快? 为什么Redis是单线程? Redis是单线程还是多线程 Redis为什么选择单线程做核心处理 Redis6.0之后引入了多线程&#xff0c;你知道为什么吗? 瓶颈是内存和I…

jmeter之变量随机参数化以及解决多线程不会随机变化

参考链接&#xff1a; https://www.cnblogs.com/Testing1105/p/12743475.html jmeter 使用random函数多线程运行时数据不会随机变化&#xff1f;_jmeter 线程组循环执行时 变量不变-CSDN博客 1、如下图所示&#xff0c;需要对请求参数 autor 和phone进行随机参数化 2、目前有…

基于用户非兴趣/非偏好/非习惯的推荐

基于用户非兴趣、非偏好、非习惯的推荐是一种个性化推荐技术&#xff0c;旨在为用户提供与其日常行为和兴趣模式不同的推荐内容。这种推荐方法的目的是打破用户的信息过滤和习惯&#xff0c;发现新的、潜在的兴趣点&#xff0c;从而提供更广泛和多样化的推荐结果。 通过收集和分…

Qt6 OpenCV4视频监控系统项目源码解析——附源码及编译运行步骤

很多刚毕业&#xff0c;或者想着转行到C Qt方向的小伙伴&#xff0c;平时可能拿不出比较像样的项目。这里你可要好好收藏啦。自己拿回去好好改改&#xff0c;就可以成为自己的项目经历了。祝各位找工作顺利呀。 好了。废话不多说。 这个项目架构采用的是MVC架构&#xff0c;结…

Qt 使用发布工具 windeployqt 来release

本文记录使用qt进行release文件 目录 1. windeployqt 常用选项 2. 创建release文件夹&#xff0c;并将exe文件拷贝进来 3.使用命令 1. windeployqt 常用选项 选项 意义 --release --no-quick-import --translations <languages> --no-translations --no-virtualkeyb…

PTA - 嵌套列表求和

使用递归函数对嵌套列表求和 函数接口定义&#xff1a; def sumtree(L) L是输入的嵌套列表。 裁判测试程序样例&#xff1a; /* 请在这里填写答案 */L eval(input()) print(sumtree(L)) # 调用函数 输入样例&#xff1a; 在这里给出一组输入。例如&#xff1a; [1,[2…

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

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

六边形动态特效404单页HTML源码

源码介绍 动态悬浮的六边形,旁边404文字以及跳转按钮,整体看着像科技二次元画风,页面简约美观,可以做网站错误页或者丢失页面,将下面的代码放到空白的HTML里面,然后上传到服务器里面,设置好重定向即可 效果预览 完整源码 <!DOCTYPE html> <html><head…

图——图的应用02最短路径(Dijkstra算法与Floyd算法详解),拓扑排序及关键路径

前面介绍了图的应用——01最小生成树章节&#xff0c;大家可以通过下面的链接学习&#xff1a; 图——图的应用01最小生成树&#xff08;Prim算法与Kruskal算法详解&#xff09; 今天就讲一下图的其他应用——最短路径&#xff0c;拓扑排序及关键路径。 目录 一&#xff0c…

整数或小数点后补0操作

效果展示&#xff1a; 整数情况&#xff1a; 小数情况&#xff1a; 小编这里是以微信小程序举例&#xff0c;代码通用可兼容vue等。 1.在utils文件下创建工具util.js文本 util.js页面&#xff1a; // 格式…

React@16.x(60)Redux@4.x(9)- 实现 applyMiddleware

目录 1&#xff0c;applyMiddleware 原理2&#xff0c;实现2.1&#xff0c;applyMiddleware2.1.1&#xff0c;compose 方法2.1.2&#xff0c;applyMiddleware 2.2&#xff0c;修改 createStore 接上篇文章&#xff1a;Redux中间件介绍。 1&#xff0c;applyMiddleware 原理 R…

【精品资料】大数据可视化平台数据治理方案(626页WORD)

引言&#xff1a;大数据可视化平台的数据治理方案是一个综合性的策略&#xff0c;旨在确保大数据的质量、安全性、可访问性和合规性&#xff0c;从而支持高效的数据分析和可视化过程。 方案介绍&#xff1a; 大数据可视化平台的数据治理方案是一个综合性的策略&#xff0c;旨在…

Nginx源码windows下编译

参考&#xff1a;Nginx Windows下编译和安装_window 如果编译安装nginx-CSDN博客 参考&#xff1a; Building nginx on the Win32 platform with Visual C 1.安装MSYS2 参考 MSYS2 下 installation 内容下载安装即可。 2.下载依赖库&#xff1a; PCRE:Download PCRE ​ …

在设计电气系统时,电气工程师需要考虑哪些关键因素?

在设计电气系统时&#xff0c;电气工程师需要考虑多个关键因素&#xff0c;以确保系统的安全性、可靠性、效率和经济性。我收集归类了一份plc学习包&#xff0c;对于新手而言简直不要太棒&#xff0c;里面包括了新手各个时期的学习方向编程教学、问题视频讲解、毕设800套和语言…

三球交汇定理计算标签位置(UWB)

目录 题目三球交汇定理计算过程代码实现说明 题目 假设标签坐标为(x0,y0)&#xff0c;基站ABCD的坐标分别为(x1,y1)(x2,y2)(x3,y3)(x4,y4)&#xff0c;基站坐标已知&#xff0c;如何计算标签坐标&#xff1f; 三球交汇定理 三球交汇定位&#xff08; Three-ball intersection…