02_MVCC-版本链管理

MVCC-版本链管理

文章目录

    • MVCC-版本链管理
        • 简介
        • 基本概念
        • 版本链的形成与管理
          • 数据插入操作
          • 数据更新操作
          • 数据删除操作
        • 一致性视图(Read View)
        • 快照读与当前读
          • 快照读(Snapshot Read)
          • 当前读(Current Read)
        • 优缺点
          • 优点
          • 缺点
        • 版本链的清理
        • 总结
        • 延伸

简介

MySQL 的 MVCC(Multiversion Concurrency Control,多版本并发控制)机制通过版本链管理来实现数据的多版本存储,从而支持高并发的读写操作。


基本概念

InnoDB 存储引擎在实现 MVCC 时,会为每一行数据维护一个版本链,这些版本链用于记录数据的多个版本。每个版本包含以下隐藏列:

  1. DB_TRX_ID(事务ID):记录创建或最后一次修改该版本的事务ID。
  2. DB_ROLL_PTR(回滚指针):指向该行数据的上一个版本的指针。
  3. DB_ROW_ID:隐式的自增ID,用于唯一标识行记录。有主键的时候会使用主键,没有主键的时候会自动生成一个行 Id 作为聚簇索引。

这些隐藏列在实际的数据表结构中不可见,但它们是实现 MVCC 的关键。


版本链的形成与管理
数据插入操作

当插入一行新数据时,InnoDB 会为该行分配一个新的事务ID,并将 DB_TRX_ID 设置为当前事务ID。同时,因为这是一条新记录,没有上一个版本,所以 DB_ROLL_PTR 为空。

INSERT INTO example (id, value) VALUES (1, 'A');

在此操作中,假设事务ID 为 trx_id = 100,新记录会包含如下信息:

  • id = 1
  • value = 'A'
  • DB_TRX_ID = 100
  • DB_ROLL_PTR = NULL
数据更新操作

当更新一行数据时,InnoDB 不会直接覆盖原数据,而是创建一个新的版本。新版本会记录当前事务ID,并通过 DB_ROLL_PTR 指向旧版本。

UPDATE example SET value = 'B' WHERE id = 1;

假设事务ID 为 trx_id = 101,更新后的新记录会包含如下信息:

  • id = 1
  • value = 'B'
  • DB_TRX_ID = 101
  • DB_ROLL_PTR 指向旧版本

旧版本数据保存在回滚日志(Undo Log)中,包含以下信息:

  • id = 1
  • value = 'A'
  • DB_TRX_ID = 100
  • DB_ROLL_PTR = NULL

通过这种方式,InnoDB 形成了一个版本链,新版本指向旧版本,实现数据的多版本存储。

数据删除操作

当删除一行数据时,InnoDB 同样不会直接物理删除该行,而是创建一个标记为“已删除”的新版本,并指向旧版本。

DELETE FROM example WHERE id = 1;

假设事务ID 为 trx_id = 102,删除后的新记录会包含如下信息:

  • id = 1
  • value = NULL(表示该行已被删除)
  • DB_TRX_ID = 102
  • DB_ROLL_PTR 指向旧版本

一致性视图(Read View)

当一个事务开始时,InnoDB 会创建一个一致性视图(Read View),该视图记录当前系统中活跃事务的 ID,用于决定哪些版本对当前事务可见。具体来说:

  1. m_ids:当前系统中所有活跃事务的 ID 列表。
  2. min_trx_idm_ids 中最小的事务ID。
  3. max_trx_id:当前系统中将要分配的下一个事务ID。
  4. creator_trx_id:创建这个 Read View 的事务ID。

通过一致性视图,InnoDB 能够决定某个数据版本是否对当前事务可见:

  • 如果数据版本(要读取的数据行)的 DB_TRX_ID 小于 min_trx_id(当前事务开始时创建的一致性视图中的 min_trx_id),表示这个版本(要读取的数据行)在当前事务开始之前就已经提交了,所以这个版本(要读取的数据行)对当前事务是可见的。
  • 如果数据版本的 DB_TRX_ID 大于或等于 max_trx_id,表示这个版本在当前事务开始之后才创建,所以是不可见的。
  • 如果数据版本的 DB_TRX_IDmin_trx_idmax_trx_id 之间,则需要进一步检查该 DB_TRX_ID 是否在 m_ids 中:
    • 如果在,表示这个版本是由一个尚未提交的事务创建的,所以是不可见的。
    • 如果不在,则表示这个版本是由一个已经提交的事务创建的,所以是可见的。

如果当前版本对事务不可见,InnoDB 会沿着版本链(通过 roll_pointer 指针)查找上一个版本,重复上述判断过程,直到找到一个对当前事务可见的版本。


快照读与当前读
快照读(Snapshot Read)

快照读是读取一致性视图中的数据版本,而不加锁。这种读操作通常用于 SELECT 查询。

