Mysql中MVCC的使用及原理详解

2023-10-26

准备

测试环境:Mysql 5.7.20-log

数据库默认隔离级别:RR(Repeatable Read,可重复读),MVCC主要适用于Mysql的RC,RR隔离级别

创建一张存储引擎为testmvcc的表,sql为:

 
  1. CREATE TABLE testmvcc (

  2. id int(11) DEFAULT NULL,

  3. name varchar(11) DEFAULT NULL

  4. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

什么是MVCC?

英文全称为Multi-Version Concurrency Control,翻译为中文即 多版本并发控制。在小编看来,他无非就是乐观锁的一种实现方式。在Java编程中,如果把乐观锁看成一个接口,MVCC便是这个接口的一个实现类而已。

Mysql中MVCC的使用及原理详解

 

特点

1.MVCC其实广泛应用于数据库技术,像Oracle,PostgreSQL等也引入了该技术,即适用范围广

2.MVCC并没有简单的使用数据库的行锁,而是使用了行级锁,row_level_lock,而非InnoDB中的innodb_row_lock.

基本原理

MVCC的实现,通过保存数据在某个时间点的快照来实现的。这意味着一个事务无论运行多长时间,在同一个事务里能够看到数据一致的视图。根据事务开始的时间不同,同时也意味着在同一个时刻不同事务看到的相同表里的数据可能是不同的。

基本特征

  • 每行数据都存在一个版本,每次数据更新时都更新该版本。
  • 修改时Copy出当前版本随意修改,各个事务之间无干扰。
  • 保存时比较版本号,如果成功(commit),则覆盖原记录;失败则放弃copy(rollback)

InnoDB存储引擎MVCC的实现策略

在每一行数据中额外保存两个隐藏的列:当前行创建时的版本号和删除时的版本号(可能为空,其实还有一列称为回滚指针,用于事务回滚,不在本文范畴)。这里的版本号并不是实际的时间值,而是系统版本号。每开始新的事务,系统版本号都会自动递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询每行记录的版本号进行比较。

每个事务又有自己的版本号,这样事务内执行CRUD操作时,就通过版本号的比较来达到数据版本控制的目的。

MVCC下InnoDB的增删查改是怎么work的

1、插入数据(insert):记录的版本号即当前事务的版本号

执行一条数据语句:insert into testmvcc values(1,"test");

假设事务id为1,那么插入后的数据行如下:

Mysql中MVCC的使用及原理详解

 

2、在更新操作的时候,采用的是先标记旧的那行记录为已删除,并且删除版本号是事务版本号,然后插入一行新的记录的方式。

比如,针对上面那行记录,事务Id为2 要把name字段更新

update table set name= 'new_value' where id=1;

Mysql中MVCC的使用及原理详解

 

3、删除操作的时候,就把事务版本号作为删除版本号。比如

delete from table where id=1;

Mysql中MVCC的使用及原理详解

 

4、查询操作:

从上面的描述可以看到,在查询时要符合以下两个条件的记录才能被事务查询出来:

1) 删除版本号未指定或者大于当前事务版本号,即查询事务开启后确保读取的行未被删除。(即上述事务id为2的事务查询时,依然能读取到事务id为3所删除的数据行)

2) 创建版本号 小于或者等于 当前事务版本号 ,就是说记录创建是在当前事务中(等于的情况)或者在当前事务启动之前的其他事物进行的insert。

(即事务id为2的事务只能读取到create version<=2的已提交的事务的数据集)

补充:

1.MVCC手段只适用于Msyql隔离级别中的读已提交(Read committed)和可重复读(Repeatable Read).

2.Read uncimmitted由于存在脏读,即能读到未提交事务的数据行,所以不适用MVCC.

原因是MVCC的创建版本和删除版本只要在事务提交后才会产生。

3.串行化由于是会对所涉及到的表加锁,并非行锁,自然也就不存在行的版本控制问题。

4.通过以上总结,可知,MVCC主要作用于事务性的,有行锁控制的数据库模型。

关于Mysql中MVCC的总结

