剖析MYSQL锁机制

深入剖析MySQL锁机制:从入门到精通 锁是数据库中用于控制并发访问的一种机制。它可以限制对数据的访问,确保在某个时刻只有一个事务可以修改数据,从而保证数据的一致性。共享锁(Shared Lock)也称为读锁,它允许多个事务同时读取同一份数据,但不允许并发的写操作。排他锁(Exclusive Lock)也称为写锁,它只允许一个事务对数据进行修改,其他事务无法读取或修改该数据。读锁(Read Lock)也称为共享锁,它允许多个事务同时读取同一份数据,但不允许并发的写操作。 阅读详情

剖析MYSQL锁机制

数据库锁设计的初衷是处理并发问题。作为多用户共享的资源,当出现并发访问的时候,数据库需要合理地控制资源的访问规则。锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,数据是一种供许多用户共享的资源。数据库的锁机制,就是数据库为了保证数据的一致性,而使各种共享资源在被并发访问变得有序所设计的一种规则。

从对数据操作的类型分类:

  • 读锁(共享锁):针对同一份数据,多个读操作可以同时进行,不会互相影响
  • 写锁(排他锁):当前写操作没有完成前,它会阻断其他写锁和读锁

根据加锁的范围,MySQL 里面的锁大致可以分成全局锁、表级锁和行锁三类

为了尽可能提高数据库的并发度,每次锁定的数据范围越小越好,理论上每次只锁定当前操作的数据的方案会得到最大的并发度,但是管理锁是很耗资源的事情(涉及获取,检查,释放锁等动作),因此数据库系统需要在高并发响应和系统性能两方面进行平衡,因此需要根据具体的业务需求选用合适的锁。

全局锁

全局锁是对整个数据库实例加锁,加锁后整个数据库处于只读状态,之后的数据更新语句(数据的增删改)、数据定义语句(包括建表、修改表结构等)和更新类事务的提交语句都将被阻塞执行。

MYSQL加全局锁的方式是 mysql> flush tables with read lock; 释放全局锁的命令为:mysql>unlock tables;,或者断开加锁的session的连接即可。

显然,一旦加上全局锁,整个数据库就不能更新,即新数据无法写入,这是非常影响业务的。因此全局锁的典型适用范围就是给数据库做全局逻辑备份(mysqldump),也就是把整库每个表都 select 出来存成文本。

让整个数据库处于只读状态是有比较大的风险的:

  • 在主库上备份,那么在备份期间都不能执行更新,业务基本上就能停止
  • 在从库上备份,那么备份期间从库不能执行主库同步过来的binlog,会导致主从延迟

但是如果在全局备份时不加全局锁,可能会导致数据的不一致性,即如果已经将某一个数据备份了之后,又对该数据进行了修改,那么就会造成主从数据库不一致的现象,并且binlog日志也会有不一致。也就是说,不加锁的话,备份系统备份的得到的库不是一个逻辑时间点,这个数据是逻辑不一致的。

官方自带的逻辑备份工具是 mysqldump。当 mysqldump 使用参数–single-transaction的时候,导数据之前就会启动一个事务,来确保拿到一致性快照视图。但是并不是所有的引擎都支持single-transaction,MyISAM 这种不支持事务的引擎,如果备份过程中有更新,总是只能取到最新的数据,那么就破坏了备份的一致性。因此single-transaction 方法只适用于所有的表使用事务引擎的库。如果有的表使用了不支持事务的引擎,那么备份就只能通过 FTWRL 方法。

既然要全库只读,为什么不使用 set global readonly=true 的方式?

  • readonly=true可以令全局进行只读状态,但是要小心发生异常。如果执行 FTWRL 命令之后由于客户端发生异常断开,那么 MySQL 会自动释放这个全局锁,整个库回到可以正常更新的状态。而将整个库设置为 readonly 之后,如果客户端发生异常,则数据库就会一直保持 readonly 状态,这样会导致整个库长时间处于不可写状态,风险较高。并且readonly 对super用户权限无效。
表级锁

MySQL 里面表级别的锁有两种:一种是表锁,一种是元数据锁(meta data lock,MDL)

表锁的语法是 lock tables … read/write,可以用 unlock tables 主动释放锁,也可以在客户端断开的时候自动释放。如果在某个线程 A 中执行 lock tables t1 read, t2 write; 这个语句,则其他线程写 t1、读写 t2 的语句都会被阻塞。同时,线程 A 在执行 unlock tables 之前,也只能执行读 t1、读写 t2 的操作,也不能去访问其他表。

