《MySQL MVCC 》

什么是 MySQL InnoDB 的 MVCC?

MVCC (Multi-Version Concurrency Control)是一种基于多版本的并发控制协议,只有在 InnoDB 引擎下存在。MVCC 是为了实现事务的隔离性,即通过版本号,避免同一数据在不同事务间的竞争,可以把它当成基于多版本号的一种乐观锁。当然,这种乐观锁只在事务级别读已提交(RC)和可重复读(RR)有效。MVCC 最大的好处,读不加锁,读写不冲突。在读多写少的应用中,读写不冲突是非常重要的,极大的增加了系统的并发性能。

前置了解知识:

MySQL 的核心日志有哪些?

MySQL 中有七种日志文件,分别是:redo log(重做日志)undo log(回滚日志)bin log(二进制日志)、error log(错误日志)、slow query log(慢查询日志)、general log(一般查询日志),relay log(中继日志)

bin log: 就是 binary log,二进制日志文件,记录了 MySQL 所有的 DDL 和 DML (除了数据查询语句)操作,以事件形式记录,还包含语句所执行的消耗的时间,MySQL 的二进制日志是事务安全型的。通过 bin log 日志我们可以做数据恢复,增量备份,主主复制和主从复制等等

undo log: 是 MySQL 用来记录事务操作的 反方向逻辑日志,顾名思义,undo log是一种用于撤销回退的日志,在事务没提交之前,MySQL 会先记录更新前的数据到 undo log 日志文件里面,当事务回滚时或者数据库崩溃时,可以利用 undo log 来进行回退

redo log: 是 InnoDB 存储引擎产生的,记录事务对数据页的修改,如果 mysql 挂了,重启后 InnoDB 会使用redo log 恢复数据,保证了数据的持久性

数据库的事务特性 (ACID)有哪些?

  • 原子性(Atomicity):事务中的全部操作在数据库中是不可分割的,要么全部完成,要么全部不执行

  • 持久性(Durability): 对于任意已提交事务,系统必须保证该事务对数据库的改变不被丢失,即使数据库出现故障

  • 隔离性(Isolation):事务的执行不受其他事务的干扰,事务执行的中间结果对其他事务必须是透明的

  • 一致性(Consistency):几个并行执行的事务,其执行结果必须与按某一顺序串行执行的结果相一致

MySQL 数据库的隔离级别有哪些,都会产生什么样的问题?

脏读

脏读指的是读到了其他事务未提交的数据,未提交意味着这些数据可能会回滚,也就是可能最终不会存到数据库中,也就是不存在的数据。读到了并一定最终存在的数据

不可重复读

不可重复读指的是在一个事务内,最开始读到的数据和事务结束前的任意时刻读到的同一批数据出现不一致的情况。

幻读

同样一笔查询在整个事务过程中多次执行后,查询所得的结果集是不一样的。也是指当事务不独立执行时,插入或者删除另一个事务当前影响的数据而发生的一种类似幻觉的现象。

什么是 MySQL InnoDB 当前读、快照读?

什么是当前读?

它读取的数据库记录,都是当前最新的版本,会对当前读取的数据进行加锁,防止其他事务修改数据。是悲观锁的一种操作。

如下操作都是当前读:

  • select lock in share mode(共享锁)

  • select for update(排他锁)

  • update(排他锁)

  • insert(排他锁)

  • delete(排他锁)

  • 串行化事务隔离级别

什么是快照读?

快照读的实现是基于多版本并发控制,即 MVCC,既然是多版本,那么快照读到的数据不一定是当前最新的数据,有可能是之前历史版本的数据。普通的 select 查询语句(即不加锁的 select 操作)就是快照读

重要:后续图解会进行演示

Read Committed 隔离级别:每次 select 都生成一个快照读。

Read Repeatable 隔离级别:开启事务后第一个 select 语句才是快照读的地方,而不是一开启事务就快照读。即仅在第一次执行快照读时生成

为什么需要 MVCC?

  • 读写锁的出现

读锁和读锁之间不互斥,而写锁和写锁、读锁都互斥。这样就很大提升了系统的并发能力。之后人们发现并发读还是不够

  • MVCC 概念出现

