MySQL 锁分类有哪些?一文带你详解!!

MySQL 锁

    • 全局锁
      • 全局锁的应用场景
      • 全局锁的缺点
    • 表级锁
      • 表锁
      • 元数据(MDL)锁
        • MDL 锁的问题
      • 意向锁
      • AUTO-INC 锁
    • 行级锁
      • 记录锁(Record Lock)
      • 间隙锁(Gap Lock)
      • 临键锁(Next-Key Lock)
      • 插入意向锁

首先让我们创建一张用户表,并插入一些数据:

CREATE TABLE userinfo (user_id INT PRIMARY KEY AUTO_INCREMENT,username VARCHAR(50) NOT NULL,password VARCHAR(50) NOT NULL,email VARCHAR(100),created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);INSERT INTO userinfo (username, password, email) VALUES ('张三', 'password123', 'zhangsan@example.com');
INSERT INTO userinfo (username, password, email) VALUES ('李四', 'password456', 'lisi@example.com');
INSERT INTO userinfo (username, password, email) VALUES ('王五', 'password789', 'wangwu@example.com');

全局锁

插入全局锁的命令

flush tables with read lock

执行后,整个数据库就处于只读状态了,这时其他线程执行以下操作,都会被阻塞:

  • 对数据的增删改操作,比如 insert、delete、update等语句;
  • 对表结构的更改操作,比如 alter table、drop table 等语句。

比如此时我们想插入一条语句,但显示被读锁阻塞住了
在这里插入图片描述
执行释放锁之后的命令就可以插入成功了

unlock tables;

在这里插入图片描述

全局锁的应用场景

全局锁的应用场景主要应用于 全库逻辑备份

举个例子,如果不加读写锁的话

在备份用户表和商品表的时候,有一个用户购买了一件商品

就会导致备份的数据 是扣减前的用户余额 和 扣减后的商品余额 —— 用户余额没变,货却没了!

在这里插入图片描述

全局锁的缺点

加上全局锁后,数据库就变成了 只读状态

那么如果数据库有很多数据,备份就会花费很多时间,而且备份期间只能读数据而不能更新数据,就会导致业务的停滞

那有什么办法可以改进呢?

可以利用 MVCC 机制,在可重复读隔离级别下,开启事务后,会先创建一个 Read View,然后整个事务执行期间都会使用这个 Read View,同时也依然可以对数据进行更新操作。

这就是事务四大特性的 隔离性,这样备份期间备份的数据一直都是在开启事务时的数据。

注意,这需要能够适用 可重复读隔离级别 下的存储引擎,比如 Innodb。

但是 MyISAM 这种不支持事务的引擎,在备份数据库时就要使用全局锁的方法了。

表级锁

表锁

表锁有两种:

//表级别的共享锁,也就是读锁;
lock tables t_student read;//表级别的独占锁,也就是写锁;
lock tables t_stuent write;

这里的锁有点乱,我们可以做四次实验试试看

  1. 给表设置读锁,然后读数据,发现是正常没问题的
    在这里插入图片描述
  2. 然后我们进行写数据,发现被阻塞住了
    在这里插入图片描述

如图,这里我们给用户表设置了读锁,然后想写入一条数据,发现被阻塞住了

在这里插入图片描述

说明这里的本线程的表级别的读锁,会限制住本线程的写操作

  1. 我们解开表级锁,并设置读锁,然后再进行读操作

在这里插入图片描述
发现这里,阻塞住了,陷入了死锁状态,注意右下角的查询时间,这里是一直在查询没停止的(我只是截了个图),说明本线程的写锁也会限制住本线程的读操作

  1. 我们在写锁下进行写操作,正常没问题
    在这里插入图片描述

所以,可以看出来,表锁除了会限制别的线程的读写外,也会限制本线程接下来的读写操作。

所以,表锁的颗粒度是很大的,会影响到并发性能,尽量要避免使用,Innodb 牛逼的地方在于实现了颗粒度更细的行级锁。

元数据(MDL)锁

我们不需要显示的使用 MDL,因为当我们对数据库表进行操作时,会自动给这个表加上 MDL:

  • 当我们对一张表进行 CRUD 操作时,会对表加一个 元数据读锁;
  • 当我们对一张表的结构进行操作的时候,会对表加一个 元数据写锁

MDL 是为了保证当用户对表执行 CRUD 操作时,防止其他线程对这个表结构做了变更。

当有线程在执行 select 语句( 加 MDL 读锁)的期间,如果有其他线程要更改该表的结构( 申请 MDL 写锁),那么将会被阻塞,直到执行完 select 语句( 释放 MDL 读锁)。

反之,当有线程对表结构进行变更( 加 MDL 写锁)的期间,如果有其他线程执行了 CRUD 操作( 申请 MDL 读锁),那么就会被阻塞,直到表结构变更完成( 释放 MDL 写锁)。

