Mysql多版本并发控制(MVCC)

2024-08-25 19:52

本文主要是介绍Mysql多版本并发控制(MVCC),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 一、数据库的并发场景
  • 二、什么是MVCC?
    • 2.1 当前读和快照读
      • 当前读
      • 快照读
  • 三、MVCC实现原理
    • 3.1 隐式字段
    • 3.2 undo log
    • 3.3 ReadView
      • 可见性匹配原则
  • MVCC隔离级别分析
  • 参考文章

一、数据库的并发场景

有三种,分别是:
1、读-读:不存在任何问题,也不需要并发控制
2、读-写:有线程安全问题,可能会造成事务隔离问题,可能遇到脏读、幻读、不可重复读
3、写-写:有线程安全问题,可能会存在更新丢失问题,比如第一类更新丢失,第二类更新丢失

多版本并发控制(MVCC)是一种用来解决读-写冲突的无锁并发控制,也就是为事务分配单向增长的时间戳,为每个修改保存一个版本,版本与事务时间戳关联,读操作只读该事务开始前的数据库的快照。

二、什么是MVCC?

MVCC(Multi-Version Concurrency Control,多版本并发控制),它是一种并发控制方法,用于在数据库管理系统中实现对数据库的并发访问。

Mysql的大多数事务性存储引擎使用的都不是简单的行级锁机制。他们会将行级锁和可以提高并发性能的多版本并发控制技术结合使用。不仅是Mysql,包括Oracle、PostreSQL以及其他一些数据库系统也都使用了MVCC,但各自的实现机制不尽相同,因为MVCC如何工作没有统一一个标准。

可以认为MVCC是行级锁的一个变种,但他在很多情况下避免了加锁操作,因此开销更低。根据其实现方式,不仅实现了非阻塞的读操作,写操作也只锁定必要的行。

MVCC在MySQL InnoDB中的实现主要是为了提高数据库并发性能,用更好的方式去处理读-写冲突,做到即使有读写冲突时,也能做到不加锁,非阻塞并发读。

2.1 当前读和快照读

当前读

每次读取的都是最新数据,但读的时候不允许写,写的时候不允许读。

通过锁机制来保证读取的数据无法通过其他事务进行修改UPDATE、DELETE、INSERT、SELECT … LOCK IN SHARE MODE、SELECT … FOR UPDATE都是当前读。

快照读

读写不冲突,在事务开始时确定需要读取的数据版本,接下来的读取都会使用这个版本的数据,不受其他事务影响。

当前读通常用于可重复读和串行化隔离级别,而快照读通常用于读已提交和可重复读隔离级别。

三、MVCC实现原理

在Mysql中,MVCC实现原理主要依赖三个部分:数据库隐式字段、undo log、Read View。

3.1 隐式字段

有三个,分别是DB_ROW_ID DB_TRX_ID DB_ROLL_PTR

详细解释参考以下文章:
数据库技术之MVCC的实现原理 之 隐式字段

3.2 undo log

undo log是一种用于撤销回退的日志,在事务没提交之前,mysql 会先记录更新前的数据到 undo log 日志里面,当事务回滚或者数据库更新崩溃时,使用undo log 进行回退。

在mysql中,undo log有两个作用:
1、提供回滚操作【undo log实现事务的原子性】
2、实现多版本并发控制

更多关于undo log的知识见此:
MySQL回滚日志(undo log)总结

3.3 ReadView

用来做可见性判断,它是事务进行快照读操作的时候生产的读视图(ReadView),它记录并维护系统当前活跃事务的ID。

Read View创建时包含四个部分,如图:
在这里插入图片描述
creator_trx_id:创建这个Read View的事务id
m_ids:表示创建ReadView时当前系统中的活跃事务的ID集合
(活跃指:启动了但未提交)
min_trx_id:表示创建ReadView时当前系统中的活跃的最小事务ID
max_trx_id:表示创建ReadView时系统中应该分配给下一个事务的id值,当前最大事务ID+1

可见性匹配原则

一个事务去访问记录的时候,怎么判断记录的可见性呢?

判断数据记录可见性的逻辑是通过readview和【行记录的隐藏字段trx_id】做对比的
在这里插入图片描述
Read View决定当前事务能读到哪个版本的数据,从表记录到Undo Log历史数据的版本链,依次匹配,满足哪个版本的匹配规则,就能读到哪个版本的数据,一旦匹配成功就不再往下匹配。

遵循了以下可见性匹配规则:
在这里插入图片描述

MVCC隔离级别分析