另一类表级的锁是 MDL(metadata lock)。MDL 不需要显式使用,在访问一个表的时候会被自动加上,MDL 的作用是,保证读写的正确性。在 MySQL 5.5 版本中引入了 MDL,当对一个表做增删改查操作的时候,加 MDL读锁;当要对表做结构变更操作的时候,加 MDL 写锁。读锁是不互斥的,多个读锁可以同时加上去,但加上读锁后不可以加上去写锁,写锁是互斥的,加上写锁后不可以再加其他锁。

通常来说,表级锁更适合于以查询为主,只有少量按索引条件更新数据的应用,如Web应用。

MyISAM 的表锁有两种模式:

  • 表共享读锁 (Table Read Lock):不会阻塞其他用户对同一表的读请求,但会阻塞对同一表的写请求;
  • 表独占写锁 (Table Write Lock):会阻塞其他用户对同一表的读和写操作;

MyISAM 表的读操作与写操作之间,以及写操作之间是串行的。当一个线程获得对一个表的写锁后, 只有持有锁的线程可以对表进行更新操作。 其他线程的读、 写操作都会等待,直到锁被释放为止。

默认情况下,写锁比读锁具有更高的优先级:当一个锁释放时,这个锁会优先给写锁队列中等候的获取锁请求,然后再给读锁队列中等候的获取锁请求。

不过需要注意的是,事务中的 MDL 锁,在语句执行开始时申请,但是语句结束后并不会马上释放,而会等到整个事务提交后再释放,因此要谨慎使用,可能导致死锁。

因此如果有长事务需要MDL锁,那么由于事务一直不提交,就会一直占着 MDL 锁。在 MySQL 的information_schema 库的 innodb_trx 表中,你可以查到当前执行中的事务。如果你要做 DDL 变更的表刚好有长事务在执行,要考虑先暂停 DDL,或者 kill 掉这个长事务。对于热点表,请求非常频繁,那么在 alter table 语句里面设定等待时间,如果在这个指定的等待时间里面能够拿到 MDL 写锁最好,拿不到也不要阻塞后面的业务语句,先放弃。

还有补充的是,在自动加锁的情况下,MyISAM 总是一次获得 SQL 语句所需要的全部锁,所以 MyISAM 表不会出现死锁。【因为没有事件】

行锁

行锁的开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。InnoDB 是支持行锁的,MyISAM 引擎就不支持行锁。

行锁是两阶段锁,在 InnoDB 事务中,行锁是在需要的时候才加上的,但并不是不需要了就立刻释放,而是要等到事务结束时才释放。因此,为了尽可能提高并发度,加快处理速度,如果事务中需要锁多个行,要把最可能造成锁冲突、最可能影响并发度的锁尽量往后放。

行锁很容易引发死锁,如下面的例子:
在这里插入图片描述

事务 A 在等待事务 B 释放 id=2 的行锁,而事务 B 在等待事务 A 释放 id=1 的行锁。 事务 A 和事务 B 在互相等待对方的资源释放,就是进入了死锁状态.

当出现死锁以后,有两种策略:

  • 一种策略是,直接进入等待,直到超时。这个超时时间可以通过参数 innodb_lock_wait_timeout 来设置。

  • 另一种策略是,发起死锁检测,发现死锁后,主动回滚死锁链条中的某一个事务,让其他事务得以继续执行。将参数 innodb_deadlock_detect 设置为 on,表示开启这个逻辑。

第一种方案中,超时值的设定就比较麻烦,如果超时值设置太大,那么可能导致等待时间过长,对线上服务产生非常不好的影响,如果超时值设定太小,会产生比较多的误伤,正常的锁等待可能会被误判。

所以,正常情况下我们还是要采用第二种策略,即:主动死锁检测,而且 innodb_deadlock_detect 的默认值本身就是 on。主动死锁检测在发生死锁的时候,是能够快速发现并进行处理的,但是它也是有额外负担的。

每当一个事务被锁的时候,就要看看它所依赖的线程有没有被别人锁住,如此循环,最后判断是否出现了循环等待,也就是死锁,因此对每个新来的被堵住的线程,都要判断会不会由于自己的加入导致了死锁,这是一个时间复杂度是 O(n) 的操作,因此整体是O(n2n^2n2)的时间复杂度。

