MySQL 的事务与多版本并发控制(MVCC)的那些事

    • 什么是事务
          • 原子性:
          • 一致性
          • 隔离性
        • 问题1: 为什么MySQL要使用mvcc实现隔离性而不使用 锁 解决并发问题?
          • 持久性
        • 问题2: MySQL 不是磁盘数据库吗,持久化为什么是 redo log 保证的?
        • 问题 3: redo log 储存了什么东西,持久化(崩溃恢复是怎么做的?)
        • 问题 4 : MySQL 的 bing log (二进制日志)已经有全量的数据,为什么还要使用 redo 做崩溃恢复,为什么不直接使用 bin log做崩溃恢复.
        • 问题 5 :redo log与 bin log 如何保证数据的一致性?
    • MySQL 的 MVCC 多版本并发控制
      • 事务的read view(事务能感应到的数据有哪些?)
    • 事务的隔离级别
        • 读未提交
          • 脏读问题
        • 读提交
          • 不可重复读问题
          • 幻读问题
        • 可重复读(默认级别)
        • 串行化
        • 问题 6 : 可重复读可以完全避免幻读的问题吗?
        • 问题 7 : 你们公司(之前的业务)使用的什么隔离级别?

MySQL 数据的版本链(undo log)

MySQL 的数据有两个隐藏列,

  • 第一是当前数据的版本(修改数据的事务 id)
  • 第二的指向数据之前状态的指针(指向的是一行 undo log 日志)
    在这里插入图片描述
    这样我们的数据就像链条一样可以获取到之前数据的版本(做回滚与 mvcc 都非常有用)

什么是事务

ACID

原子性:

任务要么全部成功要么全部失败,不存在只执行一部分的情况

  • 原子性是通过undo log(回滚日志),当事务失败就会将数据回滚到之前的状态
一致性
  • 事务前后始终保持一致性约束: 比如之前有唯一键约束,事务后也保持唯一键约束.(程序按照程序员的规则运行)
隔离性
  • 多事务并行的时候是相互不影响的(通过 mvcc 实现 : 多版本并发控制)
问题1: 为什么MySQL要使用mvcc实现隔离性而不使用 锁 解决并发问题?
  1. 锁会阻塞其他的事务,而多版本并发控制,通过数据版本链事务能感应到的数据,可以避免阻塞.–提高性能
  2. 锁并不满足事务(多个任务)的原子性,如果事务失败需要通过版本链将全部的任务修改的数据都回到事务开启前的状态
  3. 所以 MySQL 是锁与 mvcc 共用一起保证事务的隔离与原子性(比如修改单行数据:事务先上行排他锁,执行任务;事务提交后再释放锁),这样可以避免数据更新丢失的问题并且可以在失败的时候将数据回滚到之前的状态.
持久性
  • 事务提交后数据将持久化,不会因为故障丢失数据(redo log(重做日志) 实现)
问题2: MySQL 不是磁盘数据库吗,持久化为什么是 redo log 保证的?
  1. 数据持久化磁盘的消耗比较大(慢),MySQL 储存数据的流程是
    • 先存缓冲区(内存),再找合适的时机落盘,这样性能会高非常多(内存的 io 有百万,千万级 qps)
    • 但是如果数据没来得及落盘,服务就崩溃了(断电),那么数据就有丢失的风险

redo log(重做日志): 解决崩溃恢复的数据丢失问题

  1. redo log会记录写(命令)数据的偏移量(数据做了什么修改)
  2. redo log会通过追加的形式将日志记录到磁盘
  3. redo log 的落盘机制(可以设置的)
    • 事务提交立即落盘
    • 事务提交落用户缓冲区(每隔 1s,自动落盘/占用缓冲区一半自动落盘)-只要 MySQL 服务宕机数据就会丢
    • 事务提交落内核缓存(由内核缓存决定落盘时机)-只要操作系统正常数据就不会丢
  • 记录 redo log 比数据落盘更快,因为日志是顺序写(追加的形式),而数据直接落盘需要找到数据对应的位置
问题 3: redo log 储存了什么东西,持久化(崩溃恢复是怎么做的?)
  1. redo log会记录写(命令)数据的偏移量(数据做了什么修改)
  2. redo log会通过追加的形式将日志记录到磁盘
  3. redo log 的落盘机制(可以设置的)
    • 事务提交立即落盘
    • 事务提交落用户缓冲区(每隔 1s,自动落盘/占用缓冲区一半自动落盘)-只要 MySQL 服务宕机数据就会丢
    • 事务提交落内核缓存(由内核缓存决定落盘时机)-只要操作系统正常数据就不会丢
  • 记录 redo log 比数据落盘更快,因为日志是顺序写(追加的形式),而数据直接落盘需要找到数据对应的位置
