当前位置: 首页 > news >正文

MYSQL(事务+锁+MVCC+SQL执行流程)理解

一)事务的特性:

一致性:主要是在数据层面来说,不能说执行扣减库存的操作的时候用户订单数据却没有生成

原子性:主要是在操作层面来说,要么操作完成,要么操作全部回滚;

隔离性:是自己的事务操作自己的数据,不会受到到其他事务的影响;

持久性:事务进行提交以后,数据要真实的修改在磁盘上面,不能说系统宕机数据就丢失了

二)脏写:

2.1)数据丢失或者是脏写:当有两个事务或者是多个事务选择同一行,然后基于最初的值选定该行的时候,由于每一个事务都不知道其他事务的存在,就会发生数据丢失更新问题,最后的更新覆盖了其他事务所做的更新;

乐观锁:就是假设两个事务并发执行,一个事务想要把库存扣减3,另一个事务想要把库存扣减2,那么两个事务并发执行的时候,此时就会发生脏写问题,如何解决呢,可以使用版本号机制,给库存字段再加上一个版本号,每进行一次数据的更新操作,版本号+1,此时就可以解决脏写问题,此时一定会出现一个事务版本号小于等于内存版本号,更新失败;

悲观锁:一个事务针对于要操作的数据加锁,其他事务想要操作数据,只能阻塞等待;

2.2)脏读:事务A读取到了事务B已经修改但是没有提交的数据,因为数据不稳定,发生脏读一定会发生不可能重复读和幻读;

2.3)不可重复读:事务A相同的查询语句在不同的时间查询到了不同的结果

可重复读就是不管其他变量对数据是否修改,第一查询只要查询的结果是true,后面只要当前事务不修改当前这个布尔值,那么读取到的始终是一条结果,侧重于已经存在但是修改过的数据

2.4)幻读:一个事务A会读取到事务B新增的数据

表锁:每次操作锁住整张表,开销小,加锁快,不会出现死锁,锁定粒度大,发生锁冲突的概率最高,并发度最低,一般用在整表数据迁移的场景,防止数据迁移数据发生变动;

手动增加表锁:lock table 表名称1 read(write),表名称2 read(write)

查看加上的表锁:show open tables

删除表锁:unlock tables;

加读锁:只能读取该表,不能写该表

加写锁:即可以读,又可以写,其他事务既不能读,也不可以写

行锁:每一次操作锁住一行记录,开销大,加锁慢,锁定粒度最小,发生所冲突的概率最低,并发程度最高,InnoDB和MYSIM存储引擎有两个区别:

1)InnoDB支持事务

2)InnoDB支持行级锁

行锁演示:一个Session开启事务以后不提交,另一个Session更新同一条记录的时候会发生阻塞,更新不同的记录的时候不会发生阻塞;

3)表锁开销小,加锁块,但是行锁开销大,加锁慢,这样子理解很简单,对于表来说只要找到这一张表,就可以直接给他加锁,速度很快,但是对于行锁来说,先要找到表,再来找行,效率很低,行锁的粒度肯定是比表锁小的,粒度越大,锁冲突的概率还是比较高的

4)MYSIM存储引擎在执行Select语句之前,会自动给设计所有的表加读锁,在执行update,insert,delete操作的时候会自动给涉及到的表加写锁,但是InnoDB存储引擎在执行查询语句Select操作的时候,因为有MVCC机制所以不加锁,但是update,insert和delete操作会加行锁,总而言之,就是读锁会阻塞写,但是不会阻塞读,但是写锁会把读和写都会阻塞

在数据库没有提交数据的时候,你更新的数据是在缓存进行更新的,事务与事务在并发进行的时候就叫作隔离级别,只有在提交之后,数据才从日志中把数据更新到数据库里面

三)MVCC:无论事务是否提交,undolog版本链的数据都是要记录下来的,因为事务要回滚,所以要记录,基于快照结果集+undolog版本链,undolog版本链只有一份;