通常来说,行级锁则更适合于有大量按索引条件并发更新少量不同数据,同时又有并发查询的应用,如一些在线事务处理(OLTP)系统。

InnoDB 实现的两种类型的行锁:

  • 共享锁(S):允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。
  • 排他锁(X):允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集的共享读锁和排他写锁
加锁机制

乐观锁与悲观锁是两种并发控制的思想,可用于解决丢失更新问题

乐观锁会“乐观地”假定大概率不会发生并发更新冲突,访问、处理数据过程中不加锁,只在更新数据时再根据版本号或时间戳判断是否有冲突,有则处理,无则提交事务。用数据版本(Version)记录机制实现,这是乐观锁最常用的一种实现方式。

悲观锁会“悲观地”假定大概率会发生并发更新冲突,访问、处理数据前就加排他锁,在整个数据处理过程中锁定数据,事务提交或回滚后才释放锁。另外与乐观锁相对应的,悲观锁是由数据库自己实现了的,要用的时候,我们直接调用数据库的相关语句就可以了。

Labview及NI-USRP驱动安装教程 软件下载 安装使用的LabVIEW2018及NI-USRP驱动程序已上传,下载地址: 天翼云盘链接 (访问码:oc33) 百度网盘链接 (提取码:88mi) (注:天翼云盘下载不限速) LabVIEW2018安装步骤 右键软件压缩包选择解压至LabVIEW2018 选中文件,鼠标右击选择以管理员身份打开2018LV-WinChn.exe文件。 点击确定。 点击Unzip解压。 点击确定。 点击下一步。 填写任意信息后,点击下一步。 点击下一步。 点击浏览更改安装路径建议安装到除C盘以 阅读详情

相关推荐

边缘计算【智能+安全检测】系列教程--使用OpenCV+GStreamer实现真正的硬解码,完全消除马赛克

通过现有博客的GStreamer的解码方式解码,大多情况应该存在上图马赛克的问题,请勿紧张,其实上述url并没有调用硬件解码,后面有调用硬件解码的ULR,我们来在接下来的介绍中释获。通过RTSP协议连接海康威视摄像头将图片送入AI推理,发现OpenCV的VideoCapture使用的是软解码大量消耗了cpu的资源,并无法做到实时数据处理存在5秒钟的延时。只能把解码这部分送到硬件解码器去处理分摊掉cpu的压力,

Starry-SkyJing的博客 2427

mysql全局读写怎么锁_MySQL 笔记整理(6) --全局锁和表锁:给表加个字段怎么有这么多阻碍...

笔记记录自林晓斌(丁奇)老师的《MySQL实战45讲》6) --全局锁和表锁:给表加个字段怎么有这么多阻碍数据库锁设计的初衷是处理并发问题。作为多用户共享的资源,当出现并发访问的时候,数据库需要合理地控制资源的访问规则。而锁就是用来实现这些访问规则的重要结构。根据加锁的范围,MySQL里面的锁大致可以分为全局锁,表级锁和行锁三类。这篇笔记主要包含全局锁和表级锁。行锁的内容会在之后再进行分享。全局锁...

weixin_35764532的博客 269

如何适配自定义激光雷达数据到LIO-SAM:解决ring和time参数缺失问题

本文详细解析了如何将非标准激光雷达(如速腾、Livox)适配到LIO-SAM框架中,重点解决ring和time参数缺失问题。提供了从源码修改到通用适配中间件的多层级解决方案,并包含实机测试与性能调优指南,帮助开发者高效完成雷达数据适配。

weixin_42551227的博客 421

什么是数据库的锁?怎么实现?

什么是数据库的锁?怎么实现?

weixin_63791423的博客 1430

5分钟搞定!用FunASR在本地快速部署达摩院Paraformer语音识别模型

本文提供了一份快速部署指南,教你如何在5分钟内利用FunASR工具包在本地电脑上启动达摩院Paraformer语音识别模型。Paraformer作为一款非自回归端到端模型,以其推理速度快、识别精度高的特点,结合FunASR的一键式模型加载和统一API,让开发者能轻松构建本地语音识别系统,极大降低了前沿AI技术的应用门槛。

q9w8e7r6t5的博客 605

echarts如何实现3D饼图(环形图)?