问题 4 : MySQL 的 bing log (二进制日志)已经有全量的数据,为什么还要使用 redo 做崩溃恢复,为什么不直接使用 bin log做崩溃恢复.
  • bin log 是一个比较重的服务,因为是储存全量的数据,文件比较大,一个文件写满了会创建新的文件继续写(无限空间),并且 bin log是不会默认开启的,而是手动的开启(需要数据备份,或者配置主从才会使用)

  • redo log 是一个比较轻的服务,专门做数据的崩溃恢复的,他只记录近期的数据(没有持久化到磁盘的数据),采用的循环写的策略,如果 redo log 写满了,会循环覆盖之前的内容,所以消耗的空间是有限的

  • bin log当然可以做数据恢复,因为也是追加的数据修改的日志(可以做全量数据恢复的东西自然可以做数据崩溃的恢复)

  • 没有必要只为了数据恢复而强制开启一个比较重的服务(bin log),有点拿大炮打苍蝇的感觉

问题 5 :redo log与 bin log 如何保证数据的一致性?

为什么要一致性?

  1. bin log是配置主从的,从数据库复制的 bin log
  2. 如果数据不一致,那么数据主从数据库的数据就会不一致

redo log 是事务开始的时候就会记录(用于事务途中的崩溃回滚)
bin log 是事务提交时记录的,事务提交数据更新生效,同步从节点数据

redo log 双写:

  1. 写的命令执行前:记录 redo log ,登记为待提交状态

    • 这时候崩溃,就会回滚,不生效
  2. 事务提交:记录 bin log,再将 redo log 登记为提交状态

    • binlog 记录成功后将 redo log 登记为生效状态,避免 redo log 与 bin log 数据不一致导致的主从数据不一致问题

(问: 什么先记录 redo log,崩溃恢复 redo log 再刷的时候 也可以重新记录 没记录的 bin log? 搞不懂)

MySQL 的 MVCC 多版本并发控制

事务的read view(事务能感应到的数据有哪些?)

read view

  • 事务号(id)
  • 当前活跃事务列表(ids) : 表示已经开始但是没有提交的事务
  • 事务开始时列表中最小的事务号min: 事务开始时最小的活跃事务 id
  • 事务开始时列表中最大的事务号+1(max): 事务开始时最大的活跃事务 id+1

哪些数据版本是当前事务可见的?

提交可见原则:

  1. 小于(min)的数据版本是可见的:小于min 说明事务开启前,该版本的数据已经提交生效了
  2. 小于 max 但是不再 ids(活跃列表中的)是可见的:
    • 小于 max 表示事务开启前,改版本的事务已经开启(这是前提,因为>= max表示事务开启时,该数据的事务并没有开启,肯定是不可见的),
    • 不在 ids 中的事务:不在 ids 中表示事务已经提交,证明数据可见

MySQL 事务就根据数据的版本链找到自己可以感应到的数据的版本进行读取,实现多版本并发控制

事务的隔离级别

读未提交

读取版本链中最新的版本的数据(不判断是否可见)

脏读问题
  • 事务 b 修改一条数据(未提交),事务 a 读取这条数据,这时 b 事务回滚,事务 a 再一次读取这个数据
  • 这时事务 a 中两次读取的数据的结果是不一样的,这就是脏读
读提交

通过 read view 读取自己能感应到的最新版本的数据

  • 可以避免脏读的问题