1)begin和start transaction并不是一个事务的起点,在执行到第一个DML语句的时候,也就是执行到他们的第一个修改操作InnoDb的语句的时候,事务才算是真正的进行启动,才会向MYSQL中申请事务id,执行select操作是不会生成事务ID的

2)insert新插入的数据的版本连上面的记录的回滚指针的地址就是null,因为当前数据已经是最早的纪录了,不管事务是否提交,update更新的数据都会存放到undolog版本链中,一行数据由四个部分组成,当前事务操作操作完以后的数据完整记录+当前事务操作完成后的数据ID+聚簇索引ID+版本链(指针));

3)当一个事务id=60的事务新增了一条数据,那么这一行记录就变成

(userID=1,username="李四",60,聚簇索引ID,null(因为是事务新插入的第一条数据)

此时再来一个事务修改这条user数据username="王五",此时版本链的数据就变成了这样子:

0X666 (userID=1,username="王五",100,聚簇索引ID,0X777)|
----------------------------------------------------
|
0X777 (userID=1,username="李四",60,聚簇索引ID,null(因为是事务新插入的第一条数据)

4)在可重复读级别,当事务开启以后,执行任何的查询SQL都会生成当前事务的一致性视图,也叫做readView,该视图只会生成一次且在事务提交前不会发生任何变化,但是是如果是读已提交隔离级别下每一次执行查询SQL都会生成读视图(必须是当前读),但是从版本连中取数据一定是从最新的undolog版本连中的数据查找的;

5)当前进行比对的过程中是从当前undolog版本链的最新的记录的事务ID开始和读视图readView进行比对,从而来确定最终MYSQL读取的是哪一条记录,如果这条记录不符合要求,那么按照undolog版本链单向链表查询下一条符合要求的记录;

6)MYSQL会根据读视图中的最小事务ID和最大事务ID来划分区间

从而确定已提交事务和未提交事务

7)根据undolog版本链上的每一条记录的事务ID来判断当前这条记录是否已经在生成读视图之前提交了,小于min_id的一定是已提交事务,大于max_id一定是未提交事务,但是在min_id和max_id之间的记录有可能是已提交,也有可能是未提交;

8)事务操作中,update操作更新的是MYSQL中真实的数据;

比较规则:一个事务想要并可以读取到读视图生成之前事务提交的记录

1)trx_id=creator_trx_id,如果这条记录的事务ID等于创建读视图的事务ID,那么该数据记录的最后一次操作的事务就是当前事务,当前记录对当前事务可见;

2)trx_id<creator_trx_id,说明在生成读视图的时候这条记录的事务ID不在活跃列表里面,说明修改这条记录的事务已经在生成读视图之前提交了,所以当前记录可见;

3)trx_id>=max_trx_id,如果trx_id 值小于 Read View 中的 min_trx_id ,表示这个版本的记录是在创建 Read View才启动的事务生成的,所以该版本的记录对当前事务不可见,否则会发生不可重复读的问题;

4)min_trx_id <= trx_id < max_trx_id:判断 trx_id 是不是在当前事务ID集合(m_ids)里面

四)一条SQL语句的执行流程:update user set name="张三" where userID=1;

1)执行器:调用执行引擎的接口把SQL语句丢给存储引擎层来进行执行

2)首先检查buffer pool缓冲池中有没有对应的数据,正常来说一些常用的数据都被加载到buffer pool里面来提高MYSQL的性能,如果buffer pool中没有,就去加载缓存数据

3)把id=1的记录所在的16K页的数据加载到buffer pool中;

4)写入更新数据的旧值到undoLog回滚日志里面,用于回滚,将老的值写入到undolog回滚日志文件里面;

5)更新bufferpool内存的数据;

