MySQL-MVCC多版本控制及事务的隔离性

news2024/11/13 8:02:28

MySQL事务的启动方式

  1. 隐式:执行SQL语句自动提交(前提MySQL使用SET AUTOCOMMIT=1开启自动提交)
  2. 显式:begin/start transaction; update user set username = 'timi' where id =1; commit;

begin/start transaction命令并不是一个事务的起点,在执行到它们之后的第一个操作InnoDB表的语句,事务才真正启动。如果你想要马上启动一个事务,可以使用start transaction with consistent snapshot

MySQL的InnoDB引擎具有不同的事务隔离级别,不同事务隔离级别通过视图创建时机的不同来实现。

MySQL的两种视图

  • View:它是一个用查询语句定义的虚拟表,在调用的时候执行查询语句并生成结果。创建视图的语法是create view …,而它的查询方法与表一样。
  • 另一个是InnoDB在实现MVCC时用到的一致性读视图,即consistent read view,用于支持RC(Read Committed,读提交)和RR(Repeatable Read,可重复读)隔离级别的实现。

MySQL的MVCC快照

MVCC:Multiversion concurrency control,即多版本控制,在并发访问数据库时,通过对数据做多版本管理,也就是为每条记录保存多份历史数据供读事务访问,新的写入只需要添加新的版本即可,无需等待。避免因为写数据时要加写锁而阻塞读取数据的请求,实现读取数据不用加锁,读取数据同时修改。修改数据同时可读取。

多版本指的是数据表中同一个行数据可能会有多个版本(row),每次事务更新数据的时候,都会生成一个新的数据版本,并且把 transaction id 赋值给这个数据版本的事务 ID,记为 row trx_id,InnoDB复用了Undo log中已经记录的历史版本数据来满足MVCC的需求。

控制指的是,InnoDB使用Undo log控制不同的事务找到对应的数据版本。

InnoDB中每一个事务都有一个唯一的事务ID,叫做transaction id,每个事务在开始的时候向InnoDB事务系统申请的,其值按申请的顺序严格递增。

官方解释:

A unique transaction ID number, internal to InnoDB. These IDs are not created for transactions that are read only and nonlocking

Undo log

为形象说明undo log,举个例子。

现有数据表如下:

CREATE TABLE `t` (
  `id` int(11) NOT NULL,
  `k` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

一次执行执行insertupdate及再次update语句,对应的事务编号分别为:Transaction I、Transaction J、Transaction K,那么新插入的id=1的数据行就有三个版本,undo log记录的数据数据分别为:

undo_logicial

图片引用自taobao数据库月报。

undo log即为上图中的Rollptr,历史版本数据通过Rollptr穿成一个链表供MVCC使用。因此,undo log并不是在数据库中真实存在的,当需要查询某行数据历史版本时,可以通过Rollptr计算出。

Undo log与隔离级别的关系

数据可见性

一个事务在启动时声明:以我启动的时刻为准,如果一个数据版本是在我启动之前生成的,就认,如果事务在我启动后生成的,就不认,必须找到它的上一个可见的版本。如果数据是这个事务自己更新的数据,它还是要认的。

InnoDB为每一个事务构造了一个数组,用来保存这个事务启动的瞬间,当前正在“活跃”指的是,启动了还没提交。

数据里事务ID的最小值记为低水位,当前系统里边已经创建过的事务ID的最大值加1记为高水位。视图数组和高水位,组成了当前事务的一致性视图(read-view)。而数据版本的可见性规则,就是基于数据的row trx_id和这个一致性视图的对比结果得到的。

视图数组把所有的row trx_id分成了几种不同的情况。

img

对于事务启动瞬间来说,一个数据版本的row trx_id有以下几种可能:

对于当前事务的启动瞬间来说,一个数据版本的row trx_id,有一下几种可能:

  1. 如果落在绿色部分,表示这个版本是已提交的事务或者是当前事务自己生成的,这个数据是可见的。
  2. 如果落在红色部分,标识这个版本是由将来启动的事务生成的,是肯定不可见的。
    • 如果row trx_id在数组中,表示这个版本是由还没提交的事务生成的,不可见。
    • 如果row trx_id不在数组中,表示这个版本是已经提交的事务生成的,可见。

假设未提交事务数组中含有的row trx_id包含:90,91,92,96,93,94,95并未在未提交事务数组中,有一种可能性是:93,94,95事务执行较快,已提交。

一致性读

读操作基于某时间点得到一份那时的数据快照,无论其他数据对该行数据的修改,在查询过程中,若其他事务修改了数据,那么就要从undo log中获取旧版本的数据。

更新逻辑

规则:

更新数据都是先读后写的,读取的数据,读到的是当前最新版本值,称为“当前读”(current read)。

当某行数据被其他事务修改,拿到写锁还未释放时,“当前读”会等待写锁释放后再去执行。

可重复读与读提交

可重复读与读提交最大的区别是:

  • 可重复读隔离级别下,只需要在事务开始的时候创建一致性视图,之后的事务里的其他查询都共用这个一致性视图;对于可重复读,查询只承认在事务启动前就已经提交完成的数据。
  • 在读提交隔离级别下,每一个语句执行前都会重新算出一个新的视图。对于读提交,查询只承认在语句启动前就已经提交完成的数据。

举例

CREATE TABLE `t` (
  `id` int(11) NOT NULL,
  `k` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;
insert into t(id, k) values(1,1);

img

在可重复读隔离级别下,事务A查询到的k值为1,因为事务A首先启动,创建事务id,接着是事务B,事务B的row trx_id会大于事务A,落在高水位未开始事务中,数据修改对A不可见,事务C隐式开启事务,执行完成后隐式提交,由于同样C的row trx_id大于A,修改对于事务A版本依旧不可见,(即一致性读),所以事务A查询到的k值为历史版本1。

事务B查询到的k值为3,事务B首先开启事务,事务C随后开启,事务C将k=1修改为k=2,由于在修改时会使用“当前读”来查询数据的最新版本来保证数据的修改不会丢失,所以事务B在执行update语句前会查询到当前版本k=2,更新后k=3。

举例引用自极客时间《MySQL实现45讲》

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

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

相关文章

UE获取当前鼠标点击位置坐标

文章目录 1. 实现目标2. 实现过程2.1 蓝图代码2.2 实现思路3. 参考资料1. 实现目标 获取当前鼠标点击位置的UE世界坐标(x,y,z),效果如下图所示(为便于演示,下图显示了碰撞点位)。 2. 实现过程 2.1 蓝图代码 (1)核心函数的蓝图代码如下: (2)当鼠标左键按下时,…

【✨十五天搞定电工基础】一阶电路的暂态分析

本章要求1. 了解电阻元件、电感元件与电容元件的特征; 2. 理解电路的暂态和稳态、零输入响应、零状态响应、全响应的概念,以及时间常数的物 理意义; 3. 掌握换路定则及初始值的求法; 4. 掌握一阶线性电路分析的三要素法。 目录 一、一阶电路和换路定律 1…

第十四章 图的存储及图的DFS(超级详细!!逐行解析!!)

第十四章 图的存储及图的DFS一、图1、什么是图?2、图的存储(1)邻接矩阵(2)邻接表二、图的深度优先搜索1、思路2、模板(1)问题:如何求左右子树呢?什么时候记录呢?如何构造…

数字孪生场景、代码即开即用 | 图观™引擎 超详细功能范例演示

数字孪生已经从一项前沿技术,演变成为各行各业数字化转型的必选项。 过去想要构建数字孪生应用,要面对视觉设计、三维底座构建、代码开发、数据对接、部署联调等一系列复杂工作。不仅要了解复杂的数学基础知识、底层三维开发技术,还要熟知各…

Spring Cloud微服务迁移到Kubernetes容器化

文章目录相关文章k8s容器部署流程熟悉Spring Cloud微服务项目源代码编译构建构建项目镜像并推送到镜像仓库制作镜像将镜像推送到harbor仓库K8s服务编排部署基础环境在K8s中部署Nacos集群(注册和配置中心)在k8s中部署Seata分布式事务在linux部署mysql,red…

李炎恢ECMAScript6 / ES6+(二)

16.Set 数据集合 学习要点: 1.Set 数据集合 本节课我们来开始学习 ES6 新增的 Set 数据集合的用法; 一.Set 数据集合 1.ES6 之前只有数组一种数据结构,而现在提供了 Set 和 Map 两种集合; 严格来说,对象…

PC辉光效果一切正常,安卓辉光却没效果、显示异常(爆闪、黑屏等)

一:安卓端辉光不显示问题 问题描述:项目中使用unity的PostProcessing package实现辉光的功能,在pc上辉光效果一切正常,但是打出apk在真机测试时,辉光基本没效果。 解决思路:PostProcessing Bloom效果需要有…

【ArcGIS微课1000例】0056:将单波段栅格背景设置为无数据NoData的方法

本文讲解将单波段栅格背景设置为空值的方法,以DEM数据为例。 文章目录 一、DEM设置无数据二、注意事项单波段数据,一般只有DEM,遥感单波段影像,二值化图像等。 使用珊格计算器通过SetNull 函数(设定空值函数)可以将特定值计算为空值(NoData),SetNull的语法格式为: Se…

[附源码]Python计算机毕业设计Django教育企业网站

项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等等。 环境需要 1.运行环境:最好是python3.7.7,…

4-5:关注,取消关注

需求 开发关注、取消关注功能。 统计用户的关注数、粉丝数。 关键 若A关注了B,则A是B的Follower (粉丝),B是A的Followee (目标)。关注的目标可以是用户、帖子、题目等,在实现时将这些目标抽象为实体。 也是将数据存储到redis中,…

LeetCode刷题复盘笔记—一文搞懂0 - 1背包之494. 目标和问题(动态规划系列第九篇)

今日主要总结一下动态规划0-1背包的一道题目,494. 目标和问题 题目:494. 目标和 Leetcode题目地址 题目描述: 给你一个整数数组 nums 和一个整数 target 。 向数组中的每个整数前添加 ‘’ 或 ‘-’ ,然后串联起所有整数&#…

国外网友分享如何从零开始打造一辆真正的自动驾驶汽车

在 2021 年夏天大学二年级结束后,我决定从事当时最先进的项目之一——从头开发自动驾驶软件并在真车上实现。在公开我的代码的一些主要部分并发布演示视频后,我收到了很多关于该项目的问题。因此,我决定分享开发过程背后的故事。 我一直对与人工智能和机器学习相关的任何事…

Java代码审计——ClassLoader 类加载机制

目录 前言: (一)类加载机制 0x01 ClassLoader 类 0x02 loadClass()方法的流程 0x03 自定义的类加载器 0x04 loadClass()方法与 Class.forName 的区别 0x05 URLClassLoader (二)Java 动态代理 0x01 静态代理 0x02 动态代理…

2022最新 MySQL 内部技术架构面试题

更多面试题:https://javaxiaobear.gitee.io/ 47、MySQL内部支持缓存查询吗? 当MySQL接收到客户端的查询SQL之后,仅仅只需要对其进行相应的权限验证之后,就会通过Query Cache来查找结果,甚至都不需要经过Optimizer模…

dot product【点积】

(1)概念 点积在数学中,又称数量积(dot product; scalar product),是指接受在实数R上的两个向量并返回一个实数值标量的二元运算。 两个向量a [a1, a2,…, an]和b [b1, b2,…, bn]的点积定义为&#xff…

点云数据集ShapeNet

目录 1. 数据采集的作者 2. 下载shapenet数据集的代码 3. 数据特点 3.1 每个数字文件夹代表一个类别 3.2 synsetoffset2category.txt 3.3 train_test_split文件夹 3.4 pts点云文件 3.6 seg分割类别文件 1. 数据采集的作者 article{yi2016scalable,title{A scalable ac…

idea导入eclipse项目的时候,Java图标变成黄色小J了,怎么解决?

凯哥今天导入一个15年时候写的小项目,当时使用的是eclipse写的。最近好几年都在使用idea,习惯了idea的,在用eclipse,不习惯,不顺手,就导入到idea中。发现,Java文件的图标变成了黄色的J。如下图&…

【Linux】详解套接字编程

文章目录网络套接字1.端口号1.1认识端口号1.2端口号VS PID2.TCP与UDP协议3.网络字节序4.socket编程4.1常用接口4.2sockaddr结构4.3.socket接口的底层工作4.4字符串IP VS 整形IP4.5 bind与INADDR_ANY5.UDP聊天服务器5.1va_start和va_end5.2vsnprintf函数5.3自定义日志类5.4UDP服…

【RTS】杜金房大神FreeSwitch分享笔记

技术万变不离其宗不管如何实现原理都是一样的。杜金房大神 RTS 高可用 一台机器上俩fs,公用同一个ip用户连接的是一个ip,不知道切了fs。两台主备数据同步

ARM 汇编编写 LED 灯

一、一步步点亮LED 1. 硬件工作原理及原理图查阅 LED 本身有 2 个接线点,一个是 LED 的正极,一个是 LED 的负极。LED 这个硬件的功能就是点亮或者不亮,物理上想要点亮一颗 LED 只需要给他的正负极上加正电压即可,要熄灭一颗 LED…