-- 事务1:启动事务
START TRANSACTION;
-- 快照读,读取一致性视图中的数据
SELECT * FROM example WHERE id = 1;

在快照读中,InnoDB 会根据一致性视图和版本链,选择一个对当前事务可见的数据版本返回。

当前读(Current Read)

当前读是读取最新的数据版本并加锁,确保数据的一致性。这种读操作用于需要更新或锁定数据的查询,如 SELECT ... FOR UPDATESELECT ... LOCK IN SHARE MODE

-- 事务1:启动事务
START TRANSACTION;
-- 当前读,加排他锁
SELECT * FROM example WHERE id = 1 FOR UPDATE;

在当前读中,InnoDB 会读取最新的数据版本,并根据操作类型加上合适的锁(如排他锁或共享锁)。


优缺点
优点
  1. 高并发性能:通过多版本数据存储,读操作无需加锁,提高了系统的并发性能。
  2. 数据一致性:通过一致性视图和版本链,确保在事务隔离级别下的数据一致性。
  3. 事务隔离:支持事务的隔离级别,如可重复读和读已提交,避免了脏读、不可重复读和幻读问题。
缺点
  1. 存储开销:需要额外存储多版本数据和回滚日志,增加了存储需求。
  2. 数据清理:需要定期清理无用的旧版本数据,避免回滚日志无限增长,增加了系统维护的复杂性。

通过详细理解版本链管理,可以更好地掌握 MySQL 的 MVCC 机制,提高数据库系统的性能和数据一致性。


版本链的清理

随着时间的推移,旧版本的数据可能不再被任何事务需要,因此 InnoDB 会定期清理这些不再需要的版本,这个过程被称为 purge。Purge 操作会检查 undo log 记录,并在确定没有事务需要访问这些旧版本时将其删除,释放空间供将来使用。


总结

MySQL 中的 MVCC 通过在每行记录中维护额外的系统字段来构建版本链,这使得不同事务可以看到数据的不同版本。版本链的管理涉及到版本的创建、读取版本的可见性判断,以及不再需要的版本的清理。这种机制允许事务并发执行,同时保持一致性和隔离性,是 InnoDB 高效性能的关键所在。


延伸
  1. 一致性视图的实现原理(快照如何存储?存储在哪?多个快照存在时如何选取版本等)

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

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

相关文章

单片机输出方波

从P1.0上输出一个方波,高电平5ms,低电平10ms. #include〈reg51。h〉 unsigned char flag; sbit outP1^0; void main() { flag0; TMOD0X02; TH06; TL06; TR01; EA1; ET0…

使用 SSH 连接 GitLab 的常见问题及解决方案

使用 SSH 连接 GitLab 的常见问题及解决方案 在使用 SSH 连接到 GitLab 服务器时,可能会遇到类似于以下的错误信息: git192.168.xx.xxx: Permission denied (publickey).这个错误通常表示 SSH 无法验证你的公钥,导致无法访问 GitLab 仓库。…

【直播伴侣】抖音开播设置

可以使用obs作为虚拟摄像头,把加工的画面喂给直播伴侣,然后用直播伴侣开播推流:看起来蓝光画质也是1080p 下最大的8Mbps推荐是6Mbps。抖音伴侣的开播设置 测试自己的上行带宽 30Mbps 不知道为啥别人都那么大: 看起来蓝光画质,码率也只有6Mbps

【鸡翅Club】项目启动

一、项目背景 这是一个 C端的社区项目,有博客、交流,面试学习,练题等模块。 项目的背景主要是我们想要通过面试题的分类,难度,打标,来评估员工的技术能力。同时在我们公司招聘季的时候,极大的…

电商大数据获取渠道分享--官方接口、爬虫、第三方如何选择?

在当今大数据驱动的商业环境中,电商企业越来越依赖数据分析来洞察市场、优化运营和提升竞争力。本文将分享几种常见的电商大数据获取渠道,帮助电商从业者更有效地收集和利用数据资源。 一、电商平台官方接口 各大电商平台如淘宝、京东、拼多多等&#…

跟我学C++中级篇——典型的内存问题分析

一、内存问题引起的Crash 程序的崩溃对每个开发人员来说,都是一种磨难的存在,不经历不会成长,但再怎么成长也不愿意经历。在程序崩溃的现象中,内存引起的程序崩溃一直是重要的原因,也可以说,内存的异常引起…

【网络协议栈】Tcp协议(上)结构的解析 和 Tcp中的滑动窗口(32位确认序号、32位序号、4位首部长度、6位标记位、16为窗口大小、16位紧急指针)

绪论​ “没有那么多天赋异禀,优秀的人总是努力翻山越岭。”本章主要讲到了再五层网络协议从上到下的第二层传输层中使用非常广泛的Tcp协议他的协议字段结构,通过这些字段去认识其Tcp协议运行的原理底层逻辑和基础。后面将会再写一篇Tcp到底是通过什么调…