MDL 锁的问题

MDL 是在事务提交之后才会释放的,也就是说,事务执行期间,MDL 是一直持有的

那如果数据库中有一个长事务,也就是开启之后一直没提交的事务,那当我们对表结构做变更操作的时候,可能就会出现一些问题:

  1. 线程A 开启了事务
  2. 线程A 执行了一条查询 select 语句,这时会加 MDL读锁
  3. 线程B 执行了一条查询 select 语句,这时不会阻塞,因为读读并不冲突
  4. 线程C 试图修改表字段,但此时事务A 并没有提交,所以 MDL 读锁就还占用着,此时线程C 就无法申请到 MDL 写锁,而导致阻塞
  5. 之后的线程 D、E、F 想要执行查询语句时,就会被阻塞住,然后数据库的线程就会爆满
    在这里插入图片描述

为什么写锁阻塞住,读锁也会被阻塞住?

因为 申请 MDL 锁的操作会形成一个队列,队列中 写锁获取的优先级高于读锁,一旦出现MDL 写锁等待,就会阻塞住该表的所有 CRUD 操作

在这里插入图片描述
所以,为了能安全的对表结构进行变更,在变更之前,我们要先看看数据库中的长事务,是否有事务已经对表加上了 MDL读锁,如果可以就考虑先 kill 掉他,然后再做变更。

意向锁

意向锁有两种:意向共享锁、意向排他锁:

  • 意向共享锁(Intention Shared Lock,IS):当一个事务请求获取一个行级锁或表级锁时,InnoDB会自动获取相应的表的意向锁。

这个锁表明事务打算以共享方式(读取)访问数据。其他事务在查询数据时,可以通过检查意向锁来快速确定是否有任何行级锁冲突,而无需检查表中每一行的锁状态。

  • 意向排他锁(Intention Exclusive Lock,IX):与意向共享锁类似,意向排他锁表明事务打算以排他方式(写入)访问数据。

当事务持有意向排他锁时,其他事务不能获取意向共享锁,从而防止其他读取操作的干扰。

也就是说,当执行插入、更新、删除操作,需要先对表加上「意向独占锁」,然后对该记录加独占锁。

而普通的 select 是不会加行级锁的,普通的 select 语句是利用 MVCC 实现一致性读,是无锁的。

不过,select 也是可以对记录加共享锁和独占锁的,具体方式如下:

//先在表上加上意向共享锁,然后对读取的记录加共享锁 
select ... lock in share mode;  //先表上加上意向独占锁,然后对读取的记录加独占锁 
select ... for update;

意向共享锁和意向独占锁是表级锁,不会和行级的共享锁和独占锁发生冲突,而且意向锁之间也不会发生冲突,只会和共享表锁(lock tables … read)和独占表锁(lock tables … write)发生冲突。

表锁和行锁是满足读读共享、读写互斥、写写互斥的。

如果没有「意向锁」,那么加「独占表锁」时,就需要遍历表里所有记录,查看是否有记录存在独占锁,这样效率会很慢。

那么有了「意向锁」,由于在对记录加独占锁前,先会加上表级别的意向独占锁,那么在加「独占表锁」时,直接查该表是否有意向独占锁,如果有就意味着表里已经有记录被加了独占锁,这样就不用去遍历表里的记录。

所以,意向锁的目的是为了快速判断表里是否有记录被加锁。

AUTO-INC 锁

auto-inc 锁(AUTO-INCREMENT lock),是InnoDB中用于处理自动增长(AUTO_INCREMENT)字段的一种特殊的锁定机制。当向表中插入数据时,如果该表包含有AUTO_INCREMENT列,并且你需要为这个列指定一个值,那么会涉及到auto-inc锁。

auto-inc锁的主要目的是确保在同一事务中插入的记录能够获得连续的AUTO_INCREMENT值。在并发插入的场景中,这可以避免插入操作之间的干扰,确保插入的顺序性。

行级锁

InnoDB 是支持行级锁的,而 MyISAM 是不支持的

记录锁(Record Lock)

记录锁是行级锁的一种,它针对数据表中的单个记录进行锁定,有 S 锁 和 X 锁之分,也就是共享锁和独占锁之分。

一个事务对一条记录加了 S 锁,其他事务可以加 S 锁,但不能加 X 锁

一个事务对一条记录加了 X 锁,其他事务 S 锁和 X 锁都不能加

记录锁通常是通过索引项来实现的,即数据库会锁定索引项来实现对行的锁定。

在这里插入图片描述

间隙锁(Gap Lock)

Gap Lock是锁定数据表中两个记录之间的空隙(即间隙锁)。

