【面试八股总结】MySQL 锁:全局锁、表级锁、行级锁

1. 全局锁

        顾名思义,全局锁就是对整个数据库实例加锁。

MySQL 提供了⼀个加全局读锁的方法:

flush tables with read lock

释放全局锁,执行命令:

unlock tables

需要让整个库处于只读状态的时候,可以使用全局锁命令,之后其他线程的以下语句会被阻塞:

  • 数据更新语句(数据的增删改)
  • 数据定义语句(包括建表、修改表结构等)
  • 更新类事务的提交语句

典型使用场景:全库逻辑备份,即把整个库的表都select出来存成文本

2. 表级锁

MySQL 里面表级别的锁有这几种:表锁;元数据锁(MDL); 意向锁;AUTO-INC 锁;

(1)表锁

特点: 每次操作锁住整张表,开销小,加锁快,并发度最低

表锁的语法是:

 lock tables … read/write

        可以使用unlock tables 主动释放锁,也可以在客户端断开的时候自动释放。 需要注意: lock tables 语法除了会限制别的线程的读写外,也限定了本线程接下来的操作对象。

(2)元数据锁(meta data lock,MDL)

MDL 不需要显式使用,在访问⼀个表的时候会被自动加上。

  • 对一张表进行 CRUD 操作时,加的是 MDL 读锁
  • 对一张表做结构变更操作的时候,加的是 MDL 写锁

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

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

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

        MDL 是在事务提交后才会释放,这意味着事务执行期间,MDL 是一直持有的,容易产生死锁问题。申请 MDL 锁的操作会形成一个队列,队列中写锁获取优先级高于读锁,一旦出现 MDL 写锁等待,会阻塞后续该表的所有 CRUD 操作。

(3)意向锁

        意向锁用于指示⼀个事务在未来可能会请求对某些资源(如数据行)的锁定。目的是为了快速判断表里是否有记录被加锁。

  • 意向共享锁表示事务打算在资源上获得共享锁。其他事务可以继续获得共享锁,但不能获得排他锁。
  • 意向排他(独占)锁: 表示事务打算在资源上获得排他锁。

        意向共享锁和意向独占锁是表级锁,不会和行级的共享锁和独占锁发⽣冲突,意向锁之间也不会发生冲突,只会和共享表锁和独占表锁发生冲突。

(4)AUTO-INC 锁

        表里的主键通常都会设置成自增的,这是通过对主键字段声明 AUTO_INCREMENT 属性实现的。之后可以在插入数据时,可以不指定主键的值,数据库会自动给主键赋值递增的值,这主要是通过 AUTO-INC 锁实现的。

        在插入数据时,会加一个表级别的 AUTO-INC 锁,然后为 AUTO_INCREMENT 修饰的字段赋值递增的值,等插入语句执行完成后,才会把 AUTO-INC 锁释放掉。一个事务在持有 AUTO-INC 锁的过程中,其他事务的如果要向该表插入语句都会被阻塞,从而保证插入数据时,被 AUTO_INCREMENT 修饰的字段的值是连续递增的。

        AUTO-INC 锁是特殊的表锁机制,锁不是再一个事务提交后才释放,而是在执行完插入语句后就会立即释放

缺陷: 

        AUTO-INC 锁再对大量数据进行插入的时候,会影响插入性能,因为另一个事务中的插入会被阻塞。

改进:

        InnoDB 存储引擎提供了一种轻量级的锁来实现自增。在插⼊数据的时候,会为被 AUTO_INCREMENT 修饰的字段加上轻量级锁,然后给该字段赋值⼀个自增的值,就把这个轻量级锁释放了,⽽不需要等待整个插入语句执行结束后才释放锁。

3. 行级锁

InnoDB 引擎是支持行级锁的,而 MyISAM 引擎并不支持行级锁。

        行锁就是针对数据表中行记录的锁(也称为记录锁)。行级锁的类型主要有三类:

  • Record Lock,记录锁,也就是仅仅把一条记录锁上;
  • Gap Lock,间隙锁,锁定一个范围,但是不包含记录本身;
  • Next-Key Lock:Record Lock + Gap Lock 的组合,锁定一个范围,并且锁定记录本身。

共享锁(S锁)满足读读共享,读写互斥。独占锁(X锁)满足写写互斥、读写互斥。

(1)Record Lock 记录锁

        Record Lock 称为记录锁,锁住的是一条记录。而且记录锁是有 S 锁和 X 锁之分的:

  • 当一个事务对一条记录加了 S 型记录锁后,其他事务也可以继续对该记录加 S 型记录锁(S 型与 S 锁兼容),但是不可以对该记录加 X 型记录锁(S 型与 X 锁不兼容);
  • 当一个事务对一条记录加了 X 型记录锁后,其他事务既不可以对该记录加 S 型记录锁(S 型与 X 锁不兼容),也不可以对该记录加 X 型记录锁(X 型与 X 锁不兼容)。