6)把更新修改后的数据写入到redologbuffer里面,redolog日志会定期的把redologbuffer中的数据定期的刷新到redolog重做日志文件里面,这是一个prepare阶段,它是属于一个物理修改,大概在物理磁盘上面的哪一个页位置做了修改的值,不是记录的是具体的SQL语句,但是对于binlog日志来说直接记录的是name="张三";

7)准备提交事务,将binLog日志写入到binlog文件中,binlog属于归档日志文件,属于Server层,binlog主要用于恢复数据库中磁盘的数据;

8)当用户进行执行commit操作的时候,binog会将commit标记到redolog文件日志里面,此时提交事务完成,该标记就是为了保证事务提交以后binlog和redo log数据的一致性,这也就是两阶段提交,第一阶段prepare阶段,两个日志各写各的,第二个是commit操作,代表binlog日志和redolog日志已经全部完成了,两阶段提交就是为了保证事务执行完成以后两个文件都是写入成功的;

9)MYSQL会开启一个后台线程,在系统空闲的时候随机写会到磁盘里面,是以page为单位进行写入的,不是刷新一条数据,而是整个页的数据都会刷新到磁盘里面去,这一步执行完成磁盘中的数据才真正修改了,ibd表文件才是真正地被修改了;

为什么要使用redolog日志?为了程序执行的效率,因为假设现在要执行10条SQL语句,操作10张表,此时的随机IO性能比较低,因为10张表的数据在不同的位置,磁针要来回地旋转找数据,磁头旋转比较慢,但是此时使用redolog日志里面都记录着具体的数据在那一个数据页上修改,最终进行写会到磁盘的时候是顺序IO,效率非常高;

WAL机制:磁盘文件预先写的机制,Write ahead logging,真正存储数据的时候,先写磁盘的日志文件,再来刷新内存的数据;

redolog:侧重于修改的数据还没有刷新到磁盘里面的时候,用于数据恢复的,假设数据库提交的时候系统突然宕机了,内存中的数据还没有来得及刷新到磁盘里面,此时redolog就用了起来

binlog:用于程序员不小心删除数据进行数据恢复

redolog的写入过程:

1)redolog从第一个文件开始写,写完一个文件之后再来写另外一个文件,写到最后一个文件末尾之后又回到第一个文件开头来写,那么第一个文件就会覆盖掉 

2)write_pos代表当前记录的位置,一边写一边向后移动,写到第三个文件末尾以后就会到第0个文件开头,check point是当前要擦除的位置,他也是向后推移并且循环的,从上面的图来看,check point顺时针向下的数据都是真实的数据,如果发现write pos指针快要更新到check point那里了,于是就会尝试把check point后面的数据刷新到磁盘里面,擦除记录前要把记录更新到数据文件里面,write_pos区间到check_point之间的顺时针数据就是可以写的部分,如果write_pos最终追上了check_point代表redo_log日志写满了,这个时候不能再执行新的更新,得停下来先擦除掉一些新的记录,将check_point向前推进一下;

相关文章:

MYSQL(事务+锁+MVCC+SQL执行流程)理解

一)事务的特性: 一致性:主要是在数据层面来说&#xff0c;不能说执行扣减库存的操作的时候用户订单数据却没有生成 原子性:主要是在操作层面来说&#xff0c;要么操作完成&#xff0c;要么操作全部回滚&#xff1b; 隔离性:是自己的事务操作自己的数据&#xff0c;不会受到到其…...

解密一致性哈希算法:实现高可用和负载均衡的秘诀

解密一致性哈希算法&#xff1a;实现高可用和负载均衡的秘诀 前言第一&#xff1a;分布式系统中的数据分布问题&#xff0c;为什么需要一致性哈希算法第二&#xff1a;一致性hash算法的原理第三&#xff1a;一致性哈希算法的优点和局限性第四&#xff1a;一致性哈希算法的安全性…...

Python脚本:让工作自动化起来