能不能让读写之间也不冲突的方法,就是读取数据时通过一种类似快照的方式将数据保存下来,这样读锁就和写锁不冲突了,不同的事务 session 会看到自己特定版本的数据。当然快照是一种概念模型,不同的数据库可能用不同的方式来实现这种功能

总结MVCC 最大的优点是读不加锁,因此读写不冲突,并发性能好,类比 Java 中的读写锁,它是会存在读写竞争的,会有这个性能问题。MVCC 在 MySQL InnoDB 中的实现主要是为了提高数据库并发性能,用更好的方式去处理读-写冲突,做到即使有读写冲突时,也能做到不加锁,非阻塞并发读

MVCC 实现的原理

MySQL MVCC 实现原理:

具体实现主要是由 隐式字段 + undolog 版本链 + read view 的方式实现

隐式字段:

  • DB_TRX_ID:最近修改(修改/插入)事务ID:记录创建这条记录/最后一次修改该记录的事务 ID,这个 id 是递增的

  • DB_ROLL_PTR:回滚指针,指向这条记录的上一个版本

图解:

id

name

DB_TRX_ID

DB_ROLL_PTR

1088

张三

1

0x1232123

undolog 版本链是什么?

在每次更新该记录后,都会将旧值放到一条 undo 日志中。随着更新次数的增多,所有的版本都会被 roll_pointer 属性连接成一条链表,这个链表就称之为版本链。

图解:

Read View 是什么?

原文:

read view

An internal snapshot used by the MVCC mechanism of InnoDB. Certain transactions, depending on their isolation level, see the data values as they were at the time the transaction (or in some cases, the statement) started. Isolation levels that use a read view are REPEATABLE READ, READ COMMITTED, and READ UNCOMMITTED.

Read View是一个数据库的内部快照,该快照被用于 InnoDB 存储引擎中的 MVCC 机制。简单点说,Read View 就是一个快照,保存着数据库某个时刻的数据信息。Read View 会根据事务的隔离级别决定在某个事务开始时,该事务能看到什么信息。就是说通过 Read View,事务可以知道此时此刻能看到哪个版本的数据记录(有可能不是最新版本的,也有可能是最新版本的)。可重复读、读已提交、读未提交,这几个隔离级别都会使用 Read View

通俗点我的理解,Readview 是一个数据结构,包含四个字段,Read View 是"快照读" SQL 执行时 MVCC 提取数据的依据和规则

ReadView 包含的内容:
  • m_ids:当前活跃的事务编号集合即还未提交

  • min_trx_id:最小活跃事务编号

  • max_trx_id:预分配事务编号,当前最大事务编号 +1

  • creator_trx_id: ReadView 创建者的事务编号

ReadView 提取数据得规则:

1、被访问的 trx_id 与 readview 中的 creator_trx_id 相同,表示当前事务在访问自己修改的记录,可见,返回;

2、被访问的 trx_id 小于 min_trx_id,表明该版本已提交,可见,返回;

3、被访问的 trx_id 大于等于 max_trx_id ,表明该版本在生成 readview 时,还未开启,不可见,返回;

4、被访问的 trx_id 在 min_trx_id 和 max_trx_id 之间,判断是否在 m_ids 中,如果在,则说明生成 readview时,该版本事务未提交,该版本不可见;如果不在,则说明生成 readview 时,该版本事务已提交可见,返回。

案例图解说明:

思考:RC、RR 两种隔离级别下,两次查询的结果是什么?

答案:

RR 级别: select1="张三" select2="张三"

RC 级别: select1="张三" select2="张小三" RC 隔离级别下出现了"不可重复读",后续讲解为什么

上述问题的产生以及 ReadView 解析:

RC 级别下得 read view 图解分析

1. 这是第两次我们进行 select 语句 read view 给我们生成的:

 2. 第一次 select 语句分析图解:

 

3. 第二次 select 语句分析图解:

 

4. 产生的问题:

在 RC 隔离级别下,两次 select 语句读取到的内容不一致问题,即证明了 MySQL 数据库的隔离级为 RC 级别下会产生不可重复读问题,再次证实前置了解知识模块中的不同隔离级别产生的问题所述。原因是 READ COMMITTD 在每一次进行普通 SELECT 操作前都会生成一个 ReadView