【保姆级】Spring Retry 教程

什么是“重试”?为什么要进行“重试”呢? “重试”(Retry)是一种在编程和软件开发中常见的策略,用于处理在执行操作时可能遇到的临时性错误或异常。当一个操作因为某些原因(如网络问题、服务不可用、资源暂时不可用等)失败时,重试机制会尝试再次执行该操作,以期在下一…

PHP发票验真 API-发票真伪查验、验证接口示例

发票验真API是一种在线服务,它允许用户或企业通过编程接口(API)验证发票的真实性。这种服务通常由政府机构或者授权的第三方(如翔云、百度)提供,旨在打击伪造发票的行为,保护消费者的合法权益&a…

JAVA-石头迷阵小游戏

采用企业式项目结构,接下来我将分享全部代码和结构,希望大家点点关注! 这是我的结构。首先使用IDE创建一个Module,命名stone-maze,接着把自带src下的main方法删除,接着在src下创建包,包名为com.wmuj,接着创建APP类代码如下: package com.wmuj;public class App {publ…

《探索 Python 音频利器:sounddevice》

一、sounddevice 简介 Sounddevice 是一个强大的 Python 音频处理库,它为开发者提供了对 PortAudio 库的 Python 绑定,从而实现了在 Python 环境中播放和录制音频数据的功能。 这个库具有诸多优势。首先,它具有跨平台性,无论是在…

进程间通信大总结Linux

目录 进程间通信介绍 进程间通信目的 进程间通信发展 进程间通信分类 管道 System V IPC POSIX IPC 管道 什么是管道 匿名管道 用fork来共享管道原理 站在文件描述符角度-深度理解管道 管道读写规则 管道特点 命名管道 创建一个命名管道 匿名管道与命名管道的区…

RabbitMQ系列学习笔记(八)--发布订阅模式

文章目录 一、发布订阅模式原理二、发布订阅模式实战1、消费者代码2、生产者代码3、查看运行结果 本文参考: 尚硅谷RabbitMQ教程丨快速掌握MQ消息中间件rabbitmq RabbitMQ 详解 Centos7环境安装Erlang、RabbitMQ详细过程(配图) 一、发布订阅模式原理 在开发过程中&…

linux查看系统类型

要确定系统是 Ubuntu 还是 CentOS,可以通过查看系统的发行版信息来判断。以下是几种常见的方法: 方法一:使用 cat 命令查看 /etc/os-release 文件 这个文件包含了系统的详细信息,包括发行版名称和版本号。 cat /etc/os-release…

ESP32-C3实现非易失变量(Arduino IDE )

1效果 网页输入数据&#xff0c;串口打印数据。掉电后数据还在 2源码 #include <WiFi.h> // 包含WiFi库&#xff0c;用于处理WiFi连接 #include <WebServer.h> // 包含WebServer库&#xff0c;用于创建Web服务器 #include <Preferences.h> // 包含Prefere…

告别微信封号!学会这5招,让你的账号坚不可摧

在这个信息爆炸的时代&#xff0c;无论是工作沟通、社交互动还是获取信息&#xff0c;微信都扮演着极其重要的角色。但是&#xff0c;随着微信平台规则的日益严格&#xff0c;账号被封的风险也随之增加。今天&#xff0c;我们就来聊聊如何有效防止 微信被封&#xff0c;让你的账…

【MySQL】入门篇—基本数据类型:NULL值的概念

在关系数据库中&#xff0c;NULL值是一个特殊的标记&#xff0c;表示缺失或未知的值。 NULL并不等同于零&#xff08;0&#xff09;或空字符串&#xff08;&#xff09;&#xff0c;它表示一个字段没有任何值。 这一概念在数据库设计和数据管理中至关重要&#xff0c;因为它影…

力扣——环形链表问题

判断链表是否有环以及入环的第一个节点 前言判断链表是否有环找到入环的第一个节点 前言 大家好&#xff0c;前段时间&#xff0c;熊二学习了关于环形链表相关的问题&#xff0c;以下是我的见解&#xff0c;希望能够帮助你们呀&#xff01; 判断链表是否有环 给定一个链表&am…

如何在一个月内快速学习掌握大模型

原本给自己的是一个月时间&#xff0c;通过梳理之后我自信的认为不需要一个月&#xff0c;两周即可&#xff0c;相较于其他技术&#xff0c;大模型应用的门槛要低得多。 先明确你想要深入到哪一层 1、基础设施层&#xff1a;了解即可&#xff0c;关注NVIDIA和超大规模厂商的最…

[自动化测试:Selenium]:环境部署和Webdriver的使用

文章目录 修改安装源打开Python Packages。点击梅花按钮。在弹出的对话框中&#xff0c;填入Name&#xff08;随便填&#xff09;&#xff0c;Repository URL&#xff0c;选择下列的源&#xff0c;一般先选择清华源按OK确认。配置完成 安装seleniumFile→Settings→Project&…