MySQL 锁机制

2023-09-19 11:50:42

MySQL 锁机制

1、什么是锁

  • 为了保证数据并发访问时的一致性和有效性,数据库会提供锁机制
  • 锁机制的优劣直接影响到数据库的并发处理能力和系统性能
  • 锁机制是为了解决数据库的并发控制问题而产生的一种控制机制(比如转账的转入转出)

2、锁的缺点

锁是一种消耗资源的机制,锁的各种操作,包括获得锁检测锁是否已解除释放锁等 ,都会增加系统的开销

3、锁的分类

为了尽可能提高数据库的并发量,每次锁定的数据范围越小越好,但是锁定越小的范围,耗费的系统资源越多,也会系统性能下降。所以,为在高并发响应和系统性能两方面进行平衡,这样就产生了“锁粒度”的概念,可以将锁粒度理解成锁定范围。

MySQL 按锁的粒度可以细分为:表级锁、行级锁、页级锁

3.1 表级锁
(1)什么是表级锁
  • 表级锁是一种表级别的锁定机制。它会锁定整张表,可以很好的避免死锁,是 MySQL 中最大颗粒度的锁定机制。
  • 表级锁根据操作的不同,分为:读锁(共享锁)、写锁(排他锁)。
  • MyISAM存储引擎默认使用表级锁
(2)读锁
  • 读锁(read lock),也叫共享锁(shared lock)。
  • 一个用户在对表进行读操作(select)时, 针对同一份数据,多个读操作可以同时进行而不会互相影响
(3)写锁
  • 写锁(write lock),也叫排他锁(exclusive lock)。
  • 一个用户在对表进行写操作(插入、删除、更新等)时,需要先获得写锁,它会阻塞其它用户对该表的所有读写操作,具备排他性
(4)读锁和写锁的总结
  1. 读锁会阻塞写操作,不会阻塞读操作
  2. 写锁会阻塞读和写操作
(5)表级锁的优点和缺点
  • 表级锁是MySQL 中锁定粒度最大的一种锁,最大的特点就是实现逻辑非常简单,对当前操作的整张表加锁,资源消耗也比较少,加锁和释放锁的速度很快,不会出现死锁。
  • 表级锁定颗粒度大,带来最大的缺点就是:锁定资源争用的概率会很高,触发锁冲突的概率最高,并发性最低
(6)表级锁优缺点总结
  1. 对整张表加锁
  2. 开销小
  3. 加锁快
  4. 无死锁
  5. 锁粒度大,发生锁冲突概率大,并发性低
3.2 行级锁
(1)什么是行级锁
  • 行级锁的锁定颗粒度在 MySQL 中是最小的,只针对操作的当前行进行加锁,所以行级锁发生锁定资源争用的概率也最小。
  • 由于锁定资源的颗粒度很小,所以每次获取锁和释放锁需要处理并发逻辑更多,同时消耗的资源也就更大。
  • 此外,行级锁也最容易发生死锁。所以说行级锁最大程度地支持并发处理的同时,也带来了最大的锁开销。
  • 行级锁根据操作的不同,分为:读锁(共享锁 S)、写锁(排他锁 X)、意向共享锁(IS)、意向排它锁(IX)。
  • InnoDB 存储引擎默认使用行级锁
(2)读锁 S
  • 读锁(read lock),也叫共享锁(shared lock)。
  • 允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁
(3)写锁
  • 写锁(write lock),也叫排他锁(exclusive lock)。
  • 允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集的共享锁和排他锁
(4)意向共享锁IS

一个事务给一个数据行加共享锁时,必须先获得该表的意向共享锁,简称IS

(5)意向排他锁IX

一个事务给一个数据行加排他锁时,必须先获得该表的意向排他锁,简称IX

(6)行级锁的优点和缺点

行级锁是MySQL 中锁定粒度最小的一种锁,是针对索引字段加的锁,只针对当前操作的行记录进行加锁。 行级锁能大大减少数据库操作的冲突。其加锁粒度最小,并发性高,但加锁的开销也最大,加锁慢,会出现死锁

(7)行级锁的优缺点总结
  1. 对一行数据加锁
  2. 开销大
  3. 加锁慢
  4. 会出现死锁
  5. 锁粒度小,发生锁冲突概率最低,并发性高
3.3 页级锁
  • 页级锁是 MySQL 中比较独特的一种锁定级别。
  • 页级锁的颗粒度介于行级锁与表级锁之间,所以获取锁定所需要的资源开销,以及所能提供的并发处理能力同样也是介于上面二者之间。另外,页级锁和行级锁一样,会发生死锁。
  • 页级锁主要应用于 BDB 存储引擎
3.4 行级锁的实现算法

