MVCC原理以及隔离机制

article/2025/9/15 11:55:13

1、mysql是如何进行数据回滚的

mysql使用了大量的 undo日志trx_id 字段以及 roll_pointer 字段来实现的数据回滚。版本链比对规则图:在这里插入图片描述

查询

​ 当mysql开启一个查询时 遇到的select语句会创建一个 read-view 一致性视图,这个视图里面保存 一个未提交事务的数组(数组中最小的id为min_id)以及下一个需要分配的最大事务id(max_id)。read-view遇到第一个查询就会生成,不管查询的是哪个表,都会延用第一个一致性视图
​ 当mysql遇到查询时,会把版本链数据里面的事务id跟read-view里面的事务id进行对比。read-view是用来解决可重复读的隔离机制对于全表只会生成一次。如果是读未提交那么read-view每一次查询都会更新一次

  • trx_id:标识当前生成一致性视图的事务id
  • m_ids:表示活跃的事务数组(未提交)
  • min_id:在创建一致性视图时,活跃的最小事务id(未提交)
  • max_id:下一个需要分配的事务id
例如:
A开启事务,事务id为50:trx_id=50,m_ids=[50],min_id=50,max_id=51
B开启事务事务id为51:trx_id=51,m_ids=[50,51],min_id=50,max_id=52
根据版本链的比对规则,查询到每行数据时,获取隐藏字段 trx_id 时进行对比,如果不满足再通过 roll_pointer字段再向上查找
版本链对比规则:mysql会根据事务id进行划分成 已经提交事务、未提交事务与提交事务、未开始事务trx_id < min_id:证明是已经提交事务,那么证明数据可见min_id <= trx_id <= max_id:分为两种情况如果row的trx_id存在在read-view数组里面,那么就证明还没有提交事务,数据不可见,当前事务可见如果row的trx_id不存在在read-view数组里面,那么这个版本是已经提交了的事务生成的,可见max_id < trx_id: 表示还未开始的事务生成的,不可见

在这里插入图片描述

修改

​ Mysql会给每个表新增两个字段 trx_id 事务id以及 roll_pointer 回滚指针。如果执行修改语句会先插入数据并且删除原来老的数据并且将其放到undo日志中,然后新的数据roll_pointer字段就存放undo日志中的指针。

删除

update的特殊情况,会将版本链中最新的数据复制一份,然后将trx_id修改为删除操作的trx_id,同时将数据头信息(record header)里面的(delete_flag)标记上true代表删除

2、事务隔离机制

1、锁分类

  • 从性能上分为乐观锁(版本比对)和悲观锁
  • 对数据库操作的类型分为读锁和写锁(都属于悲观锁)
  • 读锁(共享锁):同一份数据,多个读操作可以同时进行不会相互影响
  • 写锁(排它锁):当前写操作没有完成前,它会阻断其他写锁和读锁
  • 从对数据操作的粒度分为,表锁和行锁

2、MyISAM

表锁:
每次都锁住整张表,开销小,加锁快;不会出现死锁;锁的粒度大,发生锁冲突的概率最高,并发度最低表锁一般用在需要数据迁移的时候,做全表操作时候