自定义修改3D饼图的宽高和legend

i-cat的博客 1万+

Mysql的锁原来就是这样啊

还是不懂的可以@我。

2201_75397629的博客 1528

setup time和hold time的计算

内容仅仅为了方便记忆,与原理无关

sddhyl的博客 7818

关于数据库MySQL的锁看这篇就够了...

​ 全局锁就是对整个数据库实例加锁,加锁后整个实例就处于只读状态,后续的DML的写语句,DDL语 句,已经更新操作的事务提交语句都将被阻塞。其典型的使用场景是做全库的逻辑备份,对所有的表进行锁定,从而获取一致性视图,保证数据的完整性。为什么全库逻辑备份,就需要加全就锁呢?A. 我们一起先来分析一下不加全局锁,可能存在的问题。假设在数据库中存在这样三张表:tb_stock 库存表,tb_order 订单表,tb_orderlog 订单日志表。此时备份出来的数据,是存在问题的。

豆恭梓的博客 405

基于Java的高校学生信息管理系统的设计与实现(论文+源码)

可以对本系统的数据进行良好的封装,Java可以对不想被访问的数据进行良好的隐藏,具备平台无关性,可移植,更加可靠与安全,具备多线程支持,进行网络交互更容易。它支持本系统的B/S模式。开发效益方面,本系统一旦开发成功并且面向社会,就会让大多数的学生教师体会到便利办公的乐趣,随之促进提高本系统的使用率和经济利润,所以在经济方面,对于零成本开发且高利润的学生管理系统是可行的。学生可以在学生端进行选课,查看自己的成绩,教师可以在教师端查看所任课程的选课情况,对学生成绩进行录入,对所任的课程进行结课等操作。

2402_82389843的博客 1094

PyTorch生成式人工智能(7)——生成对抗网络(Generative Adversarial Network, GAN)实践详解

生成对抗网络 (Generative Adversarial Network, GAN) 最早由 Ian Goodfellow 于 2014 年提出,其中生成器试图创建与真实样本无法区分的数据样本,而判别器则试图区分生成器生成的样本与真实样本。在本节中,我们将介绍 GAN 的理论基础。然后,介绍如何使用 PyTorch 从零开始构建 GAN,以便了解所有细节,深入理解 GAN 的内部工作原理,为后续讨论 GAN 的其他更高级内容奠定基础,比如生成高分辨率图像或逼真的音乐。

盼小辉丶的博客 1万+

数据库锁机制深度解析:场景、SQL 示例与实战应用

通过结合具体业务场景选择锁机制,并配合 SQL 语句精准控制,可在保证数据一致性的同时最大化数据库并发性能。

m0_57836225的博客 693

Mastercam软件二次开发:使用C#进行Mastercam二次开发

C#(发音为“C Sharp”)是一种现代、面向对象的编程语言,由微软开发,首次发布于2000年。它结合了C和C++的强大功能,同时引入了Java的垃圾回收机制,使得C#在开发效率和运行性能之间找到了一个良好的平衡点。C#的设计目标是提高开发者的生产力,它支持多种编程范式,包括面向对象、泛型、委托和事件等,这使得它成为开发Windows应用程序、Web应用程序、游戏(尤其是使用Unity引擎)和企业级应用的理想选择。

kkchenjj的博客 2216

Mysql锁机制与优化实践以及MVCC底层原理剖析

锁是协调多进程/线程并发访问资源的机制,用于解决数据库并发访问中的数据一致性问题。

weixin_74024217的博客 516

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

深入剖析MySQL锁机制,多事务并发场景锁竞争

锁定聚簇索引中的一条具体记录。锁住两条索引记录之间的范围(gap),但不包括已有的记录。即锁住记录本身其前面的间隙关键点内容锁竞争由事务访问冲突资源引发,可能阻塞回滚自动或手动撤销事务操作,使用 Undo 日志还原死锁检测InnoDB 内部维护等待图,自动检测并终止代价小的事务调试工具、慢查询日志等。

lrj41781196的博客 1263

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

MySQL 锁机制深度剖析

在现代数据库管理系统中,锁机制是确保数据一致性和完整性的至关重要的部分。MySQL 作为一种广泛使用的关系型数据库,其锁机制设计旨在提供高效的并发控制,以支持多用户环境下的数据操作。本文将深入探讨 MySQL 的锁机制,包括锁的类型、模式、实现机制、死锁处理以及优化策略等。

