InnoDB-MVCC与乐观锁

数据库并发控制:锁与MVCC(PostgreSQL) 为了解决这些问题,数据库管理系统(DBMS)提供了并发控制机制,其中锁和多版本并发控制(MVCC)是常见的方法。锁是一种常见的并发控制手段,它允许数据库管理系统在不同的事务之间协调对数据的访问。多版本并发控制(MVCC)是另一种常见的并发控制机制,它基于版本号来管理数据的并发访问。当一个事务获取了共享锁时,其他事务可以继续获取共享锁,但排他锁将被阻塞直到共享锁被释放。通过使用锁,我们可以确保事务在访问和修改数据时遵循一定的顺序,从而避免并发冲突和数据不一致的问题。在PostgreSQL中,可以使用。 阅读详情

最近通过《高性能MySQL》一书学习MySQL方面的知识,在看到书中所讲InnoDB-MVCC部分的时候,有一种强烈的感觉,这不就是乐观锁吗(入门级小学徒的疑惑脸)?当下便去网上以各种方式查找阅读MVCC和乐观锁相关的博客,发现大部分的博客对于这两者之间的关系都只字不提,提了的也是众说纷纭,关于两者关系的细节方面也十分暧昧没有定论。在暂时无法得出最终结论的情况下,我先谈谈在学习这方面知识后我自己对两者的理解,然后试着得出自己的结论,正确与否大家一起思考。

在解释MVCC之前,我首先引用《高性能MySQL》书中原文来解释一下隔离级别:

  • READ UNCOMMITTED(未提交读):在READ UNCOMMITTED级别,事务中的修改,即使没有提交,对其他事务也都是可见的。事务可以读取未提交的数据,这也被称为脏读。

  • READ COMMITTED(提交读):大多数数据库默认的隔离级别(MySQL除外)。在READ COMMITTED级别,一个事务开始时,只能“看见”已经提交的事务所做的修改。换句话说,一个事务从开始直到提交之前,所做的任何修改对其他事务都是不可见的,这个级别有时候也叫做不可重复读,因为同一事务中两次执行同样的查询,可能会得到不一样的结果。

  • REPEATABLE READ(可重复读):这是MySQL默认的隔离级别,解决了脏读的问题。该级别保证了在同一事务中多次读取同样记录的结果是一致的。但是理论上,该隔离级别还是无法解决另外一个幻读的问题。所谓幻读,指的是当某个事务在读取某个范围内的记录时,另外一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录时,会产生幻行。

  • SERIALIZABLE(可串行化):该隔离级别下通过强制事务串行执行,避免了幻读的问题。简单来说,SERIALIZABLE会在读取的每一行数据上都加锁,所以可能导致大量的超时和锁争用的问题。

如果看了以上对四个隔离级别的解释还是无法理解什么是隔离级别以及为什么要有隔离级别,可以去网上百度隔离级别,网上有一些通过现实场景来解释隔离级别的例子很容易理解,这里就不再做赘述。

那隔离级别到底和MVCC有什么关系呢?如果说将数据库比作一辆汽车,然后将隔离级别比作汽车轮毂,那么MVCC就是ABS防抱死制动系统,不过这个ABS防抱死制动系统只适用于READ COMMITTED和REPEATABLE READ两个型号的轮毂。

这里写图片描述

上面解释隔离级别时提到了,在REPEATABLE READ隔离级别下,尽管解决了不可重复读,但还是存在幻读的问题。如果要避免幻读,就得在事务执行的时候加锁,但是大量的锁会严重影响性能。怎样才能不通过加锁还能解决幻读呢?这就是MVCC要做的事情。

MVCC是Multi-Version Concurrency Control(多版本并发控制)的缩写,很多数据库都实现了MVCC,但是在不同的存储引擎中MVCC的实现是不同的,今天所说的是InnoDB中的MVCC实现。InnoDB的MVCC,是通过在每行记录后保存两个隐藏的列来实现的(用户不可见)。一个列保存行创建的时间,一个列保存行过期(删除)的时间,这里所说的时间并不是传统意义上的时间,而是系统版本号,下面是REPEATABLE READ隔离级别下MVCC的具体操作:
-SELECT
InnoDB会根据以下两个条件检查每行记录:
(1)InnoDB只查找版本早于当前事务版本的数据行(行的系统版本号小于或者等于事务的系统版本号),这样可以确保事务读取到的行,要么是在事务开始之前已经存在的,要么是事务自身插入或者修改过的(结合以下INSERT、UPDATE操作理解)。
(2)行的删除版本要么未定义,要么大于当前事务版本号。可以确保事务读取到的行,在事务开启之前未被删除(结合以下DELETE操作理解)。
-INSERT
InnoDB为新插入的每一行保存当前系统版本号作为行版本号。
-DELETE
InnoDB为删除的每一行保存当前系统版本号作为行删除标识(第二个隐藏列的作用来了)。
-UPDATE
InnoDB将更新后的列作为新的行插入数据库(并不是覆盖),并保存当前系统版本号作为该行的行版本号,同时保存当前系统版本号到原来的行作为行删除标识。

