当前位置: 首页 > news >正文

MySQL中的MVCC(多版本并发控制)

MySQL中的MVCC(多版本并发控制)

MySQL中的多版本并发控制(MVCC)是一种重要的机制,它允许多个事务并发地读取和修改数据库,同时保持数据的一致性和隔离性。MVCC通过维护数据的多个版本,使事务能够看到一致的数据库视图,从而避免了大多数锁定操作,提高了数据库的并发性能。

MVCC的工作原理

MVCC的核心概念是行的版本管理和事务ID(Transaction ID, TXID)。在MySQL的InnoDB存储引擎(更多请参考:MySQL 存储引擎详解)中,每个事务开始时都会分配一个唯一的事务ID,这个ID用于跟踪事务的状态以及行的版本信息。以下是MVCC的详细工作机制:

  1. 行的版本管理

    • 每个数据行在InnoDB存储引擎中都有两个隐藏的列:trx_idroll_pointer
      • trx_id表示最后一次修改该行的事务ID。
      • roll_pointer指向回滚日志中的旧版本数据,用于支持事务的回滚和一致性读取。
  2. 读取一致性视图

    • 当一个事务开始时,它会生成一个一致性视图(Consistent Read View),该视图包含当前活动事务的ID列表。
    • 在读取数据时,事务会根据一致性视图判断每行数据的可见性。具体规则如下:
      • 如果数据行的trx_id小于当前事务的ID,则该行是可见的(表示该行在当前事务开始之前已提交)。
      • 如果数据行的trx_id大于当前事务的ID,则该行不可见(表示该行在当前事务开始之后被修改)。
      • 如果数据行的trx_id在一致性视图的活动事务ID列表中,则该行不可见(表示该行由未提交的其他事务修改)。
  3. 写操作

    • 当事务对数据行进行修改时,会创建该行的新版本,新的trx_id设为当前事务的ID,并更新roll_pointer指向旧版本。
    • 旧版本的行数据会保留在回滚段中,直到不再需要(即没有其他事务在读取它)。
  4. 垃圾回收

    • InnoDB存储引擎会定期执行垃圾回收操作,清除不再需要的旧版本行数据,以释放存储空间。
    • 这个过程称为“清除(Purge)”,由后台线程自动处理。
    • 清除操作的步骤如下:
      • 扫描回滚段:InnoDB会扫描回滚段,查找已提交事务所留下的旧版本数据。
      • 判断可见性:如果没有任何活跃事务需要访问这些旧版本数据,它们就可以被删除。
      • 删除旧版本:删除旧版本数据,释放相关的存储空间。
      • 更新索引:更新所有相关的索引以反映删除操作。
      • 重复操作:这个过程是持续的,InnoDB后台线程会定期执行,以保持数据库的高效性。
代码示例

以下示例展示了MVCC在MySQL中的实际应用,包括插入、更新和读取操作。

-- 创建示例表,并添加注释
CREATE TABLE users (id INT AUTO_INCREMENT PRIMARY KEY COMMENT '用户ID,自动递增,主键',name VARCHAR(50) COMMENT '用户名称',balance DECIMAL(10, 2) COMMENT '用户余额,保留两位小数'
) COMMENT='用户信息表';-- 插入一些数据
INSERT INTO users (name, balance) VALUES ('Alice', 100.00), ('Bob', 150.00), ('Charlie', 200.00);-- 事务1:读取数据
START TRANSACTION;
SELECT * FROM users;
-- 事务1读取users表的所有数据。此时会生成一个一致性视图,事务将看到事务开始时的数据库状态。
-- 假设事务1在此时暂停,继续执行其他操作-- 事务2:更新数据
START TRANSACTION;
UPDATE users SET balance = balance - 50 WHERE name = 'Alice';
-- 事务2更新Alice的余额,创建了一个新版本的行,并更新了trx_id和roll_pointer。
COMMIT;-- 事务3:读取数据
START TRANSACTION;
SELECT * FROM users;
-- 事务3读取users表的数据。由于事务2已提交,事务3将看到Alice的余额减少到50。
COMMIT;-- 事务1:再次读取数据
SELECT * FROM users;
-- 事务1再次读取users表的数据。由于事务1的读取视图是在事务2提交之前创建的,
-- 事务1仍然看到Alice的余额为100。
COMMIT;

通过以上示例可以看到,MVCC通过维护行的多个版本和一致性视图,确保了事务的隔离性和一致性,同时提高了数据库的并发性能。MySQL中的MVCC使得读取操作无需加锁,从而避免了大多数锁竞争和死锁问题。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • WebRTC通话原理(SDP、STUN、 TURN、 信令服务器)
  • Git_基础命令
  • 【ESP32 idf Uart串口通信】
  • 遇到not allow unquoted fieldName怎么办
  • Leetcode 721.账户合并(hash+dfs)☆
  • [MySQL]02 存储引擎与索引,锁机制,SQL优化
  • Python:Flask自定义URL路由参数过滤器
  • 电缆故障精准定位系统
  • 在CentOS中配置三个节点之间相互SSH免密登陆
  • 极狐GitLab如何启用和配置PlantUML?
  • 【Django】在vscode中运行调试Django项目(命令及图形方式)
  • 观成科技:活跃窃密木马TriStealer加密通信分析
  • setsockopt选项对tcp速度
  • HTTP 协议浅析
  • k8s 公共服务
  • 《用数据讲故事》作者Cole N. Knaflic:消除一切无效的图表
  • C++类中的特殊成员函数
  • Intervention/image 图片处理扩展包的安装和使用
  • Javascript弹出层-初探
  • JavaScript对象详解
  • java取消线程实例
  • Python实现BT种子转化为磁力链接【实战】
  • 高度不固定时垂直居中
  • 我是如何设计 Upload 上传组件的
  • 一个SAP顾问在美国的这些年
  • 中国人寿如何基于容器搭建金融PaaS云平台
  • 06-01 点餐小程序前台界面搭建
  • ​queue --- 一个同步的队列类​
  • # 飞书APP集成平台-数字化落地
  • (Redis使用系列) SpringBoot中Redis的RedisConfig 二
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (翻译)terry crowley: 写给程序员
  • (分布式缓存)Redis哨兵
  • (三)uboot源码分析
  • (五)大数据实战——使用模板虚拟机实现hadoop集群虚拟机克隆及网络相关配置
  • (续)使用Django搭建一个完整的项目(Centos7+Nginx)
  • (自用)仿写程序
  • (自用)网络编程
  • *++p:p先自+,然后*p,最终为3 ++*p:先*p,即arr[0]=1,然后再++,最终为2 *p++:值为arr[0],即1,该语句执行完毕后,p指向arr[1]
  • ..thread“main“ com.fasterxml.jackson.databind.JsonMappingException: Jackson version is too old 2.3.1
  • .class文件转换.java_从一个class文件深入理解Java字节码结构
  • .net core IResultFilter 的 OnResultExecuted和OnResultExecuting的区别
  • .net core 的缓存方案
  • .net 受管制代码
  • .NET 指南:抽象化实现的基类
  • .NET/C#⾯试题汇总系列:⾯向对象
  • .NET6 开发一个检查某些状态持续多长时间的类
  • .net程序集学习心得
  • .net后端程序发布到nignx上,通过nginx访问
  • @AliasFor注解
  • @property python知乎_Python3基础之:property
  • @SuppressLint(NewApi)和@TargetApi()的区别
  • [ Algorithm ] N次方算法 N Square 动态规划解决
  • [ vulhub漏洞复现篇 ] Jetty WEB-INF 文件读取复现CVE-2021-34429
  • []常用AT命令解释()