RR 级别下得 read view 图解分析

 

1. 连续多次快照读,ReadView 会产生复用,没有幻读问题
2. RR 级别下使用 MVCC 能避免幻读吗?

答案能,但不完全能!

特例:当两次快照读之间存在当前读,ReadView会重新生成,导致产生幻读

MVCC 总结:

所谓的MVCC(Multi-Version Concurrency Control ,多版本并发控制)指的就是在使用读已提交(READ COMMITTD)、可重复读(REPEATABLE READ)这两种隔离级别的事务在执行普通的 SELECT 操作时访问记录的版本链的过程,这样子可以使不同事务的读-写、写-读操作并发执行,从而提升系统性能。

这两个隔离级别的一个很大不同就是:生成ReadView的时机不同,READ COMMITTD 在每一次进行普通 SELECT操作前都会生成一个 ReadView,而 REPEATABLE READ 只在第一次进行普通 SELECT 操作前生成一个ReadView,数据的可重复读其实就是 ReadView 的重复使用。

扩展知识:

1. "当前读" 的实现是基于 next-key lock (行记录锁+Gap间隙锁)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Job 和 DaemonSet

一、Job 1、Job 背景问题 K8s 里,最小的调度单元是 Pod,如果直接通过 Pod 来运行任务进程,会产生以下几种问题: ① 如何保证 Pod 内进程正确的结束? ② 如何保证进程运行失败后重试? ③ 如何管理多个任…

python在flask中的请求数据“无限流”

文章目录 一、问题描述二、解决方案 一、问题描述 在flask请求中,有个需求是让调用方一直调接口,并立马返回,而接口方缓存请求,依次执行。 二、解决方案 from flask import Flask, request, jsonify from queue import Queue i…

vue实现列表自动无缝滚动列表

大家好,今天给大家分享的知识是vue基于vue-seamless-scroll实现自动无缝滚动列表 一、实现自动滚动 最近在开发过程中遇到一个问题,就是需要实现自动滚动列表,效果图如下 就是这样一个列表在自动循环展示。在这里我是运用的 vue-seamless-sc…

数据结构——链表OJ题

目录 1.给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val val 的节点,并返回 新的头节点 。 2.给定一个带有头结点 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点…

C#开发AGV地图编辑软件

C#自己开发AGV地图编辑软件: 1、自由添加和删除站点、停车位、小车、运行路径。 2、编辑得地图以XML文件保存。 3、导入编辑好地图的XML文件。 4、程序都是源码,可以直接在此基础上进行二次开发。 下载链接:https://download.csdn.net/d…

[极客挑战2019]HTTP