CREATE TABLE `mylock` (`id` int(11) NOT NULL AUTO_INCREMENT,`NAME` varchar(20) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;# 手动添加锁
lock table 表名称 read(write),表名称2 read(write);
# 产看添加过的锁
show open tables;
#删除锁
unlock tables;INSERT INTO`test`.`mylock` (`id`, `NAME`) VALUES ('1', 'a');
INSERT INTO`test`.`mylock` (`id`, `NAME`) VALUES ('2', 'b');
INSERT INTO`test`.`mylock` (`id`, `NAME`) VALUES ('3', 'c');
INSERT INTO`test`.`mylock` (`id`, `NAME`) VALUES ('4', 'd');
lock table mylock read;
# 加读锁,当前session和其它session都可以读该表,当前session中插入或者更新锁定表都会报错,其它session等待lock table mylock write;
# 当前session增删改查都没得问题,其它session对该表所有操作都会阻塞

3、InnoDB

行锁:
每次锁操作锁住一行数据,开销大,加锁慢;会出现死锁;锁粒度最小,发生锁冲突的概率最低,并发度最高。commit之后就会释放掉锁

事务隔离级别:

  • 读未提交(Read uncommited) 脏读、不可重复读、幻读都可能
  • 读已提交(Read commited)不可重复读、幻读可能
  • 可重复读(Repeatable read)幻读可能
  • 串行化(Serializable)都不可能
# 查看当前数据库的事务隔离性
show variables like 'tx_isolation';# 设置事务隔离级别
set tx_isolation='REPEATABLE-READ';# 读未提交 无法解决脏读、不可重复读、幻读
set tx_isolation='read-uncommitted';  #客户端A
set session transaction isolation level read uncommitted; #客户端B更新事务隔离级别# 读以提交 无法解决不可重复读、幻读
set tx_isolation='read-committed';# 可重复读 无法解决 幻读
set tx_isolation='repeatable-read';

4、并发带来的问题

  • 更新丢失:10个库存,线程1查询出来为10,线程2查询出来也是10,线程1减掉5个库存这时数据库就是5个,而线程2减掉2个库存并且更新到数据库中就成了8
  • 脏读:事务1正在对一条数据进行修改,但是没有提交,而事务2查询出已经修改过的数据,但是事务1遇到错误回滚了,这时候事务2查的数据就有问题
  • 不可重复读:一个事务读取某些数据后的某个时间,再次读取以前读过的数据,却发现其读出的数据已经发生了改变、或者某个记录被删除了。 一句话:事务A读取到了事务B已经提交的修改过的数据
  • 幻读:一个事务按相同的条件查询重新读已经检索过的数据,发现其他事务插入了满足其条件的新数据。一句话:事务A读取到了事务B提交的新增数据

6、间隙锁(在某些情况下可以解决幻读)

# 这个时候数据之间的所有间隙就会被锁上,其它事务插入时就会被阻塞,就不能插入进去
update account set name='123' where id > 8 and id < 20

InnoDB的行锁是针对索引加的锁,不是针对记录加的锁,并且该索引不能失效,否则都会从行锁升级为表锁

7、死锁

# 查看近期死锁日志信息,大多数情况下mysql可以自动检测死锁并回滚产生死锁的事务
show engine innodb status

8、锁优化

  • 尽可能让所有的数据检索都通过索引来完成,避免无索引行锁升级为表锁
  • 合理设计索引,尽量缩小锁的范围
  • 尽可能减少检索条件范围,避免间隙锁
  • 尽量控制事务大小,减少锁定资源和时间长度,涉及事务加锁的sql尽量放在最后执行
  • 尽可能降低事务隔离级别

9、锁分析

show status like'innodb_row_lock%'; 行锁分析/**
Innodb_row_lock_current_waits: 当前正在等待锁定的数量 
Innodb_row_lock_time: 从系统启动到现在锁定总时间长度 
Innodb_row_lock_time_avg: 每次等待所花平均时间 
Innodb_row_lock_time_max:从系统启动到现在等待最长的一次所花时间 
Innodb_row_lock_waits:系统启动后到现在总共等待的次数
**/

http://chatgpt.dhexx.cn/article/OGiUvHay.shtml

相关文章

【MVCC多版本并发控制】MVCC 机制的原理及实现,什么是MVCC,多版本并发控制

什么是 MVCC MVCC (Multiversion Concurrency Control) 中文全程叫多版本并发控制&#xff0c;是现代数据库&#xff08;包括 MySQL、Oracle、PostgreSQL 等&#xff09;引擎实现中常用的处理读写冲突的手段&#xff0c;目的在于提高数据库高并发场景下的吞吐性能。 如此一来…

MySql的MVCC实现机制

MVCC实现机制 快照读和当前读MVCC 快照读和当前读 在了解MySql的MVCC实现之前&#xff0c;需要先了解什么是快照读和当前读&#xff0c;以便于后续讲解 快照读&#xff1a;就是单纯的 SELECT 语句&#xff0c;不包括下面这两类语句: SELECT ... FOR UPDATE SELECT ... LOCK I…

MVCC机制略解

在mysql中&#xff0c;默认的隔离级别是可重复读。即在一个事物中读取到的数据总是一样的&#xff0c;即使其他事务把数据改了&#xff0c;那在这个事务中读取的数据还是第一次读取的数据。 mysql还可以设置为读已提交隔离级别。即一个事务中读取的数据&#xff0c;随着其他事务…

什么是MVCC,一文搞懂MySQL的MVCC机制

MVCC是什么 MVCC&#xff0c;即Multi-Version Concurrency Control &#xff08;多版本并发控制&#xff09;。它是一种并发控制的方法&#xff0c;一般在数据库管理系统中&#xff0c;实现对数据库的并发访问&#xff0c;在编程语言中实现事务内存。 数据库中同时存在多个版本…

对MVCC全面解析

简介 MVCC&#xff08;Multi-Version Concurrency Control&#xff09;即多版本并发控制。 MVCC的实现原理 我们在了解MVCC之前&#xff0c;首先先了解一下几个比较常见的锁。 读锁&#xff1a;也叫共享锁、S锁&#xff0c;若事务T对数据对象A加上S锁&#xff0c;则事务T可…

【MySQL】MVCC机制

什么是MVCC MVCC 英文全称&#xff1a;Multi-Version Concurrency Control&#xff0c;Mysql的事务隔离性就是主要靠MVCC机制来实现的。对一行数据的读和写默认是不会通过加锁互斥来保证隔离性的&#xff0c;这样避免了频繁的加锁互斥&#xff0c;而在串行化隔离级别为了保证较…

一文精通MVCC机制

MVCC(Multi-Version Concurrency Control)多版本并发控制机制 使用串行化隔离级别时&#xff0c;mysql会将所有的操作加锁互斥&#xff0c;来保证并发安全。这种方式必然降低并发性能。mysql在读已提交和可重复读隔离级别下&#xff0c;对一行数据的读和写两个操作默认是不会通…

数据库的MVCC机制

MVCC 1. 什么是MVCC MVCC &#xff08;Multiversion Concurrency Control&#xff09;&#xff0c;多版本并发控制。顾名思义&#xff0c;MVCC 是通过数据行的多个版 本管理来实现数据库的 并发控制 。这项技术使得在InnoDB的事务隔离级别下执行 一致性读 操作有了保 证。换言…

MySQL之MVCC机制

1. MVCC概念 MVCC&#xff0c;全称Multi-Version Concurrency Control&#xff0c;即多版本并发控制。MVCC是一种并发控制的方法&#xff0c;一般在数据库管理系统中&#xff0c;实现对数据库的并发访问&#xff0c;在编程语言中实现事务内存。 在Mysql的InnoDB引擎中就是指在…

【MySQL进阶-05】深入理解mvcc机制(详解)

MySql系列整体栏目 内容链接地址【一】深入理解mysql索引本质https://blog.csdn.net/zhenghuishengq/article/details/121027025【二】深入理解mysql索引优化以及explain关键字https://blog.csdn.net/zhenghuishengq/article/details/124552080【三】深入理解mysql的索引分类&a…

MVCC及实现原理

&#xff01;首先声明&#xff0c;MySQL 的测试环境是 5.7 前提概要 什么是 MVCC什么是当前读和快照读&#xff1f;当前读&#xff0c;快照读和 MVCC 的关系MVCC 实现原理 隐式字段undo日志Read View整体流程MVCC 相关问题 RR 是如何在 RC 级的基础上解决不可重复读的&#xf…

4gl程式debug常用技巧

1、带参数的D&#xff1a; ‘MISC’表示具体料号传入 2、指定行数设置断点 比如我要在程式axmt360中的211行开始D 进入Debug界面后按ctrlD 弹出界面 输入b 行数 点OK 出现上面表示已设置OK&#xff0c;然后点cancel或叉叉退出 最后点下面按扭&#xff0c;程式跑到210行时自…

【OpenGL】十五、OpenGL 绘制三角形 ( 绘制 GL_TRIANGLE_FAN 三角形扇 )

文章目录 一、绘制 GL_TRIANGLE_FAN 三角形1、绘制 3 个点的情况2、绘制 4 个点的情况3、绘制 5 个点的情况4、绘制 6 个点的情况 二、相关资源 一、绘制 GL_TRIANGLE_FAN 三角形 GL_TRIANGLE_FAN 的绘制规则是 , 以第 1 1 1 个点作为顶点 , 第 1 , 2 , 3 1,2,3 1,2,3 个点组…

Unity3D笔记十八 GL图像库

作者&#xff1a;PEPE 出处&#xff1a;http://pepe.cnblogs.com/ 1、绘制2D图像的时需要使用GL.LoadOrtho()方法来将图形映射到平面中。 2、所有绘制相关的内容都要写在OnPostRender()方法中。 3、有关GL图像库的脚本需要绑定到Hierarchy视图中Camera上&#xff0c;否则无法…

Mapbox GL插件之echartsLayer

Mapbox GL除了本身的api具有的功能以外&#xff0c;还能够集成各种开源的类库。 ECharts 是一个使用 JavaScript 实现的开源可视化库&#xff0c;涵盖各行业图表&#xff0c;百度公司开发的&#xff0c;同时其中也有一些地图的效果。 Mapbox GL的echarts插件&#xff0c;在gith…

【OpenGL】十八、OpenGL 绘制多边形 ( 绘制 GL_POLYGON 模式多边形 )

文章目录 一、绘制 GL_POLYGON 模式多边形二、多边形绘制顺序分析三、相关资源 一、绘制 GL_POLYGON 模式多边形 使用 glBegin(GL_POLYGON) 设置绘制多边形 , 不管有几个点 , 都按照指定的顺序连接起来 ; 注意 : 这些点组成的多边形必须是凸多边形 , 不能是凹多边形 ; 代码示例…

gl_FragCoord 的含义

gl_FragCoord 表示当前片元着色器处理的候选片元窗口相对坐标信息&#xff0c;是一个 vec4 类型的变量 (x, y, z, 1/w)&#xff0c; 其中 x, y 是当前片元的窗口坐标&#xff0c;OpenGL 默认以窗口左下角为原点&#xff0c; 在 着色器中通过布局限定符可以重新设定原点&#xf…

WebGL着色器内置变量gl_PointSize、gl_Position、gl_FragColor、gl_FragCoord、gl_PointCoord

WebGL着色器内置变量 WebGL中文教程网 本文是WebGL教程(电子书)的2.7节内容 着色器语言在GPU的着色器单元执行&#xff0c;javascript语言、C语言在CPU上执行&#xff0c;任何一种语言的语法规则&#xff0c;整体设计都和它执行的硬件有一定的关系&#xff0c;GPU和CPU执行程…

Unity画线之GL

上一篇中&#xff0c;SetPixel的方法&#xff0c;卡顿严重&#xff0c;暂未解决&#xff0c;又去看了原来的GL画线&#xff0c;自己画图思考了一下适配UI的问题&#xff0c;最终解决。 特此说明&#xff0c;GL画线功能&#xff0c;及Shader均为借鉴&#xff0c;自己做了优化。…

GL823K

下面是另一家SD/TF解码芯片的方案 ![](https://img-blog.csdnimg.cn/20210319145313645.png?x-oss-processimage/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80OTU3MDgwNA,size_16,color_FFFFFF,t_70 13030533945 VX