到这里,MVCC是什么以及它做了什么事基本上已经说清楚了,为什么在学习了MVCC后我会产生“这就是乐观锁”的想法呢(实际上很多人都有这种想法,在一些博客里也有人说MVCC就是乐观锁)?有这几个原因。首先,InnoDB中MVCC和乐观锁(其实这么说是不严谨的,后面会解释为什么)都是通过“不加锁”的手段来实现加锁的效果。其次它们的不加锁手段都是通过版本号去控制的。通过这两点也不难看出为什么会有很多人在MVCC和乐观锁之间产生疑问。

那么乐观锁是怎么实现的呢?最常见的就是通过数据版本(Version)记录机制实现。数据版本和InnoDB-MVCC中的系统版本作用相似不做过多解释。通过为数据库表增加一个数字类型的字段作为版本标识Version(用户可见,字段名自定),当读取数据时,将其Version的值一同读出,数据每更新一次,Version都增加1,当提交更新的时候,判断数据库表对应行的当前版本信息与第一次读取出来的Version值进行对比,如果一致,则给与更新,否则不予更新(可以不涉及事务,但是MVCC机制必须依托于事务,事实上隔离级别本就是事务的隔离级别)。具体操作如下:

SELECT id, name, Version FROM testable;(例如id=1,Version=1024)
UPDATE testable SET name=’张三’,Version=Version+1 WHERE id=1 AND Version=1024;

这里写图片描述 这里写图片描述

从上面的所有文字中,我们还是无法得出一个有效的结论,只看得出InnoDB-MVCC和文中所提到的乐观锁确实很像,它们到底是何关系我们还是无从所知。那我们再来看看《高性能MySQL》中所提到的一句话:不同存储引擎的MVCC实现是不同的,典型的有乐观并发控制和悲观并发控制。看完这句话我们再结合上文,可以得出这样一个结论:MVCC并不是乐观锁,InnoDB所实现的MVCC才是乐观锁(当然也有其他存储引擎利用乐观并发控制的思想实现MVCC),更严谨一点来说,乐观锁并不是一种具体的技术,乐观锁只是一种并发控制的思想,所有认为“并发事务不算大”而采用非加锁的形式来实现“加锁”效果的控制机制我们都认为它是乐观锁。既然如此,那我们之前提到的乐观锁就不能叫乐观锁了,它只是乐观锁的一种表达方式,是一种在用户行为上通过非加锁的方式来实现并发控制的手段。同样的MVCC更不能称之为乐观锁,只能说InnoDB实现的MVCC是一种在系统行为上通过非加锁的方式来实现并发控制的手段。

总结来说,InnoDB-MVCC是一种系统行为,在REPEATABLE READ隔离级别下,它通过乐观并发控制解决了该隔离级别所不能解决的幻读,但是前提是这些都得依托于事务的封装。尽管如此,它还是无法完全解决一些并发业务场景下的问题,并且过多的事务使用会严重影响系统的性能,这就需要通过用户行为去约束(最开始所提到的乐观锁)。

所以,最后的结论就是,MVCC并非乐观锁,但是InnoDB存储引擎所实现的MVCC是乐观的,它和之前所提到的用户行为的“乐观锁”都采用的是乐观机制,属于不同的“乐观锁”手段,它们都是“乐观家族”的成员。

利用Matlab绘制非线性系统相图:从理论到实践 本文详细介绍了如何利用Matlab进行非线性系统的相图绘制与相平面分析。从理论基础的状态空间转换出发,通过无阻尼线性谐振子和范德波尔振荡器等实例,手把手演示了使用ode45求解器绘制相图、分析平衡点与极限环的完整流程,并分享了方向场绘制、参数分岔探索及常见错误解决方案等高级技巧,为动力学系统分析与控制设计提供了直观强大的可视化工具。 阅读详情

