MySQL MVCC 概述

文章目录

  • MVCC(Muti Version Concurrency Control) 的概念
    • 什么是当前读和快照读
    • 背景
    • 总结
  • undo 日志
  • InnoDB 中的 MVCC
    • InnoDB 中的 MVCC 与事务隔离级别的关系
    • InnoDB 中的 MVCC 实现原理

MVCC(Muti Version Concurrency Control) 的概念

MVCC, 是一种多版本并发控制机制。通过 MVCC ,可以极大地提升数据库的操作并发量, 在不同的数据库, 不同的存储引擎中的实现方法也不一样, 大都是基于乐观锁和悲观锁来实现的。

什么是当前读和快照读

  • 当前读
    当前读意思就是读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录, 会对读取的记录进行加锁。
    select lock in share mode(共享锁), select for update, update, insert , delete(排他锁),这些操作都是当前读的一种。
  • 快照读
    快照读即不加锁的非阻塞读, 读取的是当前事务下第一次执行 select 时最新的版本, 注意区别, 这里的当前事务下第一次执行 select 时最新的版本并不能保证是最新的版本,如果在当前事务下执行第一次 select 之后, 有其他事务对记录进行了修改并提交,则当前读的记录版本则变成了历史版本。
    快照读的前提是事务隔离级别不是串行级别, 串行下的快照读将会退化成当前读。快照读是基于提高并发性能考虑的,是基于 MVCC 来实现的。

背景

最早的数据库系统,只有读读之间可以并发,读写,写读,写写之间都要阻塞。在引入 MVCC 之后,只有写写之间相互阻塞,其他的三种操作都可以并行,这样大幅度提高了 InnoDB 的并发量。

总结

MVCC 就是为了实现读-写冲突不加锁, 将当前读变成了快照读。当前读实际上是一种加锁的操作,是悲观锁的实现。 MVCC 的核心理念就是维持一条记录的多个版本, 使得读写操作没有冲突。

undo 日志

undo log 主要分为两种:

  • insert undo log
    代表事务在 insert 新记录时产生的 undo log, 只在事务回滚时需要,并且在事务提交后可以被立即丢弃。
  • update undo log
    代表事务在进行 updatedelete 时产生的 undo log ,不仅在事务回滚时需要,在快照读时也需要,所以不能随便删除,只有在快照读或事务回滚不涉及该日志时,对应的日志才会被 purge 线程同一清除。
    关于 MySQL purge 线程的介绍,请移步 MySQL purge 线程.md

InnoDB 中的 MVCC

InnoDB 中的 MVCC 与事务隔离级别的关系

MySQ 中支持 MVCC 的引擎是 InnoDB,且 MVCC 只在 READ_COMMITEDREPEATABLE_READ 两个隔离级别下工作。
MVCC 的作用用简单的话概括就是对数据库的任何修改的提交都不会直接覆盖之前的数据,而是产生一个新的版本与老版本共存,使得读数据的时候可以完全不用加锁。这样读某一个数据时,事务可以根据当下的隔离级别来选择读取哪个版本的数据,这个过程中完全不需要加锁。所以根据这个思想,实现两个隔离级别就变得非常容易:

  • READ_COMMITTED: 一个事务读取数据时总是读取这个数据最近一次被 commit 的版本。
  • REPEATABLE_READ: 一个事务读取数据时总是读取当前事务开始之前最后一次被 commit 的版本。

InnoDB 中的 MVCC 实现原理

InnoDB 中每行有三个隐藏列:

  • 6Byte, DB_TRX_ID : 行事务 ID, 记录的是上一次记录增删改被提交后的事务 ID, 就是被经常提起的创建版本号删除版本号;
  • 7Byte, DB_ROLL_PTR : 回滚指针, 指向 undo_log, undo_log 存储于 rollback segment 区域, 用于保存事务开始之前的快照;
  • 6Byte, DB_ROW_ID : 行 ID, 可以理解为隐藏的主键, 插入新行时单调递增。

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

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

相关文章

MySQL 行级锁

MySQL 行级锁的分类 按照锁定的范围不同,行级锁分为: 记录锁:用于锁定指定的某行记录间隙锁:用于锁定指定区间的记录,只有可重复读级别下才有间隙锁,间隙锁不存在冲突, 但是有可能导致死锁。临键锁:用于锁定指定左开右闭区间的记录,是记录锁与间隙锁的结合。

Redis Scan 命令

文章目录1. Scan 命令的基本用法1.1 Scan 命令的输入值1.2 Scan 命令的返回值2. Scan 命令与 Keys 命令比较2.1 Keys 命令的缺点2.2 Scan 命令的优点3. Scan 命令的限制3.1 有限保证原则3.2 返回的结果有可能会重复1. Scan 命令的基本用法 Scan 命令是一个基于游标的迭代器:Sc…

MybatisPlus 的 MetaObjectHandler 与 @TableLogic

文章目录1.MetaObjectHandler 实现公共字段自动填充功能1.1 日常开发中的公共字段1.2 Mybatis Plus 中的解决方案1.3 用法1.3.1 定义公共字段超类,并在字段上添加注解1.3.2 实现 MetaObjectHandler 接口2. Mybatis Plus 实现逻辑删除2.1 目前的逻辑删除2.2 Mybatis Plus 提供的…

红黑树 —— 原理和算法详细介绍

红黑树 —— 原理和算法详细介绍 R-B Tree简介 R-B Tree,全称是Red-Black Tree,又称为“红黑树”,它一种特殊的二叉查找树。红黑树的每个节点上都有存储位表示节点的颜色,可以是红(Red)或黑(Black)。 红黑树的特性: 每个节点或…