间隙锁只存在于可重复读隔离级别,目的是为了解决可重复读隔离级别下幻读的问题。

它用于防止其他事务插入新的记录,从而保护一个范围行的完整性。

Gap Lock不会锁定实际的行记录,而是锁定一个范围,阻止其他事务在这个范围内插入新行。

而且,间隙锁之间是不冲突的,可以相互兼容,只不过无法往间隙范围内插入数据

在这里插入图片描述

临键锁(Next-Key Lock)

Next-Key Lock是 记录锁 和 间隙锁 的组合。

它技能保护锁住的该条记录,又能阻止其他事务将其新纪录插入到被保护记录前面的间隙中

在这里插入图片描述

因为临键锁是包含 记录锁 + 间隙锁的,而间隙锁之间是可以相互兼容的,但记录锁就需要注意考虑 S 型 和 X 型的关系了

插入意向锁

插入意向锁是与上面的间隙锁对应生效的

如果一条记录的位置已经被其他事务加了间隙锁(当然,也包含临键锁中的间隙锁),那么,这个插入操作就会被阻塞,在此期间会生成一个 插入意向锁,表明有事务想要在某个区间插入新纪录,但是现在处于等待状态

比如事务 A 在一个区间内加了间隙锁,然后事务 B 想要在该区间插入一条语句,这时候发现有个间隙锁,于是就会生成一个 插入意向锁,然后将锁呢设置为等待状态。

MySQL 加锁的时候,会先生成锁结构,然后设置锁状态,锁状态为正常状态,就表示事务获取到了锁,如果为等待状态,就意味着没有获取到锁

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

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

相关文章

Opencv中的直方图(2)计算图像的直方图函数calcHist()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 计算一组数组的直方图。 函数 cv::calcHist 计算一个或多个数组的直方图。用于递增直方图bin的元组的元素是从相同位置的相应输入数组中获取的。…

Cursor是什么?Cursor Pro Plus 如何订阅升级教程

一、Cursor是什么? Cursor 是一个基于 Visual Studio Code(VS Code)技术构建的高级代码编辑器,专为提高编程效率并更深度地整合 AI 功能而设计。它不仅继承了 VS Code 的强大功能和用户界面,还增加了专门针对 AI 支持…

Agent(智能体)和 MetaGPT,一句话实现整个需求应用代码

前面 2 篇文章,我们使用文生文、文生图和文生音频三个大模型共同实现了图文并茂的儿童绘本故事和绘本故事音频需求: 第一篇 根据主题生成儿童绘本故事:GLM-4-Flash 大模型 API 免费了,手把手构建“儿童绘本”应用实战&#xff08…

Nuxt3入门:过渡效果(第5节)

你好同学&#xff0c;我是沐爸&#xff0c;欢迎点赞、收藏、评论和关注。 Nuxt 利用 Vue 的 <Transition> 组件在页面和布局之间应用过渡效果。 一、页面过渡效果 你可以启用页面过渡效果&#xff0c;以便对所有页面应用自动过渡效果。 nuxt.config.js export defaul…

概率DP (由一道绿题引起的若干问题。目前为一些老题,蒟蒻的尝试学习1.0)

概率DP&#xff1a; 利用动态规划去解决 概率 期望 的题目。 概率DP 求概率&#xff08;采用顺推&#xff09; 从 初始状态推向结果&#xff0c;同一般的DP类似&#xff0c;只是经历了概率论知识的包装。 老题&#xff1a; 添加链接描述 题意&#xff1a; 袋子里有w只白鼠&am…

linux编译器——gcc/g++

1.gcc linux上先要安装&#xff0c; sudo yum install gcc gcc --version 可以查看当前的版本 &#xff0c;我们默认安装的是4.8.5的版本&#xff0c;比较低&#xff0c; gcc test.c -stdc99 可以使他支持更高版本的c标准 -o 可以殖指明生成文件的名字&#xff0c;可以自己…

跨越技术壁垒:EasyCVR为何选择支持FMP4格式,重塑视频汇聚平台标准

随着物联网、大数据、云计算等技术的飞速发展&#xff0c;视频监控系统已经从传统的安防监控扩展到智慧城市、智能交通、工业制造等多个领域。视频流格式作为视频数据传输与存储的基础&#xff0c;其兼容性与效率直接影响到整个视频监控系统的性能。 在众多视频流格式中&#…

TCP Analysis Flags 之 TCP Port numbers reused

前言 默认情况下&#xff0c;Wireshark 的 TCP 解析器会跟踪每个 TCP 会话的状态&#xff0c;并在检测到问题或潜在问题时提供额外的信息。在第一次打开捕获文件时&#xff0c;会对每个 TCP 数据包进行一次分析&#xff0c;数据包按照它们在数据包列表中出现的顺序进行处理。可…

