SQL进阶理论篇(十一):什么是MVCC?

文章目录

  • 简介
  • 什么是MVCC
  • 快照读与当前读
  • 悲观锁的问题示例
  • 参考文献

简介

在MySQL中,默认的隔离级别是可重复读,可以解决脏读和不可重复读的问题,但不能解决幻读问题。如果想要解决幻读问题,就需要采用串行化的方式,通过牺牲数据库的并发事务处理能力,将隔离级别提升到最高。

那有没有一种方式,可以不采用锁机制,而是只通过乐观锁的方式,来解决不可重复度和幻读问题呢?

确实有,MVCC机制就是用来解决这个问题的。在多数情况下,它可以替代行级锁,降低系统的开销(如InnoDB中就是默认开启MVCC机制的,除此之外还有Oracle,DB2是采用多版本读的方式实现隔离级别,但严格来讲不是MVCC)。

大部分的RDBMS都会支持MVCC

本节将主要介绍以下几部分:

  • MVCC机制的思想是什么?
  • 为什么RDBMS要采用MVCC机制,只依靠悲观锁还不够么?

什么是MVCC

MVCC的英文全称是Multiversion Concurrency Control,中文翻译过来就是多版本并发控制系统

顾名思义,MVCC是通过数据行的多个版本管理,来实现数据库的并发控制。

简单的说,它的思想就是保存数据的历史版本。这样我们就可以通过比较版本号来决定数据是否显示出来(具体的规则后面会讲),基于这种乐观锁的机制,我们在读取数据的时候不需要加锁也可以保证事务的隔离性。

先总结一下MVCC的具体作用:

  • 解决了读写之间的阻塞问题。通过MVCC可以让读写之间互相不阻塞,即读的时候不会再阻塞写,反之也是一样,从而提高了事务的并发处理能力;
  • 降低了死锁的概率。MVCC里采用的是乐观锁的思想,所以读取数据时根本不用加锁,即使是写数据的时候,最多也是只锁定必要的行。降低了锁的数量,自然也降低了死锁的概率。
  • 解决一致性读的问题。一致性读又叫做快照读,当我们查询数据库在某个时间点的快照时,只能看到这个时间点之前事务提交更新的结果,而不能看到这个时间点之后事务的提交结果。

快照读与当前读

快照读,读取的是快照数据,不加锁的select语句都属于快照读,如:

SELECT * FROM player WHERE ...

当前读,读取的是最新数据,而不是历史版本的数据。加锁的select,或者对数据进行增删改查的时候,都会进行当前读。

SELECT * FROM player LOCK IN SHARE MODE;
SELECT * FROM player FOR UPDATE;
INSERT INTO player values ...
DELETE FROM player WHERE ...
UPDATE player SET ...

因此,快照读实际上就是普通读,而当前读包括了加锁的读取和DML操作。

悲观锁的问题示例

接下来,我们以一个具体的例子,来讲解一下采用悲观锁思想可能造成的问题。

比如说,我们有个账户金额表 user_balance,包括三个字段,分别是 username 用户名、balance 余额和 bankcard 卡号。其中只有用户A和用户B有账户余额,其他账户的余额都是0。

接着数据库管理员需要查询这张表里的总账户金额,即执行下面语句:

SELECT SUM(balance) FROM user_balance

这个过程里,用户A或者B自行开启了一个事务,做互相转账。

当管理员事务和用户的事务,时间上撞在一起的时候,会出现什么情况呢?

我们举两个例子(例子均来源于参考文献)。

例子一:由于管理员事务的行级锁的存在,导致用户A给用户B转账会存在等待时间。

如图:

在这里插入图片描述

为了保证数据的一致性,管理员事务在统计数据的时候,会给用到的数据加上行级锁。
比如说用户A所在数据行被加锁之后,用户A就不能再操作自己的记录了,如果想做update,只能等到管理员事务结束后,锁被释放,才能操作。

这就导致了用户A的体验很不好,多了额外的等待时长。

例子二:死锁。

过程如图:

在这里插入图片描述

简单的说,就是管理员在统计的时候,用户B开启了一个事务,给A转账。