当事务执行 commit 后,事务过程中生成的锁都会被释放。

(2)Gap Lock 间隙锁

        Gap Lock 称为间隙锁,只存在于可重复读隔离级别,目的是为了解决可重复读隔离级别下幻读的现象。

        间隙锁虽然存在 X 型间隙锁和 S 型间隙锁,但是并没有什么区别,间隙锁之间是兼容的,即两个事务可以同时持有包含共同间隙范围的间隙锁,并不存在互斥关系,因为间隙锁的目的是防止插入幻影记录而提出的

假设,表中有一个范围 id 为(3,5)间隙锁,那么其他事务就无法插入 id = 4 这条记录了,这样就有效的防止幻读现象的发生。

(3)Next-Key Lock 临键锁

        Next-Key Lock 称为临键锁,是 Record Lock + Gap Lock 的组合,锁定一个范围,并且锁定记录本身。

        Next-key lock 是包含间隙锁+记录锁的,如果一个事务获取了 X 型的 next-key lock,那么另外一个事务在获取相同范围的 X 型的 next-key lock 时,是会被阻塞的

        比如,一个事务持有了范围为 (1, 10] 的 X 型的 next-key lock,那么另外一个事务在获取相同范围的 X 型的 next-key lock 时,就会被阻塞。

        虽然相同范围的间隙锁是多个事务相互兼容的,但对于记录锁,我们是要考虑 X 型与 S 型关系,X 型的记录锁与 X 型的记录锁是冲突的。

注意事项:

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

加锁规则:

  • 加锁的基本单位是 next-key lock。希望你还记得,next-key lock 是前开后闭区间
  • 查找过程中访问到的对象才会加锁。
  • 索引上的等值查询,给唯⼀索引加锁的时候,next-key lock 退化为行锁。
  • 索引上的等值查询,向右遍历时且最后⼀个值不满足等值条件的时候,next-key lock 退化为间隙锁。

        以上规则是在可重复读隔离级别 (repeatable-read) 下验证的。同时,可重复读隔离级别遵守两阶段锁协议,所有加锁的资源,都是在事务提交或者回滚的时候才释放的。如果切换到读提交隔离级别 (read-committed) 的话,就好理解了,过程中去掉间隙锁的部分,也就是只剩下行锁的部分。

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

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

相关文章

鸿蒙(API 12 Beta6版)图形【NativeImage开发指导 (C/C++)】方舟2D图形服务

场景介绍 NativeImage是提供Surface关联OpenGL外部纹理的模块,表示图形队列的消费者端。开发者可以通过NativeImage接口接收和使用Buffer,并将Buffer关联输出到OpenGL外部纹理。 针对NativeImage,常见的开发场景如下: 通过Nati…

linux系统中USB模块鼠标驱动实现

各位开发者大家好,今天主要给大家分享一下,Linux系统中使用libusb的方法以及鼠标驱动实现。 第一:libusb概述 参考网址:* libusb GIT仓库:https://github.com/libusb/libusb.git * libusb 官网:https://libusb.info/ * libusb API接口:https://libusb.sourceforge.io/…

mysql 使用 general 开启SQL跟踪功能

查看当前状态 mysql> SHOW VARIABLES LIKE %general%; 启用 临时启用 SET GLOBAL general_logon; SET GLOBAL general_log_file/tmp/general.log; 永久启用 通过修改配置文件来启用,需要重启mysql服务 [mysqld] general_logON general_log_file/tmp/general.log 再次查看状态…

【Redis】Redis 持久化机制详解:RDB、AOF 和混合持久化的工作原理及优劣分析

目录 持久化RDB触发机制流程说明RDB ⽂件的处理RDB 的优缺点 AOF使⽤ AOF命令写⼊⽂件同步重写机制启动时数据恢复 混合持久化小结 持久化 回顾 MySQL 的事务的特性: 原子性一致性持久性(持久化)隔离性 持久化:把数据存储在硬盘上…

CAN总线之一篇文章讲清楚Motorala和inter格式

前言: 之前的工作中,其实对Motorala和inter格式并不是了解的十分透彻。最近由于工作需要,研究了一下这两种格式,发现里面的门道其实挺复杂的。 特此作了一些总结:和大家一起分享。 我查了不少文档,描述其…

MongoDB 向 PostgreSQL 宣战

上周 MongoDB 发布了一份亮眼的季度财报,盘后股价涨幅超过 18%。 值得一提的是,MongoDB 的 CEO Dev Ittycheria 特别提到 MongoDB 正在借助自己的数据库服务 Atlas 从 PostgreSQL 那里挖角。原话是举了一个博彩网站的例子: “Initially, th…

【C++ 第十八章】C++11 新增语法(4)