不可重复读问题
  • 事务 a 读取一条数据,之后事务 b 修改这条数据(提交),事务 a 再一次读取数据,
  • 这时事务 a 中两次读取的数据的结果是不一样的,这就是不可重复读
    (思考: 事务在查询的时候已经持有该条数据的资源(共享锁),其他事务就无法操作该数据(加排他锁),还会有不可重复读的问题吗?
幻读问题
  • 事务 a 读取m 到 n 区间的数据, 之后事务 b 添加一条 m 到 n 区间的数据 ,事务 a 再一次读取m 到 n 区间的数据数据,
  • 这时事务 a 中两次读取的数据的结果(条数)是不一样的,这就是幻读.
可重复读(默认级别)
  • 也是通过 read view 读取自己可以感应到的数据的版本,

  • 但是不同的是,可重复读的活跃事务列表(ids)是一个拷贝,不会变化,所以只能读取到事务开始时数据的样子,中间就算有提交的更改也是感应不到的

  • 可以避免不可重复读与幻读(一定程度上)问题

串行化
  • 前一个事务执行完成,下一个事务才能执行
  • 就类似单线程依次的执行,一般很少使用,性能太低
问题 6 : 可重复读可以完全避免幻读的问题吗?

不可以,有两种情况可重复读还是会出现幻读

  1. 事务 A(读区间,更改区间,再读区间);事务 B(在事务 A期间,更改前插入或者删除了某条数据),会出现幻读的情况
  2. 事务A先用读快照(普通 select), 事务 B 插入一条数据,再使用读当前(select…for update)就会出现幻读

可以理解update 是要使用最新的数据进行 update,就会去发现最新的数据,可见范围就变了,就出现了幻读.

问题 7 : 你们公司(之前的业务)使用的什么隔离级别?
  • 很多时候不会在意,重复读,幻读的问题(很少有人会再同一个事务中做两次相同的查询/范围)
  • 所以一般情况下:读提交的隔离级别就已经够用了
  • 所以很多团队会选择读提交的隔离级别,而不是默认的可重复读
  • 为什么?
    • 隔离级别越高性能越低,读提交的性能要稍微好一点.

参考
https://blog.csdn.net/dengjiayue/article/details/144537660?fromshare=blogdetail&sharetype=blogdetail&sharerId=144537660&sharerefer=PC&sharesource=dengjiayue&sharefrom=from_link

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

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

相关文章

27.Java 线程间通信(synchronized 实现线程间通信、Lock 实现线程间通信)

一、线程间通信 1、概述 线程间通信的模型有两种:共享内存和消息传递 2、多线程编程步骤(中) 创建资源类,在资源类中创建属性和操作方法 在资源类操作方法进行判断、操作、通知 创建多个线程,调用资源类中的操作方…

多模态论文笔记——U-ViT

大家好,这里是好评笔记,公主号:Goodnote,专栏文章私信限时Free。本文详细介绍U-ViT的模型架构和实验细节,虽然没有后续的DiT在AIGC领域火爆,但为后来的研究奠定了基础,但其开创性的探索值得学习…

SpringBoot的6种API请求参数读取方式

RequestParam 用来加载URL中?之后的参数 比如: 这个请求/user?namedidspace 就可以如下面这样,使用RequestParam 来加载URL 中的name 参数 GetMapping("/user") ResponseBody() public User findUserByName(RequestParam("name") String n…

node.js内置模块之---http 和 https 模块

http 和 https 模块的作用 在 Node.js 中,http 和 https 模块用于创建和处理 HTTP 和 HTTPS 请求/响应 http模块 http 模块提供了用于实现 HTTP 协议的功能。它可以用来创建 HTTP 服务器,处理 HTTP 请求,发送 HTTP 响应,同时也可以…

Image和Video在同一个Dataloader中交错加载联合训练

单卡实现 本文主要从两个方面进行展开: 1.将两个或多个dataset组合成pytorch中的一个ConcatDataset.这个dataset将会作为pytorch中Dataloader的输入。 2.覆盖重写RandomSampler修改batch产生过程&#xff…

rpm包详解

一、rpm包 1、过滤系统rpm包,查询已安装的包 rpm -qa | grep htop2、rpm包导出 yumdownnloader htop-2.2.0.33、查看rpm包信息 rpm -qi 包名二、rpm包列表 1、查看软件包列表 yum list available *docker*2、查看软件包依赖 # rpl仓库 yum install epel-rel…

【Adobe Acrobat PDF】Acrobat failed to connect to a DDE server.是怎么回事?

【Adobe Acrobat PDF】Acrobat failed to connect to a DDE server.是怎么回事? 【Adobe Acrobat PDF】Acrobat failed to connect to a DDE server.是怎么回事? 文章目录 【Adobe Acrobat PDF】Acrobat failed to connect to a DDE server.是怎么回事&…

Rabbitmq 业务异常与未手动确认场景及解决方案

消费端消费异常,业务异常 与 未手动确认是不是一个场景,因为执行完业务逻辑,再确认。解决方案就一个,就是重试一定次数,然后加入死信队列。还有就是消费重新放入队列,然后重新投递给其他消费者,…

每日一题 380. O(1) 时间插入、删除和获取随机元素

380. O(1) 时间插入、删除和获取随机元素 最复杂的部分最简单来思考&#xff0c;其他的部分来弥补 class RandomizedSet { public:vector<int> nums;unordered_map<int,int> mp;RandomizedSet() {}bool insert(int val) {if(mp.count(val)){return false;}else{m…

MongoDB-文章目录

MongoDB学习总结1&#xff08;服务安装&#xff09; MongoDB学习总结2&#xff08;常用命令&#xff09; MongoDB学习总结3&#xff08;js文件中写命令&#xff09; MongoDB学习总结4&#xff08;数据插入、修改&#xff09; MongoDB学习总结5&#xff08;数据查询1&#x…

HBase Cassandra的部署和操作

目录 一&#xff0e;数据库的部署与配置 二&#xff0e;使用命令访问数据库 三&#xff0e;数据库的设计 四&#xff0e;编程实现数据库的访问 一&#xff0e;数据库的部署与配置 1.在单个节点上对进行数据库的单机部署 &#xff08;1&#xff09;下载apache-cassandra-4.1.7-…

springboot实战纪实-课程介绍

教程介绍 Spring Boot是由Pivotal团队提供的一套开源框架&#xff0c;可以简化spring应用的创建及部署。它提供了丰富的Spring模块化支持&#xff0c;可以帮助开发者更轻松快捷地构建出企业级应用。 Spring Boot通过自动配置功能&#xff0c;降低了复杂性&#xff0c;同时支持…

BBP飞控板中的坐标系变换

一般飞控板中至少存在以下坐标系&#xff1a; 陀螺Gyro坐标系加速度计Acc坐标系磁强计Mag坐标系飞控板坐标系 在BBP飞控板采用的IMU为同时包含了陀螺&#xff08;Gyro&#xff09;及加速度计&#xff08;Acc&#xff09;的6轴传感器&#xff0c;故Gyro及Acc为同一坐标系。同时…

数据表中的索引详解

文章目录 一、索引概述二、普通索引三、唯一索引四、全文索引五、多列索引六、索引的设计原则七、隐藏和删除索引 一、索引概述 日常生活中&#xff0c;我们经常会在电话号码簿中查阅“某人”的电话号码&#xff0c;按姓查询或者按字母排序查询&#xff1b;在字典中查阅“某个…

大模型系列17-RAGFlow搭建本地知识库

大模型系列17-RAGFlow搭建本地知识库 安装ollama安装open-wehui安装并运行ragflowRAG&#xff08;检索、增强、生成&#xff09;RAG是什么RAG三过程RAG问答系统构建步骤向量库构建检索模块生成模块 RAG解决LLM的痛点 使用ragflow访问ragflow配置ollama模型添加Embedding模型添加…

C++如何遍历数组vector

在C中&#xff0c;vector是一个可变数组。那么怎么遍历它呢&#xff1f;我们以for循环为例&#xff08;while循环&#xff0c;大家自己脑补&#xff09;。 方法一&#xff1a; 基于范围的for循环&#xff0c;这是C11新引入的。 std::vector<int> v {1, 2, 3, 4, 5, 6…

华为交换机---自动备份配置到指定ftp/sftp服务器

华为交换机—自动备份配置到指定ftp服务器 需求 交换机配置修改后及时备份相关配置,每次配置变化后需要在1分钟后自动进行保存,并且将配置上传至FTP服务器;每隔30分钟,交换机自动把配置上传到FTP服务器。 1、定时保存新配置的时间间隔为*分钟(1天=1440),默认为30分钟(…

深入解析-正则表达式

学习正则&#xff0c;我们到底要学什么&#xff1f; 正则表达式&#xff08;RegEx&#xff09;是一种强大的文本匹配工具&#xff0c;广泛应用于数据验证、文本搜索、替换和解析等领域。学习正则表达式&#xff0c;我们不仅要掌握其语法规则&#xff0c;还需要学会如何高效地利…

R shiny app | 网页应用 空格分隔的文本文件在线转csv

shiny 能快速把R程序以web app的形式提供出来&#xff0c;方便使用&#xff0c;降低技术使用门槛。 本文提供的示例&#xff1a;把空格分隔的txt文件转为逗号分隔的csv文件。 前置依赖&#xff1a;需要有R环境(v4.2.0)&#xff0c;安装shiny包(v1.9.1)。括号内是我使用的版本…

SocraticLM: Exploring Socratic Personalized Teaching with Large Language Models

题目 苏格拉底式教学:用大型语言模型探索苏格拉底式个性化教学 论文地址&#xff1a;https://openreview.net/pdf?idqkoZgJhxsA 项目地址&#xff1a;https://github.com/Ljyustc/SocraticLM 摘要 大型语言模型(LLM)被认为是推进智能教育的一项关键技术&#xff0c;因为它们展…