【MySQL 数据宝典】【事务锁】- 002 事务控制的演进

一、事务处理思路

1.1 排队

排队处理是事务管理最简单的方法,就是完全顺序执行所有事务的数据库操作,不需要加锁,简单的说就是全局排队。序列化执行所有的事务单元,数据库某个时刻只处理一个事务操作,特点是强一致性,处理性能低。
image.png

1.2 排它锁

引入锁之后就可以支持并发处理事务,如果事务之间涉及到相同的数据项时,会使用排他锁,或叫互斥锁,先进入的事务独占数据项以后,其他事务被阻塞,等待前面的事务释放锁。
image.png

1.3 读写锁

读和写操作:读读、写写、读写、写读。
读写锁就是进一步细化锁的颗粒度,区分读操作和写操作,让读和读之间不加锁,这样下面的两个事务就可以同时被执行了。
image.png
读写锁,可以让读和读并行,而读和写、写和读、写和写这几种之间还是要加排他锁。

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

生成流程

image.png
接着又有一个事务B (trx_id=58) 过来,对同一条数据进行修改,将值改为B,事务B的id是58,在更新之前会生成一个undo log来记录之前的值.然后会让roll_pointer指向这个实际的undo log回滚日志:
image.png
如果再有一个事务C (trx_id=69) 继续更新该条记录值为C,则会跟第二步的步骤一样
image.png
总结: 每一条数据都有多个版本,版本之间通过 undo log 链来进行连接
好处: 每个事务提交的时候一旦需要回滚操作,可以保证同一个事务只能读到比当前版本更早提交的值

2.3 Read View

核心解决问题: 需要判断一下版本链中的哪个版本是当前事务可见的
image.png
如上是一个 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。

核心流程

  1. 假设数据库有一行数据,很早就有事务操作过,事务id 是32. 此时两个事务并发过来执行了, 一个事务A (id=45),一个事务B (id=59). 事务A需要读取数据,而事务B需要更新数据,如下图:

image.png

如果不加任何限制,这里会出现脏读的情况,也就是一个事务可能会读到一个没有提交的值.

  1. 现在事务A直接开启一个ReadView,这个ReadView里的m_ids就包含了事务A和事务B的两个id,45和59,然后min_trx_id就是45,max_trx_id就是60. creator_trx_id就是45,是事务A自己。

image.png

  1. 此时事务A第一次查询这行数据,首先会判断一下当前这行数据的txr_id是否小于ReadView中的min_trx_id,此时发现txr_id=32,是小于ReadView里的min_trx_id就是45的,说明你事务开启之前,修改这行数据的事务已经提交了,所以此时可以查到这行数据,如下图所示:

image.png

  1. 接下来事务B开始操作该条数据,他把这行数据的值修改为了值B,然后将这行数据的txr_id设置为自己的id,也就是59,同时roll_pointer指向了修改之前生成的一个undo log,然后事务B提交,如下图所示

image.png

  1. 这时事务A再次执行了查询,但是却发现数据行里的txr_id=59
  • max_trx_id(60)>trxid (59) > mintrxid(45): 说明当前事务的数据是可能在自己同一时刻开启的
  • m_ids(45,59)包含了当前事务,说明就是同一时刻

所以当前记录无法查询
image.png

  1. 事务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读取到的数据就是之前的快照数据。

image.png

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时生成该版本的事务已经被提交,该版本可以被访问
  • 生成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
  1. 在查询时,InnoDB只查找版本早于当前事务版本的数据行,即数据行的版本必须小于等于当前事务的版本。这确保当前事务读取的行都是事务之前已经存在的,或者是由当前事务创建或修改的行。
  2. 对于被删除的行,其删除操作的版本一定是未定义的或者大于当前事务的版本号,这意味着在当前事务开始之前,行没有被删除。只有符合以上两点,才会返回查询结果。
删除 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 读取数据时不用对表数据进行加锁,从而解决了因为对数据库表的加锁而导致的两个如下问题
    1. 解决了因加锁导致的修改数据时无法对数据读取问题.
    2. 解决了因加锁导致读取数据时无法对数据进行修改的问题.
  • 当前读
    当前读是读取的数据库最新的数据,当前读和快照读不同,因为要读取最新的数据而且要保证事务的隔离性,所以当前读是需要对数据进行加锁的
    • Update delete insert select ....lock in share mode
    • select for update 为当前读

MVCC已经实现了读读、读写、写读并发处理,如果想进一步解决写写冲突,可以采用下面两种方案:

  • 乐观锁
  • 悲观锁

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

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

相关文章

测缝计测量的是实际缝宽吗?

