【MySQL 数据宝典】【事务锁】- 002 事务控制的演进
一、事务处理思路
1.1 排队
排队处理是事务管理最简单的方法,就是完全顺序执行所有事务的数据库操作,不需要加锁,简单的说就是全局排队。序列化执行所有的事务单元,数据库某个时刻只处理一个事务操作,特点是强一致性,处理性能低。
1.2 排它锁
引入锁之后就可以支持并发处理事务,如果事务之间涉及到相同的数据项时,会使用排他锁,或叫互斥锁,先进入的事务独占数据项以后,其他事务被阻塞,等待前面的事务释放锁。
1.3 读写锁
读和写操作:读读、写写、读写、写读。
读写锁就是进一步细化锁的颗粒度,区分读操作和写操作,让读和读之间不加锁,这样下面的两个事务就可以同时被执行了。
读写锁,可以让读和读并行,而读和写、写和读、写和写这几种之间还是要加排他锁。
1.4 乐观锁
通过版本进行判断,MVCC 就是其中一种实现方式
二、 MVCC
2.1 基础概念
MVCC(Multi Version Concurrency Control)被称为多版本控制,是指在数据库中为了实现高并发的数据访问,对数据进行多版本处理,并通过事务的可见性来保证事务能看到自己应该看到的数据版本。
MVCC最大的好处是读不加锁,读写不冲突。在读多写少的系统应用中,读写不冲突是非常重要的,极大的提升系统的并发性能,这也是为什么现阶段几乎所有的关系型数据库都支持 MVCC 的原因,不过目前MVCC只在** Read Commited** 和 **Repeatable Read **两种隔离级别下工作。
2.2 Undo Log 多版本链
在前面我们介绍过,每条数据都有两个隐藏的字段,事务 Id (trx_id),回滚指针 (roll_pointer)
- trx_id : 记录最近一次更新这条数据的事务 Id
- roll_pointer : 指向之前生成的 undo log
生成流程
接着又有一个事务B (trx_id=58) 过来,对同一条数据进行修改,将值改为B,事务B的id是58,在更新之前会生成一个undo log来记录之前的值.然后会让roll_pointer指向这个实际的undo log回滚日志:
如果再有一个事务C (trx_id=69) 继续更新该条记录值为C,则会跟第二步的步骤一样
总结: 每一条数据都有多个版本,版本之间通过 undo log 链来进行连接
好处: 每个事务提交的时候一旦需要回滚操作,可以保证同一个事务只能读到比当前版本更早提交的值
2.3 Read View
核心解决问题: 需要判断一下版本链中的哪个版本是当前事务可见的
如上是一个 Read View 所存储的信息
- m_ids :表示在生成 ReadView 时当前系统中活跃的读写事务的 事务id 列表。
- min_trx_id :表示在生成 ReadView 时当前系统中活跃的读写事务中最小的 事务id ,也就是 m_ids 中的最 小值。
- creator_trx_id :表示生成该 ReadView 的事务的 事务id 。
- max_trx_id :表示生成 ReadView 时系统中应该分配给下一个事务的 id 值。
注意max_trx_id并不是m_ids中的最大值,事务id是递增分配的。比方说现在有id为1,2,3这三 个事务,之后id为3的事务提交了。那么一个新的读事务在生成ReadView时,m_ids就包括1和2,mi n_trx_id的值就是1,max_trx_id的值就是4。
我们前边说过,只有在对表中的记录做改动时(执行INSERT、DELETE、UPDATE这些语句时)才会 为事务分配事务id,否则在一个只读事务中的事务id值都默认为0。
核心流程
- 假设数据库有一行数据,很早就有事务操作过,事务id 是32. 此时两个事务并发过来执行了, 一个事务A (id=45),一个事务B (id=59). 事务A需要读取数据,而事务B需要更新数据,如下图:
如果不加任何限制,这里会出现脏读的情况,也就是一个事务可能会读到一个没有提交的值.
- 现在事务A直接开启一个ReadView,这个ReadView里的
m_ids
就包含了事务A和事务B的两个id,45和59,然后min_trx_id
就是45,max_trx_id
就是60.creator_trx_id
就是45,是事务A自己。
- 此时事务A第一次查询这行数据,首先会判断一下当前这行数据的
txr_id
是否小于ReadView中的min_trx_id
,此时发现txr_id=32,是小于ReadView里的min_trx_id
就是45的,说明你事务开启之前,修改这行数据的事务已经提交了,所以此时可以查到这行数据,如下图所示:
- 接下来事务B开始操作该条数据,他把这行数据的值修改为了值B,然后将这行数据的
txr_id
设置为自己的id,也就是59,同时roll_pointer
指向了修改之前生成的一个undo log,然后事务B提交,如下图所示
- 这时事务A再次执行了查询,但是却发现数据行里的txr_id=59
- max_trx_id(60)>trxid (59) > mintrxid(45): 说明当前事务的数据是可能在自己同一时刻开启的
- m_ids(45,59)包含了当前事务,说明就是同一时刻
所以当前记录无法查询
- 事务A根据roll_point顺着undo log版本链向下找,找到最近的一条undo log,trx_id是32。由于trx_id=32小于ReadView里的min_trx_id(45),说明这个undo log版本是在事务A开启之前就执行且提交的。因此,事务A可以查询最近的这个undo log里的值,这时undo log版本链的作用就体现出来了,它保存了一条快照链条,而事务A读取到的数据就是之前的快照数据。
Read View总结
- 通过Read View判断记录的某个版本是否可见的方式总结:
- trx_id = creator_trx_id
如果被访问版本的trx_id,与readview中的creator_trx_id值相同,表明当前事务在访问自己修改过的记录,该版本可以被当前事务访问. - trx_id < min_trx_id
如果被访问版本的trx_id,小于readview中的min_trx_id值,表明生成该版本的事务在当前事务生成readview前已经提交,该版本可以被当前事务访问. - trx_id >= max_trx_id
如果被访问版本的trx_id,大于或等于readview中的max_trx_id值,表明生成该版本的事务在当前事务生成readview后才开启,该版本不可以被当前事务访问. - trx_id > min_trx_id && trx_id < max_trx_id
如果被访问版本的trx_id,值在readview的min_trx_id和max_trx_id之间,就需要判断trx_id属性值是不是在m_ids列表中?- 在:说明创建readview时生成该版本的事务还是活跃的,该版本不可以被访问
- 不在:说明创建readview时生成该版本的事务已经被提交,该版本可以被访问
- trx_id = creator_trx_id
- 生成readview时机
- RC隔离级别:每次读取数据前,都生成一个readview.
- RR隔离级别:在第一次读取数据前,生成一个readview,之后read view不再更新.
2.4 MVCC 在 MySQL 中的具体实现
2.4.1 简介
MySQL中实现MVCC(多版本并发控制)的机制主要基于undo log多版本链和ReadView机制。下面是MySQL中MVCC的实现方式的详细说明:
2.4.2 数据表隐藏字段
MySQL为了实现MVCC,在每个表中添加了一些隐藏字段:
- DATA_TRX_ID(6字节): 记录最新更新该行记录的事务ID,每个事务处理时会自动设置为当前事务ID。但值得注意的是,DATA_TRX_ID只有在事务提交之后才会更新。
- DATA_ROLL_PTR(7字节): 一个rollback指针,指向当前行数据的上一个版本。通过这个指针将数据的多个版本连接在一起构成一个undo log版本链。
- DB_ROW_ID(6字节): 隐含的自增ID,用来唯一标识每一行的字段。
- DELETE BIT位: 标识当前记录是否被删除,实际上并不是真正的删除数据,而是一个标志。真正的删除操作是在事务提交的时候执行。
2.4.3 场景示例
查询 SELECT
- 在查询时,InnoDB只查找版本早于当前事务版本的数据行,即数据行的版本必须小于等于当前事务的版本。这确保当前事务读取的行都是事务之前已经存在的,或者是由当前事务创建或修改的行。
- 对于被删除的行,其删除操作的版本一定是未定义的或者大于当前事务的版本号,这意味着在当前事务开始之前,行没有被删除。只有符合以上两点,才会返回查询结果。
删除 DELETE
- 删除操作会修改DATA_TRX_ID的值为当前执行删除操作的事务ID,并将DELETE BIT设置为True,表示被删除。
增加 INSERT
- 新记录的DATA_TRX_ID会被设置为当前事务ID。
修改 UPDATE
- 修改操作会使用排它锁锁定该行,以保证写操作的一致性。
- 同时,会记录redo log,将更新之后的数据记录到redo log中,以便日后使用。
- 也会记录undo log,将更新之前的数据记录到undo log中,以便回滚操作。
2.4.4 总结
通过undo log多版本链和ReadView机制的结合,MySQL实现了MVCC机制,确保了数据库在并发操作下的一致性和隔离性。
三、MVCC 读操作分类
在 MVCC 并发控制中,读操作可以分为两类: 快照读(Snapshot Read
)与当前读 (Current Read
)。
- 快照读
快照读是指读取数据时不是读取最新版本的数据,而是基于历史版本读取的一个快照信息(mysql读取undo log历史版本) ,快照读可以使普通的SELECT 读取数据时不用对表数据进行加锁,从而解决了因为对数据库表的加锁而导致的两个如下问题- 解决了因加锁导致的修改数据时无法对数据读取问题.
- 解决了因加锁导致读取数据时无法对数据进行修改的问题.
- 当前读
当前读是读取的数据库最新的数据,当前读和快照读不同,因为要读取最新的数据而且要保证事务的隔离性,所以当前读是需要对数据进行加锁的Update delete insert select ....lock in share mode
select for update
为当前读
MVCC已经实现了读读、读写、写读并发处理,如果想进一步解决写写冲突,可以采用下面两种方案:
- 乐观锁
- 悲观锁
相关文章:

【MySQL 数据宝典】【事务锁】- 002 事务控制的演进
一、事务处理思路 1.1 排队 排队处理是事务管理最简单的方法,就是完全顺序执行所有事务的数据库操作,不需要加锁,简单的说就是全局排队。序列化执行所有的事务单元,数据库某个时刻只处理一个事务操作,特点是强一致性…...

如何远程操作服务器中的Python编译器并将运行结果返回到Pycharm
文章目录 一、前期准备1. 检查IDE版本是否支持2. 服务器需要开通SSH服务 二、Pycharm本地链接服务器测试1. 配置服务器python解释器 三、使用内网穿透实现异地链接服务器开发1. 服务器安装Cpolar2. 创建远程连接公网地址 四、使用固定TCP地址远程开发 本文主要介绍如何使用Pych…...

C++入门指南(上)
目录 编辑 一、祖师爷画像 二、什么是C 三、C发展史 四、C在工作领域的应用 1. 操作系统以及大型系统软件开发 2. 服务器端开发 3. 游戏开发 4. 嵌入式和物联网领域 5. 数字图像处理 6. 人工智能 7. 分布式应用 五、如何快速上手C 一、祖师爷画像 本贾尼斯特劳斯…...

Python 全栈系列244 nginx upstream 负载均衡 踩坑日记
说明 最初是因为租用算力机(Python 全栈系列242 踩坑记录:租用算力机完成任务),所以想着做一个负载均衡,然后多开一些服务,把配置写在nginx里面就好了。 一开始租用了一个3080起了一个服务,后来觉得速度不够快,再起了…...

