【Sql】MVCC有关问题,以及锁,日志和主从复制原理

目录

MVCC

解决什么问题?

实现原理

隐式字段

undo log

Read View(读视图)

InnoDB 对 MVCC 的实现

分类

锁升级?

InnoDB 的行锁?

死锁避免?

乐观锁和悲观锁

日志

主从复制原理

主从复制的作用

MySQL主从复制解决的问题

涉及3个线程

复制过程

读写分离


MVCC

一种多版本并发控制机制,用处就是在多个并发事务同时读写数据库时保持数据的一致性和隔离性。它是通过在每个数据行上维护多个版本的数据来实现的。当一个事务要对数据库中的数据进行修改时,MVCC 会为该事务创建一个数据快照,而不是直接修改实际的数据行。

解决什么问题?

在并发读写数据库时,可以做到在读操作时不用阻塞写操作,写操作也不用阻塞读操作,提高了数据库并发读写的性能。同时还可以解决脏读、幻读、不可重复读等事务隔离问题,但不能解决更新丢失问题。

实现原理

它的实现原理主要是依赖记录中的 3 个隐式字段、undo log、Read View 来实现的。

通过保存数据在某个时间点的快照来实现的.不同存储引擎的MVCC实现是不同的,典型的有乐观并发控制和悲观并发控制

隐式字段

每行记录除了我们自定义的字段外,还有数据库隐式定义的DB_TRX_ID,DB_ROLL_PTR,DB_ROW_ID等字段

  • DB_ROW_ID 6byte, 隐含的自增ID(隐藏主键),如果数据表没有主键,InnoDB会自动以DB_ROW_ID产生一个聚簇索引

  • DB_TRX_ID 6byte, 最近修改(修改/插入)事务ID:记录创建这条记录/最后一次修改该记录的事务ID

  • DB_ROLL_PTR 7byte, 回滚指针,指向这条记录的上一个版本(存储于rollback segment里)

  • DELETED_BIT 1byte, 记录被更新或删除并不代表真的删除,而是删除flag变了

undo log

InnoDB把这些为了回滚而记录的这些东西称之为undo log。

注意,由于查询操作并不会修改任何用户记录,所以在查询操作执行时,并不需要记录相应的undo log。

undo log主要分为3种:

  • Insert undo log :插入一条记录时,至少要把这条记录的主键值记下来,之后回滚的时候只需要把这个主键值对应的记录删掉就好了。

  • Update undo log:修改一条记录时,至少要把修改这条记录前的旧值都记录下来,这样之后回滚时再把这条记录更新为旧值就好了。

  • Delete undo log

    :删除一条记录时,至少要把这条记录中的内容都记下来,这样之后回滚时再把由这些内容组成的记录插入到表中就好了。

    • 删除操作都只是设置一下老记录的DELETED_BIT,并不真正将过时的记录删除。

    • 为了节省磁盘空间,InnoDB有专门的purge线程来清理DELETED_BIT为true的记录。为了不影响MVCC的正常工作,purge线程自己也维护了一个read view(这个read view相当于系统中最老活跃事务的read view);如果某个记录的DELETED_BIT为true,并且DB_TRX_ID相对于purge线程的read view可见,那么这条记录一定是可以被安全清除的。

Read View(读视图)

定义:说白了Read View就是事务进行快照读操作的时候生产的读视图,在该事务执行的快照读的那一刻,会生成数据库系统当前的一个快照,记录并维护系统当前活跃事务的ID(当每个事务开启时,都会被分配一个ID, 这个ID是递增的,所以最新的事务,ID值越大)

InnoDB 对 MVCC 的实现

MVCC 的实现依赖于:隐藏字段、Read View、undo log。在内部实现中,InnoDB 通过数据行的 DB_TRX_IDRead View 来判断数据的可见性,如不可见,则通过数据行的 DB_ROLL_PTR 找到 undo log 中的历史版本。每个事务读到的数据版本可能是不一样的,在同一个事务中,用户只能看到该事务创建 Read View 之前已经提交的修改和该事务本身做的修改

分类

表级锁: MySQL 中锁定粒度最大的一种锁(全局锁除外),是针对非索引字段加的锁,对当前操作的整张表加锁,实现简单,资源消耗也比较少,加锁快,不会出现死锁。不过,触发锁冲突的概率最高,高并发下效率极低。表级锁和存储引擎无关,MyISAM 和 InnoDB 引擎都支持表级锁。