管理员事务是一行一行边读边加锁,它先读取用户A的数据,于是持有了用户A数据的行锁,接下来,它应该再读取用户B的数据,再持有用户B数据的行锁。

但是,在它还没有读到用户B的数据之前,用户B就开启了事务,抢先对自己的记录进行了操作,于是用户B持有了自己所在数据行的行锁。

等到管理员事务需要读用户B的数据时,会发现数据行已经被锁上了,咋整,那就只能等呗,于是管理员事务就开始等待用户B数据的锁被释放。

只要用户B的事务正常结束,锁释放,那么管理员事务就能继续加锁,向下执行来完成统计。

但是用户B的事务并没有结束,因为是给用户A转账,因此它还需要update用户A的数据,把多的钱update进去。但问题是用户A的数据已经被管理员事务加锁了,用户B的事务如果想读,该怎么办呢?只能等管理员事务主动释放这个行锁。

于是,场面就变成了,管理员事务在等待用户事务释放B数据的行锁,而用户事务在等待管理员事务释放A数据的行锁,互不相让,死锁了。

这个就是悲观锁的常见问题,不过在基于乐观锁的MVCC里,这种情况发生的概率会很低,具体的我们下节会介绍。

参考文献

  1. 31丨为什么大部分RDBMS都会支持MVCC?

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

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

相关文章

js中for-in和for-of的区别

文章目录 一、介绍1.1、for-in1.2、for-of 二、区别2.1、迭代对象的内容不同2.2、迭代对象的类型不同2.3、迭代对象的顺序不同2.4、迭代对象的原理不同 三、联系四、如何选择合适的循环方法五、总结六、最后 一、介绍 在JavaScript中,for-in 和 for-of 是两种不同的…

Spring Boot入门指南

本文为官方文档直译版本。原文链接 Spring Boot入门指南 引言Spring Boot 简介系统要求Servlet 容器GraalVM 原生镜像 安装 Spring BootJava 开发人员安装说明安装 Maven安装 Gradle 安装 Spring Boot CLI手动安装使用 SDKMAN 安装!使用 OSX Homebrew 安装使用 MacP…

详细教程 - 从零开发 Vue 鸿蒙harmonyOS应用 第六节(js版) ——模块化设计实现复杂页面

随着HarmonyOS生态的日渐完善,越来越多的厂商加入鸿蒙系统应用开发的行列。然而从其他系统转到鸿蒙开发,很多开发者还是需要一个适应的过程,特别是面对比较复杂的页面,应该如何合理进行模块化拆分是一个难点。 本文将通过一个实例,来分析如果采用模块化的方式实现一个包含丰富内…

Flink系列之:Table API Connectors之JSON Format

Flink系列之:Table API Connectors之JSON Format 一、JSON Format二、依赖三、创建一张基于 JSON Format 的表四、Format 参数五、数据类型映射关系 一、JSON Format JSON Format 能读写 JSON 格式的数据。当前,JSON schema 是从 table schema 中自动推…

微服务组件Gateway的学习

Gateway Gateway基础概念Gateway简单使用Gateway路由工厂Gateway过滤器Gateway跨域配置 Gateway基础概念 API网关指系统的统一入口,它封装了应用程序的内部结构,为客户端提供统一服务,一些与业务本身功能无关的公共逻辑,可以在这…

WTN6系列语音芯片:PWM与DAC音频输出在PCB设计中的优势

随着科技的飞速发展,语音芯片在电子产品中的应用越来越广泛。其中,唯创知音的WTN6系列语音芯片凭借其卓越的性能和多样的功能,受到了市场的热烈欢迎。特别是其支持PWM和DAC两种音频输出方式的特点,使得工程师在PCB设计时能够更加灵…

【个人版】SpringBoot下Spring-Security自定义落地篇【四】

SpringBoot Spring-Security 背景: 上篇文章在源码读取的基础上,根据自身代码习惯及需求,总结了一个自定义简单落地版本。后来在看到松哥写的博文(不太爱看官网),发现还有新的变种模式,虽然整…

mysql使用全文索引+ngram全文解析器进行全文检索

表结构:表名 gamedb 主键 id 问题类型 type 问题 issue 答案 answer 需求 现在有个游戏资料库储存在mysql中,客户端进行搜索,需要对三个字段进行匹配,得到三个字段的相关性,选出三个字段中相关性最大的值进…