Python是一种流行的编程语言&#xff0c;以其简洁和易读性而闻名。它提供了大量的库和模块&#xff0c;使其成为自动化各种任务的绝佳选择。 本文将探讨Python脚本及其代码&#xff0c;可以帮助您自动化各种任务并提高工作效率。无论您是开发人员、数据分析师还是只是想简化工…...

香港科技大学广州|可持续能源与环境学域博士招生宣讲会—广州大学城专场!!!(暨全额奖学金政策)

香港科技大学广州&#xff5c;可持续能源与环境学域博士招生宣讲会—广州大学城专场&#xff01;&#xff01;&#xff01;&#xff08;暨全额奖学金政策&#xff09; “面向未来改变游戏规则的——可持续能源与环境学域” &#xfffd;&#xfffd;&#xfffd;专注于能源环…...

uni-app:多种方法写入图片路径

一、文件在前端文件夹中 1、相对路径引用 从当前文件所在位置开始寻找图片文件的路径。../../ 表示返回两级目录&#xff0c;即从当前文件所在的 wind.vue 所在的位置开始向上回退两级。接着&#xff0c;进入 static 目录&#xff0c;再进入 look 目录&#xff0c;最后定位到 …...

共谋工业3D视觉发展,深眸科技以自研解决方案拓宽场景应用边界

随着中国工业领域自动化程度逐渐攀升&#xff0c;“机器换人”这一需求进一步提升。在传统2D工业视觉易受环境光干扰、无法进一步获取物体深度信息的限制条件下&#xff0c;工业3D视觉凭借着更强的空间和深度感知能力&#xff0c;以及通过点云数据获取物体距离和三维坐标信息的…...

前端面试基础面试题——11

1.什么是 vue 的计算属性&#xff1f; 2.vue怎么实现页面的权限控制 3.watch的作用是什么 4.响应式系统的基本原理 5.vue-loader 是什么&#xff1f;使用它的用途有哪些&#xff1f; 6.vuex 工作原理详解 7.vuex 有哪几种属性&#xff1f; 8.什么是 MVVM&#xff1f; 9…...

SQL server中内连接和外连接的区别、表达(表的连接)

SQL server中内连接与外连接的区别、表达 区别表达内连接外连接 待续 首先&#xff0c;内连接和外连接都是对表的连接操作 区别 内连接&#xff1a;连接结果仅包含符合连接条件的行&#xff0c;其中至少一个属性是共同的&#xff1b;注意区分在嵌套查询时使用的any以及all的区…...

Linux中的shell外壳与权限(包含目录文件的权限,粘滞位的来龙去脉)

Linux中的shell外壳与权限[包含目录文件的权限,粘滞位的来龙去脉] 一.shell外壳的理解1.为什么需要有shell外壳的存在?2.什么是shell外壳?3.shell外壳的运行原理是什么?4.shell和bash的关系 二.Linux中的用户权限1.用户分类与身份切换1.用户分类2.root用户切换为普通用户1.s…...

力扣第45题 跳跃游戏II c++ 贪心算法

题目 45. 跳跃游戏 II 中等 相关标签 贪心 数组 动态规划 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说&#xff0c;如果你在 nums[i] 处&#xff0c;你可以跳转到任意 nums[i j] 处…...

1024动态

感叹一下当前行情 从事码农这些年今年是最难的一年...

中心胖AP(AD9430DN)+远端管理单元RU(R240D)+出口网关,实现组网

适用于&#xff1a;V200R008至V200R019C00版本的万兆中心胖AP&#xff08;AD9431DN-24X&#xff09;。 组网规划 RU管理&#xff1a;VLAN 100&#xff0c;网段为192.168.100.0/24。 无线业务&#xff1a;VLAN 3&#xff0c;SSID为“wlan-net”&#xff0c;密码为“88888888”…...

shell_45.Linux在脚本中使用 getopt

在脚本中使用 getopt $ cat extractwithgetopt.sh #!/bin/bash # Extract command-line options and values with getopt # set -- $(getopt -q ab:cd "$") # echo while [ -n "$1" ] do case "$1" in -a) echo "Found the -a opt…...