行级锁: MySQL 中锁定粒度最小的一种锁,是 针对索引字段加的锁 ,只针对当前操作的行记录进行加锁。 行级锁能大大减少数据库操作的冲突。其加锁粒度最小,并发度高,但加锁的开销也最大,加锁慢,会出现死锁。行级锁和存储引擎有关,是在存储引擎层面实现的。

表锁和行锁都有共享锁和排它锁

  1. 共享锁:又称读锁,多个用户可以同一时刻读取同一个资源,相互之间没有影响。事务在读取记录的时候获取共享锁,允许多个事务同时获取(锁兼容)。不堵塞,

  2. 排它锁:又称写锁/独占锁,事务在修改记录的时候获取排他锁,不允许多个事务同时获取。如果一个记录已经被加了排他锁,那其他事务不能再对这条事务加任何类型的锁(锁不兼容)。

意向锁是表级锁,共有两种:

  1. 意向共享锁:事务有意向对表中的某些记录加共享锁,加共享锁前必须先取得该表的意向共享锁。

  2. 意向排他锁:事务有意向对表中的某些记录加排他锁,加排他锁之前必须先取得该表的意向排他锁。

锁升级?
  • MySQL 行锁只能加在索引上,如果操作不走索引,就会升级为表锁。因为 InnoDB 的行锁是加在索引上的,如果不走索引,自然就没法使用行锁了,原因是 InnoDB 是将主键索引 和相关的行数据共同放在 B+ 树的叶节点。InnoDB 一定会有一个 主键,二级索引 查找的时候,也是通过找到对应的主键,再找对应的数据行。

  • 当非唯一索引上记录数超过一定数量时,行锁也会升级为表锁。测试发现当非唯一索引相同的内容不少于整个表记录的二分之一时会升级为表锁。因为当非唯一索引相同的内容达到整个记录的二分之一时,索引需要的性能比全文检索还要大,查询语句优化时会选择不走索引,造成索引失效,行锁自然就会升级为表锁。

InnoDB 的行锁?

InnoDB 行锁是通过对索引数据页上的记录加锁实现的,MySQL InnoDB 支持三种行锁定方式:

  • 记录锁(Record Lock):也被称为记录锁,属于单个行记录上的锁。

  • 间隙锁(Gap Lock):锁定一个范围,不包括记录本身。

  • 临键锁(Next-Key Lock):Record Lock+Gap Lock,锁定一个范围,包含记录本身,主要目的是为了解决幻读问题(MySQL 事务部分提到过)。记录锁只能锁住已经存在的记录,为了避免插入新记录,需要依赖间隙锁。

在 InnoDB 默认的隔离级别 REPEATABLE-READ 下,行锁默认使用的是 Next-Key Lock。但是,如果操作的索引是唯一索引或主键,InnoDB 会对 Next-Key Lock 进行优化,将其降级为 Record Lock,即仅锁住索引本身,而不是范围。

死锁避免?

定义:死锁是指两个或多个事务在同一资源上相互占用,并请求锁定对方的资源,从而导致恶性循环的现象。

  1. 设置获取锁的超时时间,至少能保证最差情况下,可以退出程序,不至于一直等待导致死锁;

  2. 设置按照同一顺序访问资源,类似于串行执行;

  3. 避免事务中的用户交叉;

  4. 保持事务简短并在一个批处理中;

  5. 使用低隔离级别;

乐观锁和悲观锁

乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。在修改数据的时候把事务锁起来,通过version的方式来进行锁定。实现方式:一般会使用版本号机制或CAS算法实现。用在读多的场景。

悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作。在查询完数据的时候就把事务锁起来,直到提交事务。实现方式:使用数据库中的锁机制。用在写多的场景。

日志

更新语句的流程会涉及到三种日志:

  • undo log(回滚日志):是 Innodb 存储引擎层生成的日志,实现了事务中的原子性,主要用于事务回滚和 MVCC

  • redo log(重做日志):是 Innodb 存储引擎层生成的日志,实现了事务中的持久性,主要用于掉电等故障恢复

  • binlog (归档日志):是 Server 层生成的日志,主要用于数据备份和主从复制

写入原理:

主从复制原理

  • 主从复制:将主数据库中的DDL和DML操作通过二进制日志(BINLOG)传输到从数据库上,然后将这些日志重新执行(重做);从而使得从数据库的数据与主数据库保持一致。

  • 原理

    • 在主库上把数据更高记录到二进制日志

    • 从库将主库的日志复制到自己的中继日志

    • 从库读取中继日志的事件,将其重放到从库数据中

主从复制的作用
  1. 主数据库出现问题,可以切换到从数据库。

  2. 可以进行数据库层面的读写分离。

  3. 可以在从数据库上进行日常备份。