相关推荐

别再纠结高侧低侧了!用INA199/INA219这类集成电流检测芯片,5分钟搞定精准电流测量

本文详细解析了使用INA199/INA219等集成电流检测芯片实现精准电流测量的高效方案。通过对比传统分立元件方案,突出集成芯片在精度、温度稳定性和设计简化方面的优势,并提供硬件设计避坑指南和软件实现最佳实践,帮助开发者快速掌握电流检测技术。

weixin_42685438的博客 471

MVCC 过程中会加锁吗?

所以说,MVCC 在处理过程中,虽然本身不涉及加锁,但在实际操作中,为了防止更新操作导致的数据不一致,会加锁,但对读操作是非阻塞的。

qq_63431773的博客 1606

京东联盟h5st(3.1)加密参数逆向实战与反爬对抗策略

本文详细解析了京东联盟h5st(3.1)加密参数的逆向分析与实战破解过程。通过接口分析定位关键加密函数,拆解h5st结构并还原其基于SHA256和HMAC-SHA256的加密逻辑,最终使用Python集成JavaScript环境成功复现加密算法,并分享了应对反爬的频率限制、IP封禁及算法升级等对抗策略。

weixin_29246195的博客 1740

Mysql在什么情况下用mvcc,什么情况下用锁?

非锁定读(普通select)用mvcc, 锁定读(select for update/select lock in share mode)/update/insert/delete的时候用锁 依据: 1、官方文档 MySQL :: MySQL 8.0 Reference Manual :: 15.7.2.1 Transaction Isolation Levels 2、知乎文章 MySQL多版本并发控制机制(MVCC)-源码浅析 - 知乎 ...

qq_41836217的博客 1738

基于NXP1778的CAN自动波特率检测

一、概念 NXP1778芯片内部自带一个CAN控制器。CAN模块由两部分组成:控制器和验收滤波器。所有的寄存器和RAM都以32位字宽度来访问。 CAN自动波特率检测主要用于以一种CAN的转换的产品中。产品中CAN部分的波特率以前都是通过网页中修改然后配置下去的,依据实际情况的考虑,如果CAN部分的波特率能够根据客户设备的改变而自动改变,将会增加其灵活性。   二、原理 根据CAN控制器的

菜鸟的痕迹专栏 5273

OCTA-500:用于光学相干断层扫描血管造影研究的视网膜数据集|文献速递-基于生成模型的数据增强与疾病监测应用

数据集提供了丰富的图像和注释,包括两种模态(OCT/OCTA体积)、六种投影类型、四种文本标签(年龄/性别/眼别/疾病)以及七种分割标签(大血管/毛细血管/动脉/静脉/2D FAZ/3D FAZ/视网膜层)。我们介绍了新的 OCTA-500 数据集,该数据集包含来自 500 名受试者的 OCTA 成像,并提供了丰富的图像和标注集。(C) OCTA-500 切片的人工标注示例。图 4. OCTA-500 数据集中文本标签的统计直方图:(a) 性别,(b) 眼别,(c) 年龄,(d) 疾病。

weixin_38594676的博客 1437

mysql中的mvcc机制