这道题考察的是http请求头字段的含义和使用; 具体如下 Referer:来源地址 User-Agent:客户端配置信息:浏览器类型、版本、系统类型等 X-Forwarded-For:代理地址,即数据发出的地址 开始解题:(对我这初学者真的烧脑&a…

解决数学计算公式在前端项目里的展示,涉及换肤适配各个框架

有时候我们项目里面会嵌套一些数学公式说明 例如 可能你会发现市面上有很多的第三方库可以实现,比如: MathJax: https://www.mathjax.org/ 但是我们项目里面用到公式可能就一个页面,引一个第三方库进来会显得十分臃肿&#xff0…

【python】linux系统python报错“ssl module in Python is not available”

一、问题现象 1.1 执行pip命令报错 pip安装时遇到openssl问题,没办法安装第三方库 “WARNING: pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available. ” 1.2 导入import ssl 报错 直接执行python&…

【Flink网络通讯(一)】Flink RPC框架的整体设计

文章目录 1. Akka基本概念与Actor模型2. Akka相关demo2.1. 创建Akka系统2.2. 根据path获取Actor并与之通讯 3. Flink RPC框架与Akka的关系4.运行时RPC整体架构设计5. RpcEndpoint的设计与实现 我们从整体的角度看一下Flink RPC通信框架的设计与实现,了解其底层Akka通…

IDEA 2023.2 配置 JavaWeb 工程

目录 1 不使用 Maven 创建 JavaWeb 工程 1.1 新建一个工程 1.2 配置 Tomcat 1.3 配置模块 Web 2 使用 Maven 配置 JavaWeb 工程 2.1 新建一个 Maven 工程 2.2 配置 Tomcat 💥提示:IDEA 只有专业版才能配置 JavaWeb 工程,若是社区版&am…

VIO第3讲:基于优化的IMU与视觉信息融合之最小二乘详解

第3讲:基于优化的IMU与视觉信息融合之最小二乘详解 文章目录 第3讲:基于优化的IMU与视觉信息融合之最小二乘详解1 最小二乘问题求解1.1 基础概念1.2 总结1.1 基础:最速下降法,牛顿法, 阻尼法1.1.1 迭代法1.1.2 最速下降法&#xf…

OAuth2.0 最简向导

本文是一篇关于OAuth2.0的启蒙教程,图文并茂,通俗易懂,力求用最简洁明了的方式向初学者解释OAuth2.0是什么。本文并不是冗杂难懂的长篇大论,一图胜千言,深入浅出OAuth2.0,知其然知其所以然。 参考文献 首…

DDI中的自适应子结构

SA-DDI提出了一种子结构感知图神经网络,一种配备了子结构注意力机制和用于DDI预测的子结构-子结构交互模块(SSIM)的消息传递神经网络。具体而言,基于分子中官能团的尺寸和形状通常是不规则的化学直觉,子结构注意力被设…

大模型时代下做科研的四个思路【论文精读·52】

大家好,上个礼拜FacebookMetaAI刚刚开源了他们自己的一个语言的大模型,叫做LLAMA,这个LLAMA的模型有65billing的参数,效果自然是不错的。他们的目的也是想让这个大模型更加的亲民,能够让更多人拿到这个模型的参数&…

ClickHouse快速上手

简介 ClickHouse是一个用于联机分析(OLAP)的列式数据库管理系统(DBMS) 官网(https://clickhouse.com/docs/zh)给出的定义,其实没看懂 特性 ClickHouse支持一种基于SQL的声明式查询语言,它在许多情况下与ANSI SQL标准相同。使用时和MySQL有点相似&#…

加固平板电脑在无人机的应用|亿道三防onerugged

无人机技术的快速发展已经在许多领域展现出巨大潜力,而加固平板电脑的应用在无人机领域中扮演着重要角色。 首先,加固平板电脑在无人机探测设备中发挥着关键作用。无人机探测设备通常需要实时传输高清图像和数据,以支持各种监测、勘测和检测…

JAVA高并发——无锁与死锁

文章目录 1、与众不同的并发策略:比较交换2、无锁的线程安全整数:AtomicInteger3、Java中的指针:Unsafe类4、无锁的对象引用:AtomicReference5、带有时间戳的对象引用:AtomicStampedReference6、数组也能无锁&#xff…

Unity2023.1.19_ShaderGraph节点说明以及使用技巧

Unity2023.1.19_ShaderGraph节点说明以及使用技巧 目录 Unity2023.1.19_ShaderGraph节点说明以及使用技巧 1. 快捷键CtrlG完成和UE蓝图使用快捷键C一样的蓝图分组注释效果: 2. Tiling And Offset: 3. 以下是两组URP材质渲染的效果对比: 4…

JWT 重点讲解

JWT 重点讲解 文章目录 JWT 重点讲解1. JWT 是什么2. JWT 的组成2.1 第一部分 HEADER2.2 第二部分 PAYLOAD2.3 第三部分 SIGNATURE 3. JWT 在线生成与解析4. JWT 的特点4.1 无状态4.2 可自定义4.3 扩展性强4.4 调试性好4.5 安全性取决于密钥管理4.6 无法撤销4.7 需要缓存到客户…

Android基础Adapter适配器详解

一、概念 Adapter是后端数据和前端显示UI的适配器接口。常见的View如ListView、GridView等需要用到Adapter. BaseAdapter:抽象类,实际开发中继承这个类并且重写相关方法,用得最多的一个Adapter! ArrayAdapter:支持泛型…