MySQL主从复制解决的问题
  • 数据分布:随意开始或停止复制,并在不同地理位置分布数据备份

  • 负载均衡:降低单个服务器的压力

  • 高可用和故障切换:帮助应用程序避免单点失败

  • 升级测试:可以用更高版本的MySQL作为从库

涉及3个线程
  • binlog 线程 : 负责将主服务器上的数据更改写入二进制日志中。

    I/O 线程 : 负责从主服务器上读取二进制日志,并写入从服务器的中继日志中。

    SQL 线程 : 负责读取中继日志并重放其中的 SQL 语句。

复制过程
  1. 主节点在每个事务更新数据完成之前,将该操作记录串行地写入到binlog文件中。

  2. 从节点开启一个I/O Thread,该线程在主节点打开一个普通连接,主要工作是二进制日志传输。如果读取的进度已经跟上了主节点,就进入睡眠状态并等待主节点产生新的事件。I/O线程最终的目的是将这些事件写入到中继日志中。

  3. SQL Thread会读取中继日志,并顺序执行该日志中的SQL事件,从而与主数据库中的数据保持一致。

读写分离

主服务器处理写操作以及实时性要求比较高的读操作,而从服务器处理读操作。

读写分离能提高性能的原因在于:

  • 主从服务器负责各自的读和写,极大程度缓解了锁的争用;

  • 从服务器可以使用 MyISAM,提升查询性能以及节约系统开销;

  • 增加冗余,提高可用性。

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

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

相关文章

Java基于微信小程序的校园生活互助小助手

博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…

vue3 el-form中嵌套el-tabale 对输入动态校验

简单案例 <el-form :model"Form" :rules"rules" ref"FormRef" class"formDiv"><el-table :data"Form.copyWriters" style"width: 100%"><el-table-column label"文案链接"><temp…

Day33:安全开发-JavaEE应用SQL预编译Filter过滤器Listener监听器访问控制

目录 JavaEE-预编译-SQL JavaEE-过滤器-Filter JavaEE-监听器-Listen 思维导图 Java知识点 功能&#xff1a;数据库操作&#xff0c;文件操作&#xff0c;序列化数据&#xff0c;身份验证&#xff0c;框架开发&#xff0c;第三方库使用等. 框架库&#xff1a;MyBatis&#…

Mysql锁与MVCC

文章目录 Mysql锁的类型锁使用MVCC快照读和当前读读视图【Read View】串行化的解决 exlpain字段解析ACID的原理日志引擎整合SpringBoot博客记录 Mysql锁的类型 MySQL中有哪些锁&#xff1a; 乐观锁&#xff08;Optimistic Locking&#xff09;&#xff1a;假设并发操作时不会发…

C语言程序环境和预处理Pt.1 - 预处理指令|预处理操作符

电脑所能识别的语言为二进制指令&#xff0c;而我们所写的C语言代码是文本信息。为了能使计算机识别并执行C语言代码&#xff0c;就需要翻译环境&#xff0c;使C语言代码翻译为二进制的指令。 1.按下编译按钮的幕后 - 程序的翻译环境 从C语言源代码到计算机可识别的二进制文件…

MTK安卓开发板_联发科开发板评估套件_安卓主板硬件开发

在介绍开发板之前&#xff0c;让我们先来区分一下核心板和开发板的区别。核心板是一种集成度高、功能完整的计算模块&#xff0c;搭载系统&#xff0c;简化了外围接口&#xff0c;体积尺寸相对较小&#xff0c;主要适用于嵌入式系统。而开发板由核心板底板组成&#xff0c;提供…

spring中事务失效的场景有哪些?

异常捕获处理 在方法中已经将异常捕获处理掉并没有抛出。 事务只有捕捉到了抛出的异常才可以进行处理&#xff0c;如果有异常业务中直接捕获处理掉没有抛出&#xff0c;事务是无法感知到的。 解决&#xff1a;在catch块throw抛出异常。 抛出检查异常 spring默认只会回滚非检…

EI级 | Matlab实现PCA-GCN主成分降维结合图卷积神经网络的数据多特征分类预测

EI级 | Matlab实现PCA-GCN主成分降维结合图卷积神经网络的数据多特征分类预测 目录 EI级 | Matlab实现PCA-GCN主成分降维结合图卷积神经网络的数据多特征分类预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现PCA-GCN主成分降维结合图卷积神经网络的数据多…

c/c++ | 求叶子结点个数 |构建B树 | 动态规划--找叶子结点个数