数据链路层——计算机网络学习笔记三
使用点对点信道的数据链路层 前言: 1.数据链路层的重要性:网络中的主机、路由器都必须实现数据连输层; 2.数据链路层中使用的信道: 点对点信道:这种信道是一对一的通信方式; 广播信道:使用一对多…...

leetcode——反转链表
206. 反转链表 - 力扣(LeetCode) 思路:创建三个指针n1,n2,n3,遍历原链表,通过三者之间的关系将链表反转。下面给出图示: 下面给出题解代码: typedef struct ListNode ListNode; struct List…...

类加载机制(双亲委派机制)
文章目录 JVM的作用是什么双亲委派机制加载流程 JVM的作用是什么 我们运行Java程序时,要安装JDK,JDK包含JVM,不同环境的JDK都是不同的。 Java 代码在编译后会形成 class 的字节码文件,该字节码文件通过 JVM 解释器,生…...

nss刷题(2)
1、[NSSCTF 2022 Spring Recruit]ezgame 打开题目是一个游戏界面 发现是有分数的,猜测分数达到某个之后可以获得flag,查看源码看一下 看到末尾显示分数超过65后显示flag 在js中找到了一个score,将他的值改为大于65的数后随意玩一次就可以得到flag同时&a…...

2024 年“泰迪杯”A 题:生产线的故障自动识别与人员配置--第四题(用遗传算法解决生产线排班问题--matlab代码)
问题背景: 问题四:根据实际情况,现需要扩大生产规模,将生产线每天的运行时间从 8 小时增加 到 24 小时不间断生产,考虑生产线与操作人员的搭配,制定最佳的操作人员排班方案,要求满足以下条件&am…...