【MYSQL】-库的操作

💖作者:小树苗渴望变成参天大树🎈 🎉作者宣言:认真写好每一篇博客💤 🎊作者gitee:gitee✨ 💞作者专栏:C语言,数据结构初阶,Linux,C 动态规划算法🎄 如 果 你 …

在Idea中创建基于工件的本地服务

目录 1、创建基于工件的Tomcat服务器: 2、修改名称: 3、修改服务器项: 4、部署项 5、最后记得点右下角的【应用】和【确定】保存。 1、创建基于工件的Tomcat服务器: 运行->编辑配置->【Tomcat服务器】->本地 2、修…

前端框架如何帮助开发者构建应用程序?

目录 前言 1.项目简介 2. 平台特性 2.1 构架特性 2.2 功能特性 3. 整体架构 4. 技术栈 平台的开放性: 平台高拓展性: 5. 基础功能及搭建 5.1 代码生成器 5.2 工作流程 5.3 门户设计 5.4 大屏设计 5.5 报表设计 5.6 第三方登录 5.7 多租…

ceph更换硬盘

ceph -s //检查故障 k8s70132:~$ ceph -scluster:id: d10b3028-b78d-4b23-bacb-ca26c0a35c99health: HEALTH_WARN1 daemons have recently crashedservices:mon: 5 daemons, quorum k8sceph70201,k8sceph70202,k8sceph70203,k8sceph70204,k8sceph70205 (age 4d)mgr: k8sc…

vscode 同步插件

vscode 扩展商店链接 https://marketplace.visualstudio.com/vscode settings sync 插件

apache shiro 反序列化漏洞解决方案

apache shiro 反序列化漏洞解决方案 反序列化漏洞解决方案产生原因解决方案1:1.升级shiro至最新版本1.7.1解决方案2:修改rememberMe默认密钥,生成随机密钥。 反序列化漏洞解决方案 反序列化漏洞介绍 序列化:把对象转换为字符串或…

opencv、pillow和matplotlib的区别

参考文章:Python学习小技巧——opencv、pillow和matplotlib的区别_pillow和opencv区别-CSDN博客 1 概念的比较: opencv (1)默认不支持中文文件名 (2)数据为numpy,维度:高&#xff…

每日一练,蓝桥杯

蓝桥杯---链表类型题: 小王子排序 这一题要求用到单项列表来解决。也可以使用跨行接受解决,事不宜迟,直接上代码。 第一个,我使用的是链表法解决问题。 一.创建链表。 class Node:def __init__(self,data):self.data datase…

图片速览 PoseGPT:基于量化的 3D 人体运动生成和预测(VQVAE)

papercodehttps://arxiv.org/pdf/2210.10542.pdfhttps://europe.naverlabs.com/research/computer-vision/posegpt/ 方法 将动作压缩到离散空间。使用GPT类的模型预测未来动作的离散索引。使用解码器解码动作得到输出。 效果 提出的方法在HumanAct12(一个标准但小规…

AWS-WAF-CDN基于速率rate的永久黑名单方案(基于lambda实现)

参考方案(有坑), 所以产生了这篇博客: 点击跳转 1. 部署waf (有则跳过) 必须存在一个rate速率规则,后面的方案堆栈要用 新建rate速率规则 关联cdn资源 2.部署堆栈 (美国东部 (弗吉尼亚北部 …

短视频账号剪辑矩阵系统源码技术3年自研开发框架

短视频账号剪辑矩阵系统源码技术3年自研开发框架,这个市场截至到现在基本上违规开发的,没有正规接口开发的,基本上都已经筛选完了,目前各位技术者公司想要考察的话,只需要甄别3方面即可 1.剪辑是不是自己核心研发的&a…

正则表达式:简化模式匹配的利器

正则表达式:简化模式匹配的利器 一、正则表达式简介1.1 正则表达式介绍1.2 正则表达式使用场景 二、正则表达式语法2.1 正则表达式元字符和特性2.2 正则表达式常用匹配 三、正则表达式实战3.1 常见的正则表达式用法3.2 正则表达式的过滤用法3.3 正则表达式的代码用法…