在不同的隔离级别下快照读生成的ReadView规则不同,区别如下:

read committed (读已提交):事务每次select时创建ReadView,每个ReadView中四个字段的值都是不同的
repeatable read (可重复读):事务第一次select时创建ReadView,后面都是复用这个ReadView

流程举例说明,文章后半段:
结合图文一起搞懂MySQL事务、MVCC、ReadView!

参考文章

MVCC多版本并发控制原理总结(最终版)

亮点:有结合github仓库中的源码讲解:
一文读懂MySQL的事务隔离级别及MVCC机制

这篇关于Mysql多版本并发控制(MVCC)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1106500

相关文章

Python一次性将指定版本所有包上传PyPI镜像解决方案

《Python一次性将指定版本所有包上传PyPI镜像解决方案》本文主要介绍了一个安全、完整、可离线部署的解决方案,用于一次性准备指定Python版本的所有包,然后导出到内网环境,感兴趣的小伙伴可以跟随... 目录为什么需要这个方案完整解决方案1. 项目目录结构2. 创建智能下载脚本3. 创建包清单生成脚本4

MySQL的JDBC编程详解

《MySQL的JDBC编程详解》:本文主要介绍MySQL的JDBC编程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、前置知识1. 引入依赖2. 认识 url二、JDBC 操作流程1. JDBC 的写操作2. JDBC 的读操作总结前言本文介绍了mysq

java.sql.SQLTransientConnectionException连接超时异常原因及解决方案

《java.sql.SQLTransientConnectionException连接超时异常原因及解决方案》:本文主要介绍java.sql.SQLTransientConnectionExcep... 目录一、引言二、异常信息分析三、可能的原因3.1 连接池配置不合理3.2 数据库负载过高3.3 连接泄漏

Linux下MySQL数据库定时备份脚本与Crontab配置教学

《Linux下MySQL数据库定时备份脚本与Crontab配置教学》在生产环境中,数据库是核心资产之一,定期备份数据库可以有效防止意外数据丢失,本文将分享一份MySQL定时备份脚本,并讲解如何通过cr... 目录备份脚本详解脚本功能说明授权与可执行权限使用 Crontab 定时执行编辑 Crontab添加定

SpringBoot 多环境开发实战(从配置、管理与控制)

《SpringBoot多环境开发实战(从配置、管理与控制)》本文详解SpringBoot多环境配置,涵盖单文件YAML、多文件模式、MavenProfile分组及激活策略,通过优先级控制灵活切换环境... 目录一、多环境开发基础(单文件 YAML 版)(一)配置原理与优势(二)实操示例二、多环境开发多文件版

MySQL中On duplicate key update的实现示例

《MySQL中Onduplicatekeyupdate的实现示例》ONDUPLICATEKEYUPDATE是一种MySQL的语法,它在插入新数据时,如果遇到唯一键冲突,则会执行更新操作,而不是抛... 目录1/ ON DUPLICATE KEY UPDATE的简介2/ ON DUPLICATE KEY UP

MySQL分库分表的实践示例

《MySQL分库分表的实践示例》MySQL分库分表适用于数据量大或并发压力高的场景,核心技术包括水平/垂直分片和分库,需应对分布式事务、跨库查询等挑战,通过中间件和解决方案实现,最佳实践为合理策略、备... 目录一、分库分表的触发条件1.1 数据量阈值1.2 并发压力二、分库分表的核心技术模块2.1 水平分

Python与MySQL实现数据库实时同步的详细步骤

《Python与MySQL实现数据库实时同步的详细步骤》在日常开发中,数据同步是一项常见的需求,本篇文章将使用Python和MySQL来实现数据库实时同步,我们将围绕数据变更捕获、数据处理和数据写入这... 目录前言摘要概述:数据同步方案1. 基本思路2. mysql Binlog 简介实现步骤与代码示例1

Web服务器-Nginx-高并发问题

《Web服务器-Nginx-高并发问题》Nginx通过事件驱动、I/O多路复用和异步非阻塞技术高效处理高并发,结合动静分离和限流策略,提升性能与稳定性... 目录前言一、架构1. 原生多进程架构2. 事件驱动模型3. IO多路复用4. 异步非阻塞 I/O5. Nginx高并发配置实战二、动静分离1. 职责2

Ubuntu如何升级Python版本

《Ubuntu如何升级Python版本》Ubuntu22.04Docker中,安装Python3.11后,使用update-alternatives设置为默认版本,最后用python3-V验证... 目China编程录问题描述前提环境解决方法总结问题描述Ubuntu22.04系统自带python3.10,想升级