资产公物仓管理系统|实现国有资产智能化管理
1、项目背景 资产公物仓管理系统(智仓库DW-S201)是一套成熟系统,依托互3D技术、云计算、大数据、RFID技术、数据库技术、AI、视频分析技术对RFID智能仓库进行统一管理、分析的信息化、智能化、规范化的系统。 项目设计原则 方案对公物仓资…...
实用的 Google Chrome 命令
以下是一些实用的 Google Chrome 命令: chrome://version - 显示 Chrome 浏览器的详细信息,包括版本号、用户代理和命令行参数等。 chrome://flags - 打开 Chrome 实验性功能页面,可以启用或禁用各种实验性功能。请注意,这些功能…...

动态规划算法:⼦数组、⼦串系列(数组中连续的⼀段)
例题一 解法(动态规划): 算法思路: 1. 状态表⽰: 对于线性 dp ,我们可以⽤「经验 题⽬要求」来定义状态表⽰: i. 以某个位置为结尾,巴拉巴拉; ii. 以某个位置…...

2010年认证杯SPSSPRO杯数学建模D题(第一阶段)服务网点的分布全过程文档及程序
2010年认证杯SPSSPRO杯数学建模 D题 服务网点的分布 原题再现: 服务网点、通讯基站的设置,都存在如何设置较少的站点,获得较大效益的问题。通讯基站的覆盖范围一般是圆形的,而消防、快餐、快递服务则受到道路情况和到达时间的限…...

docker-compose 安装ZLMediaKit,ffmpeg、VLC实现推流并播放
1、目录(创建conf文件夹,777权限) 二、docker-compose.yml version: "3.9"services:zlmediakit:image: zlmediakit/zlmediakit:mastercontainer_name: zlmediakitprivileged: true# 指定加载配置# command: /opt/media/bin/MediaS…...

|Python新手小白中级教程|第二十八章:面向对象编程(类定义语法私有属性类的继承与多态)(4)
文章目录 前言一、类定义语法二、私有方法和私有属性1.私有属性2.私有方法 三、类“继承”1.初识继承2.使用super函数调用父类中构造的东西 四、类“多态”1.多态基础2.子类不同形态3.使用isinstance函数与多态结合判断类型 总结 前言 大家好,我是BoBo仔吖…...

vue项目基于WebRTC实现一对一音视频通话
效果 前端代码 <template><div class"flex items-center flex-col text-center p-12 h-screen"><div class"relative h-full mb-4 fBox"><video id"localVideo"></video><video id"remoteVideo">…...

web 基础之 HTTP 请求
web 基础 网上冲浪 就是在互联网(internet)上获取各种信息,进行工作,或者娱乐,他的英文表示surfing the Internet,因 “surfing”d的意思是冲浪,即成为网上冲浪,这是一种形象说法, 也是一个非…...

嵌入式 - GPIO编程简介
An Introduction to GPIO Programming By Jeff Tranter Wednesday, June 12, 2019 编者按:本 2019 年博客系列是 ICS 最受欢迎的系列之一,现已更新(2022 年 12 月),以确保内容仍然准确、相关和有用。 本博客是 Integr…...

8种区块链开发者必须知道的顶级编程语言!
我来问你一个问题:请说出一种技术,它以去中心化、不可篡改和透明性等核心特征席卷了全球。 这个问题的答案是,当然是区块链,它在近些年进入大家的视野并颠覆了工商业,没有任何其他技术能够做到这一点。 预计从2020年…...

十三、Redis哨兵模式--Sentinel
上一篇介绍了Redis中的主从复制。我们知道Redis主从中一般只有主节点对外提供写操作,如果主节点发生故障,为了保证Redis的可用性,这时就要在可用的slave节点中,挑选一个作为主节点。这种切换操作如果是人为的操作,那么…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...
scikit-learn机器学习
# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...

【Veristand】Veristand环境安装教程-Linux RT / Windows
首先声明,此教程是针对Simulink编译模型并导入Veristand中编写的,同时需要注意的是老用户编译可能用的是Veristand Model Framework,那个是历史版本,且NI不会再维护,新版本编译支持为VeriStand Model Generation Suppo…...
微服务通信安全:深入解析mTLS的原理与实践
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、引言:微服务时代的通信安全挑战 随着云原生和微服务架构的普及,服务间的通信安全成为系统设计的核心议题。传统的单体架构中&…...

企业大模型服务合规指南:深度解析备案与登记制度
伴随AI技术的爆炸式发展,尤其是大模型(LLM)在各行各业的深度应用和整合,企业利用AI技术提升效率、创新服务的步伐不断加快。无论是像DeepSeek这样的前沿技术提供者,还是积极拥抱AI转型的传统企业,在面向公众…...