是这样的&#xff0c;一道代码题&#xff0c;根据输入数据&#xff0c;计算运行结果 #include<bits/stdc.h> using namespace std; vector<int>g[10]; int ans 0; void dfs(int x){if(g[x].size() 0){ans;return;}for(int i 0; i < g[x].size(); i){dfs(g[x]…

windows 安装 gitlab-runner CICD

点击搜索图标 手动输入PowerShell, 右键点击管理员权限打开&#xff0c; 一、安装 安装 gitlab runner 文档参考地址 1、下载exe执行文件 我这里是 win64 https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-windows-amd64.exe 2、创建 gitla…

基于java+springboot+vue实现的电影订票系统(文末源码+Lw+ppt)23-41

摘 要 随着网络科技的不断发展以及人们经济水平的逐步提高&#xff0c;计算机如今已成为人们生活中不可缺少的一部分&#xff0c;为电影订票方便管理&#xff0c;基于java技术设计与实现了一款简洁、轻便的管理系统。本系统解决了电影订票事务中的主要问题&#xff0c;包括个…

08.JavaScript中的编程思想,构造函数和原型对象

一、编程思想 学习 JavaScript 中基于原型的面向对象编程序的语法实现&#xff0c;理解面向对象编程的特征。 1.面向过程 面向过程就是分析出解决问题所需要的步骤&#xff0c;然后用函数把这些步骤一步一步实现&#xff0c;使用的时候再一个一个的依次 调用就可以了。 举个…

JAVA初阶数据结构栈(工程文件后续会上传)(+专栏数据结构练习是完整版)

1.栈的概念讲解(Stack)&#xff09; 定义&#xff1a;栈是一种先进后出的数据结构 要想拿到12就要把它头上的所有东西给移出去 2.栈的实现&#xff08;代码&#xff09; 2.1栈的方法逻辑的讲解 &#xff08;1&#xff09;新建一个测试类Frank &#xff08;2&#xff09;进…

基于STM32的智慧农业管理系统设计与实现

文章目录 一、前言1.1 项目介绍【1】项目功能【2】设计实现的功能【3】项目硬件模块组成 1.2 设计思路1.3 传感器功能介绍1.4 开发工具的选择 二、EMQX开源MQTT服务器框架三、购买ECS云服务器3.1 登录官网3.2 购买ECS服务器3.3 配置安全组3.4 安装FinalShell3.5 远程登录到云服…

后端给前端导出 数据excal表

pom <!-- 读取文档 --><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.15</version></dependency><!-- https://mvnrepository.com/artifact/org.apache.poi/poi --><…

最新CLion + STM32 + CubeMX 开发环境搭建

网上有不少相关教程&#xff0c;但都是基于老版本Clion&#xff0c;新版有一些改变&#xff0c;但整体是简单了。 PS&#xff1a;本教程基于CLion 2023.3.4 安装所需工具参考&#xff1a;Clion搭建stm32开发环境&#xff08;STM32F103C8T6&#xff09;&#xff0c;有这一篇就够…

BFS(宽度优先搜索)C++(Acwing)

代码&#xff1a; #include <cstring> #include <iostream> #include <algorithm>using namespace std;typedef pair<int, int> PII;const int N 110;int n, m; int g[N][N]; int d[N][N]; PII q[N * N];int bfs() {int hh 0, tt 0;q[0] {0, 0};m…

C#,图论与图算法,输出无向图(Un-directed Graph)全部环(cycle)的算法与源代码

1 无向图(Un-directed Graph)全部环 图算法中需要求解全部的环。 2 方法 使用图着色方法,用唯一的数字标记不同循环的所有顶点。图形遍历完成后,将所有类似的标记数字推送到邻接列表,并相应地打印邻接列表。 3 算法 将边插入到邻接列表中。调用DFS函数,该函数使用着色方…

完整的通过git命令框和windows窗口将本地文件上传到gitee远程仓库流程步骤

1.下载git 这个网站搜索git官方&#xff0c;去下载就行了 2.打开git安装后的Git Bash命令框 3.在Git Bash命令框设置一下要远程链接的gitee账号 git config --global user.name “名字”Git config --global user.email “邮箱” 4.查看一下账号设置 git config --global -…

解释multi_update_all函数

import dgl import dgl.function as fn import torch# 实例化一个异构图 g dgl.heterograph({(user, follows, user): ([0, 1], [1, 1]),(game, attracts, user): ([0], [1]) }) g.nodes[user].data[h] torch.tensor([[1.], [2.]]) g.nodes[game].data[h] torch.tensor([[1.…