兀行者的博客 933

SAP B1中文培訓教材_SDK

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

深入底层剖析Mysql各种锁机制

乐观锁 乐观锁是一种乐观思想,即认为读多写少,遇到并发写的可能性低,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,采取在写时先读出当前版本号,然后加锁操作(跟上一次的版本号比较,如果一样则更新),如果失败则要重复读-比较-写的操作。 java 中的乐观锁基本都是通过 CAS 操作实现的,CAS 是一种更新的原子操作,比较当前值跟传入值是否一样,一样则更新,否则失败。 悲观锁 悲观锁是就是悲观思想,即认为写多,遇到并发写的可能性高,每次去拿数据

陈三千的博客 2551

【数据库】【MySQL】锁机制 从粒度到模式的剖析

MySQL锁机制是实现并发控制的核心,主要包括表锁和行锁两种粒度。表锁开销小但并发度低,适合读多写少的场景;行锁开销大但并发度高,必须命中索引否则退化为表锁。锁模式分为共享锁(S锁)、排他锁(X锁)和意向锁,其中意向锁是表级锁,用于协调表锁和行锁的关系。InnoDB还提供特殊锁机制如间隙锁(防止幻读)、临键锁(默认RR级别锁)和插入意向锁(提高插入并发)。不同隔离级别下锁行为不同:RC级别仅加行锁,无间隙锁;RR级别使用Next-Key Lock锁定记录和间隙防止幻读。

瘦到被风吹走的博客 753

Mysql事务隔离级别、锁机制及MVCC底层原理剖析

我们的数据库一般都会并发执行多个事务,多个事务可能会并发的对相同的一批数据进行增删改查操作,可能就会导致我们说的脏写、脏读、不可重复读、幻读这些问题。这些问题的本质都是数据库的多事务并发问题,为了解决多事务并发问题,数据库设计了事务隔离机制、锁机制、MVCC多版本并发控制隔离机制,用一整套机制来解决多事务并发问题。接下来,我们会深入讲解这些机制,让大家彻底理解数据库内部的执行原理。

IAtlantiscsdn的博客 603

【MySQL】第7节|Mysql锁机制与优化实践以及MVCC底层原理剖析

MVCC是InnoDB实现高并发的基石,通过版本链和读视图在。

泽韦德的专栏 1473

深入剖析MySQL InnoDB锁机制:从原理到实战优化

数据库锁是实现事务隔离性的核心机制,用于协调多事务对共享数据的并发访问。其基本原理是通过共享锁(S Lock)和排他锁(X Lock)等锁类型,配合意向锁(Intention Locks)实现高效的锁冲突检测,从而在保证数据一致性的前提下提升并发性能。在MySQL InnoDB引擎中,锁与MVCC(多版本并发控制)协同工作,区分了不加锁的“快照读”和需要加锁的“当前读”,这是理解其高并发能力的关键。锁的技术价值在于,它是诊断和解决数据库性能瓶颈、死锁问题的核心工具,直接影响着高并发在线系统的稳定性和吞吐量。

weixin_29280657的博客 267

MySQL数据库进阶(九)———事务与锁机制深度剖析

在掌握了查询优化后,我们将深入MySQL最核心的并发控制领域——事务与锁机制。本文将从ACID原理到锁实现机制,全面解析MySQL如何保障数据一致性和高并发能力,助你构建高可靠数据库系统

本人的博客 1408

MySQL的锁机制:从全局锁到行级锁的全面剖析

MySQL锁机制全面解析 文章深入剖析了MySQL的锁机制,涵盖全局锁、表级锁和行级锁三种粒度。全局锁(FTWRL)用于全库备份但会阻塞所有写操作,可通过MVCC机制优化;表级锁包括显式表锁、元数据锁(MDL)、AUTO-INC锁和意向锁,其中MDL锁保护表结构变更,意向锁协调表锁与行锁;行级锁实现精细并发控制。文章详细分析了各种锁的加锁方式、应用场景、性能影响及替代方案,并提供了丰富的SQL示例演示锁行为,帮助开发者理解MySQL并发控制机制,优化高并发系统设计。

weixin_54644789的博客 687
上一篇: 深入浅出MYSQL索引
下一篇: 深入浅出MYSQL的事务隔离
coding丁
博客等级 码龄9年 383粉丝 147原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值