客观上,我们认为他就是乐观锁的一整实现方式,就是每行都有版本号,保存时根据版本号决定是否成功。

但由于Mysql的写操作会加排他锁(前文有讲),如果锁定了还算不算是MVCC?

了解乐观锁的小伙伴们,都知道其主要依靠版本控制,即消除锁定,二者相互矛盾,so从某种意义上来说,Mysql的MVCC并非真正的MVCC,他只是借用MVCC的名号实现了读的非阻塞而已。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Mysql中MVCC的使用及原理详解 的相关文章

  • Flask SqlAlchemy 连接两个模型,无需外键 MYSQL

    我正在加入两个没有外键的模型 Models class Users db Model tablename Users userName db Column db String primary key True lastLogin db Co
  • 将结果行强制转换为对象

    有没有办法将调用存储过程获得的结果行强制转换为特定对象 以便我可以仅将该对象的列表传递到视图中 我知道我可以使用 Node list 之类的东西来做到这一点 但我最终将用一个相当复杂的存储过程替换 getnodes 该存储过程创建临时表并执
  • Hibernate不生成级联

    我有一套hibernate hbm2ddl auto创建以便 Hibernate 为我在 mysql 中创建表 但是 休眠似乎没有正确添加Cascade关于表中的参考文献 然而 当我删除一行 并且我有一个删除级联作为休眠注释时 它确实有效
  • Over() 函数没有覆盖表中的所有行

    我正在使用 MySQL 练习 SQL 并在 SQL 中遇到了奇怪的行为 假设我有一张这样的表 Delivery table delivery id customer id order date customer pref delivery
  • 将数据导入mysql的最佳方法

    我有一个包含 500 000 行和大约 10 列的表 该表处于访问状态 我如何将其导入到mysql 这是关于该主题的文章 http www kitebird com articles access migrate html http www
  • sql 查询不适用于 order by

    这是我原来有效的查询 Select FROM story st sentences s speaker sp WHERE st lesson id 1 AND st speaker id sp speaker id AND st sente
  • 按“计数(列不为空)”排序

    我正在寻找一种方法 通过值不为空的列的计数来对 MySQL 结果进行排序 所以 id 1 1 0 1 1 4 id 0 1 1 1 0 3 id 0 0 0 1 1 2 id 1 0 0 0 0 1 在上面的例子中 我忽略了 ID 列 但实
  • AWS RDS 如何设置 MySQL 数据库

    我有一个 Java 应用程序成功运行在Amazon Web Services Elastic Beanstalk 我正在尝试设置MySQL 我已经创建了一个数据库实例 如您所见 问题一 如何将我的 Java 应用程序连接到数据库 我有以下代
  • 如何对表中的每一行运行特定的sql查询?

    所以我的数据库中有两个表 它们看起来都是这样的 通讯 拨打电话 Timestamp FromIDNumber ToIDNumber GeneralLocation 2012 03 02 09 02 30 878 674 Grasslands
  • 致命错误:无法在functions.php第25行中重新声明session_start()

    当我尝试让登录部分正常工作时遇到问题 我不断遇到的问题是 致命错误 无法在 public html login functions php 第 25 行重新声明 session start
  • 在 MySQL 中存储 IPv6 地址

    正如 需要支持 ipv6 的 inet aton 和 inet ntoa 函数 http bugs mysql com bug php id 34037 目前没有用于存储 IPv6 地址的 MySQL 函数 用于存储 插入的推荐数据类型 函
  • CentOs Php 和 MySql 配置

    我已经安装了 php 并运行了一段时间 但我开始从事一个连接到数据库 即 mysql 的项目 所以我安装了 mysql 5 1 73 现在当我使用它连接到数据库时线 dbhandle mysql connect hostname usern
  • 带有mysql的实体框架,linux和windows之间的表大小写问题

    我们目前正在开发一个使用 Code First Entity Framework 和 Mysql 的产品 开发数据库托管在 Windows 环境中 而生产 mysql 则托管在 Linux 环境中 我遇到的问题是 mysql 中的表命名如下
  • Codeigniter 活动记录选择、左连接、计数

    我有一个显示数据库查询结果的表单 这些结果可以有许多其他资产与之相连 我想找到一种方法来显示每个元素有多少资产 例如 我的表是英格兰地区 另一个表是用户居住的地方 我当前有这个代码 this gt db gt select this gt
  • Symfony2 - 访问被拒绝(用户未经过完全身份验证)

    我正在使用 Symfony2 开发一个网站 直到今天 登录没有问题 但现在登录时我没有正确验证 Symfony 分析器将我列为logged in as anon而不是我登录的用户 我还被重定向回登录页面而不是目标路径 登录过程由传统的登录表
  • MySQL 存储映像 BLOB 不良实践性能

    我知道不建议在 SQL 中将图像存储为 BLOB 然而 在我的本地 PC 和服务器上同时工作使得在两者之间同步图像变得困难 是否还有理由不单独使用 BLOB 作为备份 这会在本地创建缓存文件 以静态方式提供服务 本质上 只有选择 BLOB
  • MySQL 监听通知等效项

    是否有相当于 PostgresQL 的notify http www postgresql org docs 9 1 static sql notify html and listen http www postgresql org doc
  • 课程完成时更新外部数据库

    我的场景 Moodle 中的用户完成了一门课程 一旦发生这种情况 我想更新外部数据库 我的理解是 每次运行 cron 作业时都会触发 course completed 事件 使用一些简单值 例如已完成课程的用户名 ID 课程 ID 以及完成
  • mysql_insert_id 带更新

    执行下面的查询后 我使用 PHP 函数mysql insert id 它总是给我0 UPDATE tbl training types SET fld serial serial no fld name training name fld
  • 基于 MySQL 中的另一列创建计算列

    我的表中有 2 列 varchar 8 and an int 我想要auto increment the int column当我这样做时 我想将值复制到varchar 8 column 但用 0 填充它直到它达到 8 个字符长 因此例如