MVCC全称是【Multi-Version ConCurrency Control】即多版本控制协议。 MVCC的主要是靠在每行记录上增加隐藏列和使用undo log来实现的,隐藏列主要包括,改行数据创建的版本号(递增的),删除时间,指向undo log的指针等。MVCC是读不加锁的,只有在写的时候才会加锁,从而提高的并发的效率。 那么MVCC是如何保证读写隔离的呢?主要是通过快照读和当前读两个操作。 快照读: MVCC为了保证并发的效率,在进行读取数据的时候是不加锁的,在执行select的时候(不带

ldw1986hf123的博客 1446

在Simulink中进行基于模拟信号数字化处理的仿真

模拟信号数字化处理通常包括以下几个步骤:采样、量化、编码以及数字信号处理(如滤波、变换等)。Simulink提供了丰富的模块库,可以方便地实现这些步骤,并支持对整个系统的实时仿真与调试。首先明确你的系统需求,比如输入信号类型(正弦波、方波等)、采样率、需要执行的数字信号处理操作(低通滤波、频谱分析等)。假设我们需要处理一个50Hz的正弦波信号,采样率为1kHz,并希望对该信号进行低通滤波以去除高频噪声。本文介绍了如何在Simulink中进行基于模拟信号数字化处理的仿真。

xiaoheshang_123的博客 626

Mysql基础篇-25-Mvcc与锁的理解(事务隔离级别)

Mysql锁和事务

Alan0517 1427

华为OD机试双机位C卷-流水线(Py/Java/C/C++/Js/Go)

华为OD机试双机位C卷 流水线,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解。华为OD机试 - 流水线。

qq_45776114的博客 2267

在 SAP GUI Editor 中使用 OpenAI 自动生成 ABAP 代码 —— 技术实践与思考

在传统 SAP GUI Editor 场景下融入OpenAI开发者表达意图,模型负责实现。随着的持续演进,以及Joule等官方 Copilot 的加入,未来 ABAP 开发形态必将更加专注业务逻辑与架构设计,而把样板式编码交给 AI 自动完成。现在就动手试试,让你的下一段 ABAP 由 AI 来书写吧!

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 709

mysql mvcc知乎_InnoDB-MVCC与乐观锁

最近通过《高性能MySQL》一书学习MySQL方面的知识,在看到书中所讲InnoDB-MVCC部分的时候,有一种强烈的感觉,这不就是乐观锁吗(入门级小学徒的疑惑脸)?当下便去网上以各种方式查找阅读MVCC和乐观锁相关的博客,发现大部分的博客对于这两者之间的关系都只字不提,提了的也是众说纷纭,关于两者关系的细节方面也十分暧昧没有定论。在暂时无法得出最终结论的情况下,我先谈谈在学习这方面知识后我自己对...

weixin_39529302的博客 297

电子元器件-三极管终终篇:三极管工作原理详解、参数/手册详解、开关应用详解、Ib电流研究、开关应用实例

三极管工作原理与应用摘要 三极管是一种电流控制器件,通过小基极电流控制大集电极电流。其内部结构由高掺杂发射区、薄低掺杂基区和中等掺杂集电区组成,形成NPN或PNP结。三极管有三种工作状态: 截止区:发射结和集电结均反偏,无放大作用 放大区:发射结正偏,集电结反偏,Ic=βIb 饱和区:两结均正偏,Ic不再随Ib增大 作为开关使用时,需确保三极管深度饱和(Vce≈0.2V)。设计要点包括: 基极电阻计算确保Ib足够大 集电极电阻控制Ic 基极加下拉电阻提高抗干扰 NPN管作地开关,PNP管作电源开关 典型应用

qq_60226558的博客 313

深入理解InnoDB的MVCC:不是乐观锁,是更优雅的并发控制方案

MVCC的核心并非乐观锁,也非悲观锁,而是为每行数据维护多个历史版本,通过Read View判断版本可见性,让读操作通过无锁的快照读实现高性能,写操作通过加锁+Undo Log记录历史实现原子性。它是InnoDB跳出传统锁机制框架,为读多写少场景打造的独立并发控制体系,是数据库高性能的核心基石。

he_co的博客 737

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

#### mysql.innoDB的乐观锁mvcc机制 ####

转自:https://juejin.cn/post/6844904096378404872,仅做个人备份,浏览请务必看原文 转自:https://juejin.cn/post/6844904096378404872,仅做个人备份,浏览请务必看原文 转自:https://juejin.cn/post/6844904096378404872,仅做个人备份,浏览请务必看原文 为了方便描述,首先我们创建一个表book,就三个字段,分别是主键book_id, 名称book_name, 库存stock..

仅做个人笔记 157

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

#### 事务、并发问题、隔离级别、mysql.innoDB中的乐观锁(mvcc)和悲观锁 ####

三宗罪,事务并发可能出现的情况: 1. 脏读 概述:事务a读取,事务b修改 2. 不可重复读 概述:事务a读取,事务b修改 3. 幻读 概述:事务a读取,事务b插入 针对三宗罪,得出的隔离级别:(在innoDB中,仅手动悲观锁的时候,而乐观锁mvcc不需要这样) READ UNCOMMITTED(读未提交) 在读未提交隔离级别下,事务A可以读取到事务B修改过但未提交的数据。 可能发生脏读、不可重复读和幻读问题,一般很少使用此隔离级别。 READ COMMITTED(读提交)

仅做个人笔记 444

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

mysql:乐观锁 & 悲观锁 & CAS & synchronized及其他各种锁 & MVCC & InnoDB

1.悲观锁 总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。Java中synchronized和ReentrantLock(可重入锁)等独占锁就是悲观锁思想的实现。 2.乐观锁 总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但

s11show_163的博客 373

mysql innodb 并发_Mysql 的InnoDB事务方面的 多版本并发控制如何实现 MVCC

我们知道,mysql的innodb采用的是行锁,而且采用了多版本并发控制来提高读操作的性能。什么是多版本并发控制呢 ?其实就是在每一行记录的后面增加两个隐藏列,记录创建版本号和删除版本号,而每一个事务在启动的时候,都有一个唯一的递增的版本号。1、在插入操作时 : 记录的创建版本号就是事务版本号。比如我插入一条记录, 事务id 假设是1 ,那么记录如下:也就是说,创建版本号就是事务版本号。idnam...

weixin_29955689的博客 178

mysql mvcc实现乐观锁_MVCC-乐观锁

MysqlMVCC是乐观锁的一种实现方式,但并不是MVCC就等于乐观锁。乐观锁( Optimistic Locking)其实是一种思想。相对悲观锁而言,乐观锁假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让返回用户错误的信息,让用户决定如何去做。什么是MVCC?英文全称为Multi-Version Concurrency Co...

weixin_39725650的博客 415

mysql mvcc实现乐观锁_乐观锁与CAS,MVCC

乐观锁如一个金融系统,当某个操作员读取用户的数据,并在读出的用户数据的基础上进行修改时(如更改用户帐户余额),如果采用悲观锁机制,也就意味着整个操作过程中(从操作员读出数据、开始修改直至提交修改结果的全过程,甚至还包括操作员中途去煮咖啡的时间),数据库记录始终处于加锁状态,可以想见,如果面对几百上千个并发,这样的情况将导致怎样的后果。乐观锁机制在一定程度上解决了这个问题。乐观锁,大多是基于数据版本...

weixin_29064009的博客 516

mysql insert 乐观锁_【mysql】关于乐观锁

一、乐观锁介绍乐观锁( Optimistic Locking ) 相对悲观锁而言,乐观锁假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检,乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库如果提供类似于write_condition机制的其实都是提供的乐观锁。类似SVN悲观锁假定其他用户企图访问或者改变你正在访问、更改的对象的概率是很高的,因此...

weixin_27872611的博客 1867

MySQL的MVCC机制

MVCC是指多版本并发控制,MVCC是在并发访问数据库时,通过对数据进行多版本控制,避免因写锁而导致读操作的堵塞,从而很好的优化并发堵塞问题,为了用来处理读写冲突的手段和解决数据库的事务操作中的多线程并发安全问题的无锁并发控制技术。

Gscsd的博客 1212

InnoDB的MVCC

什么是MVCC MVCC即Multi-Version Concurrency Control,中文翻译过来叫多版本并发控制。 MVCC解决的问题 MySQl默认的存储引擎是InnoDB,默认的事务隔离级别是REPEATABLE RED(可重复度),这种事务隔离级别要求2个事务之间不能影响,而且还能支持并发,悲观锁无法达到这个性能要求。所以该隔离级别采用的是乐观锁的形式实现的,乐观锁采用的具体实现方...

weixin_42146996的博客 420

MySQL 多版本并发控制 MVCC

MySQL 多版本并发控制 MVCC

lolly1023的博客 1581

Mysql中MVCC原理

Mysql中MVCC原理 什么是MVCC? 英文全称为Multi-Version Concurrency Control,翻译为中文即 多版本并发控制。他无非就是乐观锁的一种实现方式。在Java编程中,如果把乐观锁看成一个接口,MVCC便是这个接口的一个实现类而已。 特点 1.MVCC其实广泛应用于数据库技术,像Oracle,PostgreSQL等也引入了该技术,即适用范围广 2.MVCC并没有简单的使用数据库的行锁,而是使用了行级锁,row_level_lock,而非InnoDB中的innodb_row

悟空Edison的博客 221

mvcc原理_Mysql中MVCC的使用及原理详解

准备测试环境:Mysql 5.7.20-log数据库默认隔离级别:RR(Repeatable Read,可重复读),MVCC主要适用于Mysql的RC,RR隔离级别创建一张存储引擎为testmvcc的表,sql为:CREATE TABLE testmvcc (id int(11) DEFAULT NULL,name varchar(11) DEFAULT NULL) ENGINE=InnoDB D...

weixin_39829307的博客 149
上一篇: 浅谈哈希表与其映射函数(哈希函数)
下一篇: InnoDB的多版本并发控制机制—— MVCC底层实现
Jeaforea
博客等级 码龄10年 30粉丝 29原创
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值