MySQLInnoDB存储引擎中,行锁通过给索引树中的索引项加锁来实现,如果没有索引,InnoDB 将通过隐藏的主键索引(聚集索引)引来对记录加锁。

InnoDB 主要通过以下 3 种算法实现行级锁

  • 记录锁Record Lock):直接对索引项加锁,属于单个行记录上的锁。Record Lock总是会去锁住索引记录,如果InnoDB存储引擎表建立的时候没有设置任何一个索引,这时InnoDB存储引擎会使用隐式的主键来进行锁定。
  • 间隙锁Gap Lock):间隙锁是一个在索引记录之间的间隙上进行锁定。间隙可以是两个索引记录之间,也可能是第一个索引记录之前或最后一个索引之后的空间。间隙锁会锁定该间隙空间,防止其它事务在这个区域内插入、修改、删除数据;
  • 临键锁(Next-Key Lock):记录锁+间隙锁组合起来用就叫做临键锁 Next-Key Lock。 锁定一个范围,同时包含记录本身。记录锁只能锁住已经存在的记录,为了避免插入新记录,需要依赖间隙锁
3.5 总结
表级锁行级锁页级锁
开销介于表级锁和行级锁之间
加锁介于表级锁和行级锁之间
死锁不会出现死锁会出现死锁会出现死锁
锁粒度介于表级锁和行级锁之间
锁粒度一般

4、锁的兼容与互斥

锁和锁之间的关系,要么是兼容的,要么是互斥的。

  • a 和锁 b 兼容是指:操作同样一组数据时,如果事务 t1 获取了锁 a,另一个事务 t2 还可以获取锁 b
  • a 和锁 b 互斥是指:操作同样一组数据时,如果事务 t1 获取了锁 a,另一个事务 t2 t1 释放锁 a 之前无法释放锁 b

其中共享锁、排他锁、意向共享锁、意向排他锁相互之间的兼容/互斥关系如下表所示,其中 Y 表示相容,N 表示互斥

参数X(排他锁)S(共享锁)IX(意向排他锁)IS(意向共享锁)
X(排他锁)NNNN
S(共享锁)NYNY
IX(意向排他锁)NNYY
IS(意向共享锁)NYYY

如果一个事务请求的锁模式与当前的锁兼容,InnoDB 就将请求的锁授予该事务;反之,如果两者不兼容,该事务就要等待锁释放

5、乐观锁与悲观锁

5.1 悲观锁(Pessimistic Lock)
  • 悲观锁(又名“悲观并发控制”,Pessimistic Concurrency Control,缩写“PCC”)是一种并发控制的方法。它可以阻止一个事务以影响其他用户的方式来修改数据。如果一个事务执行的操作读某行数据应用了锁,那只有当这个事务把锁释放,其他事务才能够执行与该锁冲突的操作。
  • 所以,悲观锁从名称上顾名思义,就是很悲观的锁定思想,每次去拿数据的时候都认为其它的事务会修改,所以每次在拿数据的时候都会上锁,这样其它事务想要获取这个数据就会被block阻塞,直到当前事务释放锁。关系型数据库中的行锁,表锁,读锁,写锁等,都是在做操作之前先上锁。它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。
  • 悲观锁主要用于数据争用激烈的环境,以及发生并发冲突时使用锁保护数据的成本要低于回滚事务的成本的环境中
5.2 乐观锁(Optimistic Lock)

顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于读多写少的应用场景

5.3 比较
  • 两种锁各有优缺点:
  • 乐观锁适用于写比较少的情况下,即:并发冲突相对较低的场景。这样可以省去了锁的开销,加大了系统的整个吞吐量。
  • 悲观锁适用于写入比较多的情况下,因为如果经常产生数据冲突,使用乐观锁,应用程序会不断的retry,这样反倒是降低了性能,所以这种情况下用悲观锁就比较合适

6、死锁

  • 数据库的死锁是指两个或两个以上的事务在执行过程中,因争夺资源而造成的一种互相等待的现象。常见的报错信息为“Deadlock found when trying to get lock…”。
  • 死锁发生以后,只有部分或完全回滚其中一个事务,才能打破死锁。多数情况下只需要重新执行因死锁回滚的事务即可。

在实际应用中,我们通过下面几种方式避免死锁的方法:

  1. 如果不同程序会并发存取多个表,或者涉及多行记录时,尽量约定以相同的顺序访问表,这样可以大大降低死锁的发生。
  2. 业务中要及时提交或者回滚事务,可减少死锁产生的概率。
  3. 在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁产生概率。
  4. 对于非常容易产生死锁的业务部分,可以尝试使用升级锁粒度,通过表锁定来减少死锁产生的概率(表级锁不会产生死锁)