十大口碑最好开放式蓝牙耳机是哪些?五款热销好用产品测评!

​开放式耳机现在超火&#xff0c;成了时尚、好看又舒服的代名词&#xff0c;迅速俘获了一大波粉丝&#xff0c;成了耳机界的新宠儿。跟那些传统的入耳式耳机比起来&#xff0c;开放式耳机戴着更稳&#xff0c;对耳朵也更友好。不过&#xff0c;也有人觉得这玩意儿不值&#xf…

系统找不到指定的文件怎么解决?

把U盘插在电脑上&#xff0c;当我打开U盘中的文件时&#xff0c;弹窗提示系统找不到指定的文件&#xff0c;这是什么情况&#xff1f;有谁遇到过吗&#xff1f;大家有没有解决办法&#xff1f; 这个问题可能大家并不陌生&#xff0c;可能也曾遇到过&#xff0c;造成问题出现的原…

现代计算机中数字的表示与浮点数、定点数

现代计算机中数字的表示与浮点数、定点数 导读&#xff1a;浮点数运算是一个非常有技术含量的话题&#xff0c;不太容易掌握。许多程序员都不清楚使用操作符比较float/double类型的话到底出现什么问题。这篇文章讲述了浮点数的来龙去脉&#xff0c;所有的软件开发人员都应该读…

sqli-lab靶场学习(一)——Less1-4

前言 最近一段时间想切入安全领域&#xff0c;因为本身有做数据库运维工作&#xff0c;就打算从sql注入方向切入。而sql注入除了学习日常书本上的概念外&#xff0c;需要有个实践的环境&#xff0c;刚好看到sqli-lab这个靶场&#xff0c;就打算先用这个来学习。 安装部署 网上…

小阿轩yx-Kubernertes日志收集

小阿轩yx-Kubernertes日志收集 前言 在 Kubernetes 集群中如何通过不同的技术栈收集容器的日志&#xff0c;包括程序直接输出到控制台日志、自定义文件日志等 有哪些日志需要收集 日志收集与分析很重要&#xff0c;为了更加方便的处理异常 简单总结一些比较重要的需要收集…

数据分析面试题:如何分析每日平均每件商品的锁定时长问题?

目录 0 题目描述 2 数据准备 3 数据分析 3.1 需求1:计算 2014/03/22-2014/04/30 每天的购买客户数、订单量、销售件数、销售额 3.2 计算 2014 年 4 月各品类的销售额、晚上 20-24 点销售额 3.3 提取 2014 年 3-5 月销售额排名前三的客户信息(排名/客户号/客户姓名/总销…

华为OD机试真题 - 二叉树的广度优先遍历 - 二叉树(Python/JS/C/C++ 2024 D卷 200分)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试真题&#xff08;Python/JS/C/C&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加入华为OD刷题交流群&#xff0c;…

Github 2024-09-07Rust开源项目日报Top10

根据Github Trendings的统计,今日(2024-09-07统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Rust项目10CUE项目1Python项目1Go项目1Polars: Rust中的DataFrame接口和OLAP查询引擎 创建周期:1354 天开发语言:Rust, Python协议类型:MIT …

Ubuntu之源码编译安装nginx

参考&#xff1a;Ubuntu之源码编译安装nginx_ubuntu编译安装nginx-CSDN博客 1.下载源码后进入源码目录&#xff0c;如下&#xff1a; cd /home/jq/wf/nginx-1.26.1 2.下载相应依赖库&#xff1a; apt-get install libpcre3-dev apt-get install openssl libssl-dev apt-get…

神经网络骨架nn.Module

文章目录 一、认识nn.Module二、nn.Module的基础加1操作 一、认识nn.Module nn.Module 是 PyTorch 中的一个核心类&#xff0c;它是所有神经网络模块的基类。在 PyTorch 中构建模型时&#xff0c;通常会继承这个类来创建自定义的网络结构。nn.Module 提供了一系列用于构建神经…

如何在Word中插入复选框

如何在Word中插入复选框&#xff1a;详细教程与技巧 在Word中插入复选框是一项非常实用的技巧&#xff0c;尤其是在制作问卷调查、待办事项清单、交互式表单或文档中需要用户进行选择时&#xff0c;复选框不仅能提高文档的功能性&#xff0c;还能显得更加专业。本文将详细讲解…

嵌入式软件--51单片机 DAY 4

一、蜂鸣器 当电流通过线圈时会产生电磁场&#xff0c;电磁场与永磁体相互作用&#xff0c;从而使金属膜产生震动而发声。为使金属膜持续震动&#xff0c;蜂鸣器需要使用震荡电路进行驱动。有些蜂鸣器元件内部自带震荡驱动电路&#xff0c;这种蜂鸣器叫做有源蜂鸣器&#xff0…