微服务雪崩效应与 Hystrix

文章目录微服务雪崩效应微服务中常见的容错方案常见的服务容错思路Hystrix 简介微服务雪崩效应 微服务系统中, 每一个服务专心于自己的业务逻辑, 并对外提供相应的接口, 看上去似乎耦合度比较低, 但经常会遇见这样一种场景: 可以看到, 当 C 服务挂掉时, B 服务还在不断地调用…

MySQL count(1) , count(*), count(列名) 的异同

count 函数主要用于统计行数,我们一般会用 count(1) , count(*), count(列名) 来统计行数,但是这三者之间有什么差距呢? 异同 当 count(列名) 在列名不是主键列的情况下,将只统计该列的非空行数,效率也最低下;当 count(列名) 在列名为主键列,且在没有非聚集索引的情况下,三者…

时间复杂度到底怎么算

时间复杂度到底怎么算 算法(Algorithm)是指用来操作数据、解决程序问题的一组方法。对于同一个问题,使用不同的算法,也许最终得到的结果是一样的,但在过程中消耗的资源和时间却会有很大的区别。 那么我们应该如何去衡…

Java 异常种类及处理方法

概述 异常的基类是 Throwable, Throwable 有两个子类: Exception : 表示可以恢复的异常, 编译器可以捕捉。Error : 表示编译时和系统错误, 表示系统在运行期间出现了严重的错误, 属于不可恢复的错误。 受检异常和非受检异常 受检异常指的是在编译期间会接受编译器检查, 且必…

十分钟搞定时间复杂度(算法的时间复杂度)

十分钟搞定时间复杂度(算法的时间复杂度) 我们假设计算机运行一行基础代码需要执行一次运算。 int aFunc(void) {printf("Hello, World!\n"); // 需要执行 1 次return 0; // 需要执行 1 次 }那么上面这个方法需要执行 2 次运算 …

Java 父子类加载顺序

现在有一个Parent类和一个Son类, 代码分别如下: public class Parent {static {System.out.println(" order 0");}private static String s init();{System.out.println(" order 3");}public Parent() {System.out.println(" order 4");}publi…

java实现简单二叉树

二叉树基本知识: 一、树的定义 树是一种数据结构,它是由n(n>1)个有限结点组成一个具有层次关系的集合。 树具有的特点有: (1)每个结点有零个或多个子结点 (2)没有…

HashMap 学习笔记

1.HashMap 的类继承关系 图示即为 Map 相关类的继承关系。源码中的类签名如下: public class HashMap<K,V> extends AbstractMap<K,V>implements Map<K,V>, Cloneable, Serializable {...... }2.HashMap 的底层存储结构 HashMap 的底层存储结构是 Node 类,…

MySQL中清空表和截断表的区别(新手入门)

清空表和截断表 清空表&#xff1a;delete from users&#xff1b; 清空表只是清空表中的逻辑数据&#xff0c;但是物理数据不清除&#xff0c;如主键值、索引等不被清除&#xff0c;还是原来的值。 截断表&#xff1a;truncate table users&#xff1b; 截断表可以用于删除…

终止线程的方法

如何终止一个正在运行的线程&#xff1f; 设置状态位来终止一个正在运行的线程。可以自己实现, 也可以使用 interrupt 方法来设置这个状态位, 然后在代码中判断 isInterrupted 的返回结果来执行退出执行的逻辑。 了解 Thread 类中的 stop、interrupt 方法吗?为什么不用 stop…

十大经典排序算法动画与解析(配代码完全版)

排序算法是《数据结构与算法》中最基本的算法之一。 排序算法可以分为内部排序和外部排序。 内部排序是数据记录在内存中进行排序。 而外部排序是因排序的数据很大&#xff0c;一次不能容纳全部的排序记录&#xff0c;在排序过程中需要访问外存。 常见的内部排序算法有&…

服务启动不了,显示 config 异常的问题排查

文章目录问题详情排查过程1.1 查看配置文件是否可以正常加载1.2 进入 config 服务正在运行的容器, 查看文件是否存在1.3 查看容器运行日志:最后发现是配置文件中多了一个 TAB 符,唉,说多了都是泪!问题详情 出现异常报错: Could not locate PropertySource and the fail fast p…

java使用Socket类接收和发送数据

java使用Socket类接收和发送数据 网络应用分为客户端和服务端两部分&#xff0c;而Socket类是负责处理客户端通信的Java类。通过这个类可以连接到指定IP或域名的服务器上&#xff0c;并且可以和服务器互相发送和接受数据。在本文及后面的数篇文章中将详细讨论Socket类的使用&a…

Docker Swarm compose 文件 depends_on 属性

Swarm 部署时候如果需要管理应用之间的启动先后顺序,则可以使用 services.depends_on 属性进行指定,例如 services:eureka-service:......depends_on:- config-service......

Java 单例模式:懒加载(延迟加载)和即时加载

Java 单例模式&#xff1a;懒加载&#xff08;延迟加载&#xff09;和即时加载 引言 在开发中&#xff0c;如果某个实例的创建需要消耗很多系统资源&#xff0c;那么我们通常会使用惰性加载机制&#xff08;或懒加载、延时加载&#xff09;&#xff0c;也就是说只有当使用到这…

递推算法之滚动数组思维方式

概述 在算法的最终结果只用到本层与上一层的结果时&#xff0c; 可以使用滚动数组思想。 简单的理解就是每次都使用固定的几个存储空间达到压缩节省存储空间的作用&#xff0c; 主要用在递推算法中。示例1&#xff1a; 爬楼梯问题 假设你正在爬楼梯。需要 n 阶你才能到达楼顶…