前情回顾: 【C11 新增语法(1):1~6 点】 C11出现与历史、花括号统一初始化、initializer_list初始化列表、 auto、decltype、nullptr、STL的一些新变化 【C11 新增语法(2):7~8 点】 右值引用和…

uniapp插槽用法

目录 什么是插槽? 基本概念 默认插槽 命名插槽 作用域插槽 场景一:子插槽向父组件传递一个字符串 场景二:子插槽向父组件传递对象 什么是插槽? 在 UniApp 中,插槽(Slot)是一种允许父组件向子组件特定位置插入HTML内容的方式。这种方式使得组…

快速便捷地解决 reCAPTCHA 的方法

reCAPTCHA 是一种流行的挑战-响应系统,旨在通过提供人类易于解决但机器难以解决的难题来保护网站免受机器人和自动化滥用。无论您是处理网络抓取项目中的 reCAPTCHA 的开发人员,还是在各种网站上浏览的用户,了解如何有效地处理 reCAPTCHA 都可…

每日OJ_牛客_五子棋(判断是否有赢)

目录 牛客_五子棋(判断是否有赢) 解析代码 牛客_五子棋(判断是否有赢) 五子棋__牛客网 题目: 用例输入: .................... .................... .................... .................... ....…

基础闯关4

环境配置 我们来配置LlamaIndex实验环境,首先创建Python环境并安装必要的库: conda create -n llamaindex python3.10 conda activate llamaindex conda install pytorch2.0.1 torchvision0.15.2 torchaudio2.0.2 pytorch-cuda11.7 -c pytorch -c nvid…

VBA数据库解决方案第十四讲:如何在数据库中动态删除和建立数据表

《VBA数据库解决方案》教程(版权10090845)是我推出的第二套教程,目前已经是第二版修订了。这套教程定位于中级,是学完字典后的另一个专题讲解。数据库是数据处理的利器,教程中详细介绍了利用ADO连接ACCDB和EXCEL的方法…

Pixelmator Pro for Mac 专业图像处理软件【媲美PS的修图软件】

Mac分享吧 文章目录 效果一、下载软件二、开始安装1、双击运行软件,将其从左侧拖入右侧文件夹中,等待安装完毕2、应用程序显示软件图标,表示安装成功 三、运行测试安装完成!!! 效果 一、下载软件 下载软件…

MySQL 使用C语言链接

mysql的基础,我们之前已经学过,后面我们只关心使用 要使用C语言连接mysql,需要使用mysql官网提供的库,大家可以去官网下载 我们使用C接口库来进行连接 要正确使用,我们需要做一些准备工作: 保证mysql服务有…

python常用库学习-Matplotlib使用

文章目录 安装 Matplotlib导入库基本示例1. 绘制简单的线图2. 散点图3. 柱状图4. 直方图5. 子图 更多高级功能1. 自定义样式2. 文本和注释3. 保存图形 示例:使用 Matplotlib 绘制多个图表示例 1: 绘制多个线图示例 2: 绘制散点图和直方图 参考文献 Matplotlib 是 Py…

MySQL数据库安装(详细)—>Mariadb的安装(day21)

该网盘链接有效期为7天,有需要评论区扣我: 通过网盘分享的文件:mariadb-10.3.7-winx64.msi 链接: https://pan.baidu.com/s/1-r_w3NuP8amhIEedmTkWsQ?pwd2ua7 提取码: 2ua7 1 双击打开安装软件 本次安装的是mariaDB,双击打开mar…

移动UI:成就勋章页面该如何设计,用例子说明。

移动应用的UI成就勋章页面通常是一个展示用户在应用中取得成就和获得勋章的页面。这种页面通常用于激励用户参与应用的活动,增加用户的参与度和忠诚度。 UI设计成就勋章页面时,一般会包括以下元素和功能: 1. 勋章列表: 展示用户…

集成电路学习:什么是ARM先进精简指令集计算机

ARM:先进精简指令集计算机 ARM先进精简指令集计算机(Advanced RISC Machine,简称ARM)是一种基于精简指令集计算机(RISC)原则的计算机处理器架构,由英国的ARM公司开发。这种架构以其低功耗和高性…

git创建本地分支并track跟踪远程分支

git创建本地分支并track跟踪远程分支 查看本地分支与远程分支的映射关系: git branch -vv 查看远程都有什么分支: git branch -r 在本地自动新建一个xxx分支,且自动track跟踪远程的同名xxx分支: git checkout --track origin/xx…

《黑神话:悟空》背后的渲染技术解析

《黑神话:悟空》作为备受瞩目的国产单机游戏,承载了深厚的文化底蕴,其背后的渲染技术无疑是推动其视觉表现达到新高度的关键。这款游戏不仅融合了传统与创新的角色设计,还通过一系列前沿的图形渲染技术,为玩家带来了前…