2023-8-20 CVTE视源股份后端开发实习一面

自我介绍 操作系统 1 有了解进程和线程的特点吗 2 在linux层面的话是怎么创建一个进程或者一个线程的&#xff08;具体的系统调用的命令&#xff09; 答&#xff1a; 3 如果是java层面讲&#xff0c;怎么去启动一个线程&#xff0c;要实现哪些方法呢 Thread类实现run()方法的…...

二叉树进阶

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;那个传说中的man的主页 &#x1f3e0;个人专栏&#xff1a;题目解析 &#x1f30e;推荐文章&#xff1a;题目大解析&#xff08;3&#xff09; 目录 &#x1f449;&#x1f3fb;二叉搜索树概念 &#x1f4…...

前端性能优化 - 虚拟滚动

一 需求背景 需求&#xff1a;在一个表格里面一次性渲染全部数据&#xff0c;不采用分页形式&#xff0c;每行数据都有Echart图插入。 问题&#xff1a;图表渲染卡顿 技术栈&#xff1a;Vue、Element UI 卡顿原因&#xff1a;页面渲染时大量的元素参与到了重排的动作中&#x…...

手写 Promise(1)核心功能的实现

一&#xff1a;什么是 Promise Promise 是异步编程的一种解决方案&#xff0c;其实是一个构造函数&#xff0c;自己身上有all、reject、resolve这几个方法&#xff0c;原型上有then、catch等方法。 Promise对象有以下两个特点。 &#xff08;1&#xff09;对象的状态不受…...

深入探究Java内存模型

文章目录 &#x1f31f; Java虚拟机内存模型&#x1f34a; 一、方法区&#x1f34a; 二、堆&#x1f389; 堆的基本概念&#x1f389; 堆的结构&#x1f4dd; 新生代&#x1f4dd; 老年代 &#x1f389; 堆的分配策略&#x1f4dd; 对象优先分配&#x1f4dd; 空间优先分配 &am…...

深度学习 | Pytorch深度学习实践 (Chapter 10、11 CNN)

十、CNN 卷积神经网络 基础篇 首先引入 —— 二维卷积&#xff1a;卷积层保留原空间信息关键&#xff1a;判断输入输出的维度大小特征提取&#xff1a;卷积层、下采样分类器&#xff1a;全连接 引例&#xff1a;RGB图像&#xff08;栅格图像&#xff09; 首先&#xff0c;老师…...

谈谈你对spring boot 3.0的理解

谈谈你对spring boot 3.0的理解 一&#xff0c;Spring Boot 3.0 的兼容性 Spring Boot 3.0 在兼容性方面做出了很大的努力&#xff0c;以支持存量项目和老项目。尽管如此&#xff0c;仍需注意以下几点&#xff1a; Java 版本要求&#xff1a;Spring Boot 3.0 要求使用 Java 1…...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站&#xff0c;会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后&#xff0c;网站没有变化的情况。 不熟悉siteground主机的新手&#xff0c;遇到这个问题&#xff0c;就很抓狂&#xff0c;明明是哪都没操作错误&#x…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查

在对接支付宝API的时候&#xff0c;遇到了一些问题&#xff0c;记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望

文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例&#xff1a;使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例&#xff1a;使用OpenAI GPT-3进…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf

FTP 客服管理系统 实现kefu123登录&#xff0c;不允许匿名访问&#xff0c;kefu只能访问/data/kefu目录&#xff0c;不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

前端调试HTTP状态码

1xx&#xff08;信息类状态码&#xff09; 这类状态码表示临时响应&#xff0c;需要客户端继续处理请求。 100 Continue 服务器已收到请求的初始部分&#xff0c;客户端应继续发送剩余部分。 2xx&#xff08;成功类状态码&#xff09; 表示请求已成功被服务器接收、理解并处…...