随机推荐

  • k8s基本问题排查

    排查pod故障 查看pod是否正常 kubectl get pods n fronted 常见pod排查命令 kubectl logs
  • Docker

    目录 1 离线安装 1 1 下载Docker离线包 1 2 下载离线安装工具 1 3 安装 1 4 镜像加速 1 4 1 下面命令直接生成文件 daemon json 1 4 2 重新加载docker配置 1 4 3 重启docker服务
  • Android Animation.setAnimationListener()失效问题

    Android执行动画 使用Animation情景如下 Animation animation new Animation 如果需要监听动画执行 animation setAnimationListener 需要在 view startAn
  • Conda错误:Collecting package metadata (current_repodata.json): failed

    conda新安装设置清华源后发现并没有使用 且会出现错误 Collecting package metadata current repodata json failed 换了科大源也没成功 考虑可能是默认源的问题 删除 condarc文件
  • TCP/IP详解学习笔记(4)-ICMP协议,ping和Traceroute

    1 IMCP协议介绍 前面讲到了 IP协议并不是一个可靠的协议 它不保证数据被送达 那么 自然的 保证数据送达的工作应该由其他的模块来完成 其中一个重要的模块就是ICMP 网络控制报文 协议 当传送IP数据包发生错误 比如主机不可达 路由不
  • STM32F103ZET6【HAL函开发】STM32CUBEMX------1.GPIO输出-点亮led灯

    一 硬件介绍 正点原子战舰开发板 主控芯片STM32F103ZET6 两个LED分别连接到单片机的PB5和PE5 二 STM32CUBEMX基础配置 2 1 晶振配置 如果你的板子上外部高速晶振8M和外部低速晶振32 768K都有的话 那么
  • Java中如何自定义数组

    Java中如何自定义数组 数组是一种非常常见的数据结构 在Java中也是一个非常重要的概念 在Java中 数组的定义和使用非常简单 但是如果我们想要自定义数组 那么可能需要一些额外的操作 Java中如何自定义数组 在Java中 数组是一种简
  • 华为OD机试 - 分苹果(Java)

    题目描述 A B两个人把苹果分为两堆 A希望按照他的计算规则等分苹果 他的计算规则是按照二进制加法计算 并且不计算进位 12 5 9 1100 0101 9 B的计算规则是十进制加法 包括正常进位 B希望在满足A的情况下获取苹果重量最多 输
  • 【转载】区块链技术原理、应用领域及挑战

    区块链技术原理 应用领域及挑战 李董 魏进武 中国联合网络通信有限公司研究院 北京 100032 引用本文 李董 魏进武 区块链技术原理 应用领域及挑战 电信科学 J 2016 32 12 20 26 doi 10 11959 j issn
  • 小米手机解BL锁教程

    1 找到设置 找到我的设备 2 点击全部参数 多点几下miui版本 直到弹出开发者模式提醒 3 返回 找到更多设置 4 找到开发者选项
  • Linux设备上时间不准确?使用chrony服务配置时间服务器实现Linux时间同步以及实现主从设备时间同步

    本文基于Linux上CentOS 7版本配合chrony 需要使用yum自行下载 进行演示 目录 一 计算机设备上的两种时间 1 硬件时间 2 系统时间 二 配置同步时间服务器 1 安装服务 2 配置服务 三 搭建主从时间服务器 1 服务器
  • 阿里云提示ECS服务器存在漏洞处理方法

    1 阿里云提供生成修复命令 但是这个只提供给企业版 即收费的 2 自己手动修复的话 采用软件升级一般都可以解决 除了提示带kernel的高危漏洞的 其他的不需要重启实例即可修复 有kernel的需要更新完成重启实例 这里可以先把 漏洞名称
  • 2021-04-08 使用Eclipse进行Web前端开发

    使用Eclipse进行Web前端开发 前言 本机为微软Surface pro4 为64位 所用操作系统为Windos 10 使用的Java版本为1 8 0 151 使用的JDK版本为JDK8 注意事项 1 Eclipse安装插件的时候一定要
  • 【mac】Mac 安装 RabbitMQ

    文章目录 1 概述 2 安装brew 3 安装 4 安装RabiitMQ的可视化监控插件 5 配置环境变量 6 后台启动 rabbitMQ 7 创建rabbitmq账号 8 给账号配置角色 1 概述 学习spring cloud 的时候 因
  • 【pytorch】pytorch模型保存技巧

    Pytorch会把模型相关信息保存为一个字典结构的数据 以用于继续训练或者推理 1 保存与加载模型参数 这是最常见的模型保存与加载方式 保存方式如下 state model state dict torch save state xxx p
  • qml实现红绿灯切换功能

    题目要求 参考代码 https download csdn net download y478225902 5260541 实现源码 import QtQuick 2 12 import QtQuick Window 2 12 Window
  • springboot整合maven Profile实现properties文件多环境配置

    步骤 首先写几个properties的配置文件 一般这样的文件有三个 而且文件的名称也也可以随意 不论你们的项目是使用的springmvc还是springboot 文件名称都可以随意指定 例如我的几个文件 在文件中写一些测试的属性值 方便测
  • 【一】重温HTML

    引言 经典对答 面试官 你了解HTML吗 回答 啊 我是来面试前端的呀 我会Vue 面试官 写文思考 写这一系列文章的时候 自己思考了几个问题 HTML的文章太多了 为什么还要写 HTML的入门谁不会 还要学 HTML的文章基本都是水文 谁
  • ES6解构赋值

    前面的话 我们经常定义许多对象和数组 然后有组织地从中提取相关的信息片段 在ES6中添加了可以简化这种任务的新特性 解构 解构是一种打破数据结构 将其拆分为更小部分的过程 本文将详细介绍ES6解构赋值 引入 在ES5中 开发者们为了从对象和
  • Mysql中MVCC的使用及原理详解

    准备 测试环境 Mysql 5 7 20 log 数据库默认隔离级别 RR Repeatable Read 可重复读 MVCC主要适用于Mysql的RC RR隔离级别 创建一张存储引擎为testmvcc的表 sql为 CREATE TABL