更多推荐

铁路设备屡遭破坏!RFID电子锁实现铁路防护网破坏实时报警管理

铁路防护网是铁路运输中保障安全的重要组成部分,然而,铁路设备被破坏的情况时有发生,给铁路运输带来了严重的安全隐患和经济损失。一、铁路防护网面临的挑战铁路防护网作为铁路运输的重要保障措施,时刻面临着破坏行为的威胁。传统的锁控系统存在以下问题:开关锁记录不完善:传统锁控系统无法准确记录每次开锁和关锁的时间、地点以及操作人员

Xamarin.Android实现App内版本更新

目录1、具体的效果2、代码实现2.1基本原理2.2开发环境2.3具体代码2.3.1基本设置2.3.2系统的权限授予2.3.3进度条的layout文件2.3.4核心的升级文件3、代码下载4、知识点5、参考文献1、具体的效果有事需要在程序内集成自动更新的功能,网上找了下,改改适配下Xamarin.Android,效果如下2

API接口文档管理系统平台搭建(更新,附系统源码及教程)

简介这是一款简洁大方的API接口文档管理系统,附系统源码及教程方法。可以轻松管理和使用API接口。安装步骤打开config/database.php配置数据库信息导入数据库data.sql设置运行目录为/public伪静态设置thinkPHP后台地址/admin/login.html账号:admin密码:123456源

LLM(一)| 百川智能baichuan7B、13B、53B以及baichuan2总结

之前在文章baichuan-53BVSChatGLM-6B对比中做过百川大模型53B和ChatGLM6B模型的效果对比,由于百川大模型的内测模型是53B,因此本次对比参数量差异较大,但仍然可以看到两个模型的效果。百川大模型在benchmark上有超越ChatGLM和LLaMA的迹象,尤其是在中文任务上的表现,下面分别对

让Pegasus天马座开发板吃上STM8S标准库

WeCanStudio官方仓库的示例工程,只提供基于STM8S003寄存器方式来开发Pegasus天马座开发板。在此,我将基于官方的工程示例,将STM8S标准库移植到工程中。先上图,看运行结果:main.c文件#include"config.h"#include"delay.h"#defineLED_GPIO_PORT

OpenGL之着色器

着色器(Shader)是运行在GPU上的小程序。这些小程序为图形渲染管线的某个特定部分而运行。从基本意义上来说,着色器只是一种把输入转化为输出的程序。着色器也是一种非常独立的程序,因为它们之间不能相互通信;它们之间唯一的沟通只有通过输入和输出。GLSL着色器是使用一种叫GLSL的类C语言写成的。GLSL是为图形计算量身

MyCat主从数据库集群搭建

1背景最近工作需要对比几种数据库技术方案,主从读写分离集群也是其中之一。接着上一篇文章《MySQL主从数据库搭建》基础上继续搭建MyCat主从集群。2MyCat什么是MyCat?MyCat是数据库中间件,就是介于数据库和应用之间,进行数据处理与交互的中间服务。可以对数据进行分片处理,从原有一个库,被切分为多个分片数据库

安装torch113、cuda116并运行demo【Transformer】

文章目录01.导读02.显卡驱动版本03.创建环境、下载安装必要包04.运行参考代码:01.导读安装torch113、cuda116并运行demo【Transformer】02.显卡驱动版本C:\Users\Administrator>nvidia-smi-l10WedSep1323:35:082023±-------

Docker 原理

基础技术试验进程linuxnamespaceMount(mnt)namespace可以在不影响宿主机文件系统的基础上挂载或者取消挂载文件系统了;PID(ProcessID)在一个pidnamespace中,第一个进程的pid为1,所有在此namespace中的其他进程都是此进程的子进程,操作系统级别的其他进程不需要在此

kruskal重构树

Kruskal重构树第二次学了。大致思路就是在最小生成树加边的时候,把每条边也设一个点,和他连着的两个点连边。由于最小生成树的贪心,感觉很像哈夫曼树,有性质是经过的边的长度(已经转化为点权)越向上越大/越小,取决于生成树的排序。那就可以通过倍增找不经过长度超过x的边所能走到的所有点,实际上是一直往上跳的那个子树。for

红海云签约科百特,“膜界”小巨人人力资源数字化转型全面提速

杭州科百特过滤器材有限公司(以下简称“科百特”)是全球优秀的创新过滤企业,专注于纳米膜材料的开发和应用,致力于为全球集成电路制造和生物制药产业提供创新的过滤纯化解决方案。近日,科百特与广州红海云计算股份有限公司达成战略合作。红海云作为一家技术驱动的专业型厂商,基于深厚的人力资源管理专业积累和前沿的数字技术,成功打造了众

热文推荐