在土木工程中&#xff0c;测缝计作为一种重要的监测工具&#xff0c;广泛应用于桥梁、隧道、大坝等大型结构中&#xff0c;用以测量和监控结构接缝或裂缝的实际宽度变化。然而&#xff0c;有些人可能会产生疑问&#xff1a;测缝计测量的是实际缝宽吗?本文将对这一问题进行深入…

六西格玛管理培训对企业有哪些实际帮助?

当下&#xff0c;企业要想脱颖而出&#xff0c;不仅要有创新思维和敏锐的市场洞察力&#xff0c;更要有高效的管理体系和严谨的质量控制手段。而六西格玛管理培训正是这样一项能够帮助企业实现提质增效、提升竞争力的关键举措。那么&#xff0c;六西格玛管理培训对企业究竟有哪…

亲子失和最大的内耗是:家长总是“说硬话,办软事”!

一声爸妈&#xff0c;一辈子的责任&#xff0c;操不完的心、做不完的事。 然而&#xff0c;爱太满&#xff0c;注定会溢出。爱有边界&#xff0c;我们是父母&#xff0c;更是自己&#xff01; 01 前些时候悠悠起床又开始混账了&#xff01; 气愤的是&#xff0c;周末休息那…

MES系统在电线电缆行业生产上的应用

MES系统在线缆行业的应用可以带来多重价值&#xff0c;包括提高生产效率、降低生产成本、提高产品质量、优化库存管理、改善生产环境和提高企业竞争力等方面。因此&#xff0c;在电线电缆行业中广泛应用MES系统可以提高企业的经济效益和社会效益&#xff0c;推动企业发展和行业…

平芯微PW4056HH中文规格书

概述 PW4056HH 是一款完整的采用恒定电流/恒定电压的高压、大电流、单节锂离子电池线性充电 IC。充电电流可达 1A。输入 MAX 低工作电压 3.75V&#xff0c;降低充电功耗&#xff0c;提高效率。 PW4056HH 采用了内部 PMOS 架构&#xff0c;加上防反充电路&#xff0c;不需要外部…

Lumina-T2X 一个使用 DiT 架构的内容生成模型,可通过文本生成图像、视频、多视角 3D 对象和音频剪辑。

Lumina-T2X 是一个新的内容生成系列模型&#xff0c;统一使用 DiT 架构。通过文本生成图像、视频、多视角 3D 对象和音频剪辑。 可以在大幅提高生成质量的前提下大幅减少训练成本&#xff0c;而且同一个架构支持不同的内容生成。图像质量相当不错。 由 50 亿参数的 Flag-DiT …

HL7协议

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1.介绍2.传输协议规范2.1. MLLP2.1.1. 数据头定义2.1.2. 转义字符集 2.2. 规范说明2.3. 消息格式说明 3.HL7结构介绍3.1. 患者建档&#xff08;ADT^A28&#xff09;…

webpack5零基础入门-14提取css为单独文件

1.背景 Css文件目前被打包到JS文件中&#xff0c;当JS文件加载时&#xff0c;会尝试创建一个style标签来生成样式&#xff0c;这样对于网站来说&#xff0c;会出现闪屏的现象&#xff0c;用户体验不好。我们应该是单独的Css文件&#xff0c;通过link标签来加载性能才好。 2.下…

好烦啊,我真的不想写增删改查了!

大家好&#xff0c;我是程序员鱼皮。 很想吐槽&#xff1a;我真的不想写增删改查这种重复代码了&#xff01; 大学刚做项目的时候&#xff0c;就在写增删改查&#xff0c;万万没想到 7 年后&#xff0c;还在和增删改查打交道。因为增删改查是任何项目的基础功能&#xff0c;每…

BUUCTF靶场[MISC]荷兰宽带数据泄露、九连环

[MISC]荷兰宽带数据泄露 考点&#xff1a;查看路由器恢复丢失密码的文件 工具&#xff1a;RouterPassView——路由器密码查看工具 工具链接&#xff1a;https://routerpassview.en.lo4d.com/windows RouterPassView是一款老牌的路由器密码查看器&#xff0c;可以一键获取路…

网络安全等级保护在工业控制系统中的应用

工业控制系统(Industrial Control Systems,ICS)&#xff0c;是由各种自动化控制组件和实时数据采集、监测的过程控制组件共同构成。其组件包括数据采集与监控系统(SCADA)、分布式控制系统(DCS)、可编程逻辑控制器(PLC)、远程终端(RTU)、智能电子设备(IED)&#xff0c;以及确保各…

Linux备份---异地

参考文档&#xff1a;Linux环境实现mysql所在服务器定时同步数据文件到备份服务器&#xff08;异地容灾备份场景&#xff09;_mysql异地备份-CSDN博客 通过SSH进行连接&#xff1a; 应用服务器&#xff1a; 通过ssh-keygen -t rsay建立ssh通信的密钥 密钥建立后&#xff0c;…