MYSQL篇--锁机制高频面试题

Mysql锁机制

1对mysql的锁有了解吗?

首先我们要知道,mysql的锁 其实是为了解决在并发事务时所导致的数据不一致问题的一种处理机制,也就是说 在事务的隔离级别实现中,就需要利用锁来解决幻读问题
然后我们可以聊到锁的分类
按锁的粒度可以分为

  1. 行锁:锁某行数据,锁粒度最⼩,并发度⾼
  2. 表锁:锁整张表,锁粒度最大,并发度低
  3. 间隙锁:锁的是⼀个区间

按锁的性质可以分为

  1. 共享锁:也就是读锁,⼀个事务给某行数据加了读锁,其他事务也可以读,但是不能写
  2. 排它锁:也就是写锁,⼀个事务给某行数据加了写锁,其他事务不能读,也不能写

还可以分为

  1. 乐观锁:并不会真正的去锁某行记录,而是通过⼀个版本号来实现的
  2. 悲观锁:上面所的行锁、 表锁等都是悲观锁

2什么是死锁?怎么解决?

常规回答:死锁它其实是两个或者多个事务在同一个资源上相互占用,同时并请求锁定对方的资源,从而导致恶性循环的现象

解决办法:

  1. 程序再并发存取多个表的时候,尽量让他们以相同的顺序来访问表
  2. 在同一个事务中,尽可能做到一次锁定所需要的所有资源,来避免死锁问题
  3. 对于比较容易产生死锁的部分,可以尝试升级锁的颗粒度,比如使用表级锁,或者分布式事务锁,或者使用乐观锁

3 数据库的乐观锁和悲观锁是什么,如何实现?

首先我们要明白数据库的四大特性,ACID-其中有隔离性,也就是多个事务在并发执行时 他们内部是不能互相干扰的,而悲观锁和乐观锁正是实现隔离性的一种方式

悲观锁:简单的理解就是 它假定会发生并发冲突,在查询完数据的时候就会把事务锁起来,直到提交事务
实现方式:使用数据库中的锁机制–select * for update

乐观锁:它就是说假定不会发生并发冲突,也就是只在提交操作的时候才会检查数据的完整性,在进行修改的时候把事务锁起来
实现方式:版本号机制和cas算法

最后可以总结下:两种锁其实并没有好坏之分,但是却有分别合适的场景,对于乐观锁来说 它其实更适合读多写少的场景,也就是说冲突很少发生的场景,这样的话 就会省去锁的开销,加大系统的吞吐量,相反针对写比较多的场景,乐观锁可能会频繁的冲突,进而导致上层应用不断地retry,这样反倒降低了性能,因此悲观锁更适合写多场景

4 MySQL中InnoDB引擎的行锁是怎么实现的?

首先我们要明白行锁它其实就是记录锁,说白了也就是对表中的记录加锁,简称记录锁,但是注意记录锁-行锁它是锁住索引记录,而不是数据记录,即其实是基于索引来完成的加锁。
你比如说select * from db where a = 1 for update, 这里的for update就是根据条件来完成行锁锁定,并且这里的条件也是有索引建的列,如果a字段不是索引键 将会对整张表加锁
同时记录锁也是排它(X)锁, 所以会阻塞其他事务对其插入、更新、删除。

5 什么是间隙锁-Gap lock?

间隙锁 是 Innodb 在 RR(可重复读) 隔离级别 下为了解决 幻读问题 时引入的锁机制
而间隙锁它其实也算是行锁的一种,另外尤其注意的是间隙锁 它锁住的是一个区间,而不仅仅是这个区间中的每一条数据。
举例来说,假如student表中只有101条记录,其empid的值分别是1,2,…,100,101,

SELECT * FROM student WHERE sid > 100 FOR UPDATE

当我们用条件检索数据,并请求共享或排他锁时,InnoDB不仅会对符合条件的empid值为101的记录加
锁,也会对sid大于101(这些记录并不存在)的“间隙”加锁。
这个时候如果你插入empid等于102的数据的,如果那边事物还没有提交,那你就会处于等待状态,无法插入数据。

6 什么是临键锁(Next-Key Locks)?

Next-key锁是记录锁和间隙锁的组合,它指的是加在某条记录以及这条记录前面间隙上的锁。
也可以理解为一种特殊的间隙锁
通过临建锁可以解决 幻读 的问题。
每个数据行上的非唯一索引列上都会存在一把临键锁,当某个事务持有该数据行的临键锁时,会锁住一段左开右闭区间的数据。
注意:临键锁只与 非唯一索引列 有关,在 唯一索引列(包括主键列)上不存在临键锁。
举个例子
假设有如下表:id主键, age 普通索引
在这里插入图片描述
该表中 age 列潜在的临键锁有:
(-∞, 10],
(10, 24],
(24, 32],
(32, +∞],

在事务 A 中执行如下命令:
– 根据非唯一索引列 UPDATE 某条记录
UPDATE table SET name = Vladimir WHERE age = 24;
– 或根据非唯一索引列 锁住某条记录
SELECT * FROM table WHERE age = 24 FOR UPDATE;

不管执行了上述 SQL 中的哪一句,之后如果在事务 B 中执行以下命令,则该命令会被阻塞:
INSERT INTO table VALUES(100, 26, ‘tianqi’);
很明显,事务 A 在对 age 为 24 的列进行 UPDATE 操作的同时,也获取了 (24, 32] 这个区间内的临键锁。

这里对 记录锁、间隙锁、临键锁 做一个总结:
InnoDB 中的行锁的实现依赖于索引,一旦某个加锁操作没有使用到索引,那么该锁就会退化为表锁 。
记录锁存在于包括主键索引在内的唯一索引中,锁定单条索引记录。
间隙锁存在于非唯一索引中,锁定开区间范围内的一段间隔
临键锁存在于非唯一索引中,该类型的每条记录的索引上都存在这种锁,它是一种特殊的间隙锁,锁定一段左开右闭的索引区间

7 什么是意向锁?

意向锁又分为 意向共享锁(IS) 和 意向排他锁(IX)

意向共享(IS)锁:简单理解就是事务有意向对表中的某些行加共享锁(S锁)
即-- 事务要获取某些行的 S 锁,必须先获得表的 IS 锁。
SELECT column FROM table … LOCK IN SHARE MODE;

意向排他(IX)锁:即事务有意向对表中的某些行加排他锁(X锁)
– 事务要获取某些行的 X 锁,必须先获得表的 IX 锁。
SELECT column FROM table … FOR UPDATE;

首先我们要明白四点
意向共享锁(IS)和 意向排他锁(IX)都是表锁。
意向锁是一种 不与行级锁冲突的表级锁,这一点非常重要。
意向锁是 InnoDB 自动加的, 不需用户干预
意向锁是在 InnoDB 下存在的内部锁,对于MyISAM 而言 没有意向锁之说。(即只针对InnoDB

那么问题来了,既然前面已经有了共享锁(S锁)、排它锁(X锁)。
又为什么需要引入意向锁呢?它能解决什么问题呢?
我们可以理解 意向锁 存在的目的就是 为了让 InnoDB 中的行锁和表锁更高效的共存 。
也就是说 如果某个事物要加表锁,如果没有意向锁 那么它就需要去检测表中的每一行是否存在排他锁。很明显这是一个效率很差的做法,
但是有了意向锁之后,情况就不一样了:这个事务只要看表上有没有
意向共享锁,有则说明表中有些行被共享行锁锁住了,因此,事务B申请表的写锁会被阻塞。这样就高效多了

这里我们再来看下 共享(S)锁、排他(X)锁、意向共享锁(IS)、意向排他锁(IX)的兼容性
在这里插入图片描述
可以看出 意向锁之间是互相兼容的.那你存在的意义是啥?
意向锁不会为难意向锁。也不会为难行级排他(X)/共享(X)锁,它的存在是为难 表级 排他(X)/共享(X)锁。
在这里插入图片描述
注意 这里的排他(X)/共享(S)锁指的都是表锁!意向锁不会与行级的共享/排他锁互斥! 行级别的X和S按照上面的兼容性规则即可。
意向锁与意向锁之间永远是兼容的,因为当你不论加行级的X锁或S锁,都会自动获取表级的IX锁或者IS锁。
也就是你有10个事务,对不同的10行加了行级X锁,那么这个时候就存在10个IX锁。
这10IX存在的目的是啥呢,就是假如这个时候有个事务,想对整个表加排它X锁,那它不需要遍历每一行是否存在S或X锁,而是看有没有存在意向锁,只要存在一个意向锁,那这个事务就加不了表级排它X
锁,要等上面10个IX全部释放才行。

8 什么是插入意向锁?

插入意向锁 的特性可以分成两部分:
插入意向锁是一种特殊的间隙锁 —— 间隙锁可以锁定开区间内的部分记录。
插入意向锁之间互不排斥,所以即使多个事务在同一区间插入多条记录,只要记录本身(主键、唯一索引)不冲突,那么事务之间就不会出现冲突等待。
需要强调的是,虽然插入意向锁中含有意向锁三个字,但是它并不属于意向锁而属于间隙锁,因为意向锁 是表锁而 插入意向锁是行锁
总结下:

  1. InnoDB在RR的事务隔离级别下,使用插入意向锁来控制和解决并发插入。
  2. 插入意向锁是一种特殊的间隙锁。
  3. 插入意向锁在锁定区间相同但记录行本身不冲突的情况下互不排斥。

9 MySQL间隙锁,如何解决幻读?

首先我们要知道
在RR的隔离级别下,Innodb使用MVCC和 next-key locks(行锁和间隙锁的组合)解决幻读,
MVCC解决的是普通读(快照读)的幻读
next-key locks解决的是当前读情况下的幻读。
MySQL间隙锁 + 记录锁 ,组合起来,解决的是当前读情况下的幻读

至于MVCC如何解决幻读的 请看 我之前的事务篇
而在这里 我们简单说下什么是当前读和快照读

快照读(历史数据)-mvcc
快照读对应的sql 语法:简单的select操作(不包括 select … lock in share mode, select … for update)

当前读(最新数据)对应的sql 语法:
select * from table where ? lock in share mode;
select * from table where ? for update;
insert into table values (…);
update table set ? where ?;
delete from table where ?;
特殊的读操作,插入/更新/删除操作,属于当前读,需要加锁。
那么解决原理其实就是 保证数据是一致的(也就是一个事务,其内部读取对应某一个数据的时候,数据都是一样的),同时读取的数据是最新的数据。
innodb提供了next-key lock,也就是结合gap锁与行锁,达到最终目的

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

9.云原生存储之ceph在k8s中应用及问题处理

文章目录 ceph应用场景ceph应用在k8s集群外使用块设备ceph客户端配置创建块挂载使用删除pool 在k8s集群内使用块设备创建块池和StorageClass使用存储 块存储映射问题处理问题现象事件分析csi-rbdplugin pod日志分析问题小结CentOS 7 编译安装 nbd 模块nbd内核模块介绍安装 nbd …

模型评估:ROC曲线

二值分类器(Binary Classifier)是机器学习领域中最常见也是应用最广泛的分类器。评价二值分类器的指标很多,比如precision、recall、F1 score、P-R曲线等。相比而言,ROC曲线有很多优点,经常作为评估而知分类器最重要的…

web前端算法简介之栈

栈 栈的基本操作包括: 初始化栈(InitStack):判断栈是否为空(IsStackEmpty):入栈(Push):出栈(Pop):获取栈顶元素&#xff0…

【动态规划】 【字典树】C++算法:472 连接词

作者推荐 【动态规划】458:可怜的小猪 涉及知识点 动态规划 字典树 LeetCode472 连接词 给你一个 不含重复 单词的字符串数组 words ,请你找出并返回 words 中的所有 连接词 。 连接词 定义为:一个完全由给定数组中的至少两个较短单词(不…

Spring Boot - Application Events 的发布顺序_ApplicationStartingEvent

文章目录 概述Code源码分析 概述 Spring Boot 的广播机制是基于观察者模式实现的,它允许在 Spring 应用程序中发布和监听事件。这种机制的主要目的是为了实现解耦,使得应用程序中的不同组件可以独立地改变和复用逻辑,而无需直接进行通信。 …

C#上位机与欧姆龙PLC的通信11----【爆肝】上位机应用开发(Winform版)

1、先上图 前面10讲,让你爽煹了肝,已经进入最后收尾阶段,这节来个常规应用,让前面的技能直接飞上天,我们要做的界面软件是这样的,虽然没有潘金莲漂亮,但也是爆抱: 2、如何爆&#x…

win系统搭建Minecraft世界服务器,MC开服教程,小白开服教程

Windows系统搭建我的世界世界服务器,Minecraft开服教程,小白开服教程,MC 1.19.4版本服务器搭建教程。 此教程使用 Mohist 1.19.4 服务端,此服务端支持Forge模组和Bukkit/Spigot/Paper插件,如果需要开其他服务端也可参…

应用在LCD显示器电源插头里的氮化镓(GaN)MTC-65W1C

LCD(Liquid Crystal Display)显示器是利用液晶显示技术来进行图像表现的显示装置,从液晶显示器的结构来看,无论是笔记本电脑还是桌面系统,采用的LCD显示屏都是由不同部分组成的分层结构。LCD显示器按照控制方式不同可分…

网络编程的理论基础

文章目录 1 重点知识2 应用层3 再谈 "协议"4 HTTP协议4.1 认识URL4.2 urlencode和urldecode4.3 HTTP协议格式4.4 HTTP的方法4.5 HTTP的状态码4.6 HTTP常见Header4.7 最简单的HTTP服务器 3 传输层4 再谈端口号4.1 端口号范围划分4.2 认识知名端口号(Well-Know Port Nu…

2024美赛数学建模思路 - 复盘:光照强度计算的优化模型

文章目录 0 赛题思路1 问题要求2 假设约定3 符号约定4 建立模型5 模型求解6 实现代码 建模资料 0 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 1 问题要求 现在已知一个教室长为15米,宽为12米&…

Linux动态分配IP与正向解析DNS

目录 一、DHCP分配 1. 动态分配 1.1 服务端服务安装 1.2 修改服务端dhcp配置 1.3 修改客户端dhcp,重启查询网卡信息 2. 根据mac固定分配 2.1 修改服务器端dhcp服务配置 2.2 客户端自动获取,查看网卡信息 二、时间同步 1. 手动同步 2. 自动同…

小汪,TCP连接和断连夺命6连问你可能扛得住?

目录 TCP三次握手连接和四次挥手断连的几处疑问 一、建立连接,为什么是三次握手,而不是二次握手? 二、为什么每次建立 TCP 连接时,初始化的序列号都要求不一样呢? 三、断开连接,为什么是四次握手&#x…

【C语言】ipoib驱动 - ipoib_cm_post_receive_srq_rss函数

一、ipoib_cm_post_receive_srq_rss函数定义 static int ipoib_cm_post_receive_srq_rss(struct net_device *dev,int index, int id) {struct ipoib_dev_priv *priv ipoib_priv(dev);struct ipoib_recv_ring *recv_ring priv->recv_ring index;struct ib_sge *sge;stru…

聚乙烯PE的特性有哪些?UV胶水能够粘接聚乙烯PE吗?

聚乙烯(Polyethylene,PE)是一种聚合物,是由乙烯(ethylene)单体通过聚合反应形成的合成塑料。以下是聚乙烯的一些主要化学特性: 1.化学式: 聚乙烯的基本化学式是 (C2H4)n,…

Camunda Sub Process

一:内嵌子流程 repositoryService.createDeployment().name("内嵌子流程").addClasspathResource("bpmn/embed_sub_process.bpmn").deploy(); identityService.setAuthenticatedUserId("huihui"); ProcessInstance processInstance …

【已解决】c++如何打印变量的类型

本博文源于笔者正在编写的c代码,在c/c中我们经常用auto去接一个变量,这样我们既可以不用知道变量或函数结果的类型,就可以轻松愉快编码,如果想要知道变量的类型呢?那就需要这样一个函数。 问题再现 想要用函数去打印…

使用numpy处理图片——90度旋转

在《使用numpy处理图片——镜像翻转和旋转》一文中,我们介绍了如何将图片旋转的方法。本文将使用更简单的方法旋转图片90度。 左旋转90度 import numpy as np import PIL.Image as Imagedata np.array(Image.open(the_starry_night.jpg))# left 90 rot90LeftWith…

SQL-条件查询与聚合函数的使用

目录 DQL-条件查询 1.语法 2.条件 常用的比较运算符如下: 常用的逻辑运算符如下: 案例: 聚合函数 1.常见的聚合函数 2.聚合函数的语法 案例: 🎉欢迎您来到我的MySQL基础复习专栏 ☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克🍹 ✨博客…

pycharm导入etree报Cannot find reference ‘etree‘ in ‘__init__.py‘ more... (Ctrl+F1)

问题 发现 from lxml import etree的时候,etree报错了。提示Cannot find reference etree in __init__.py more... (CtrlF1)。 解决办法 后面发现是pycharm自己的BUG,所以写了新的写法

turnjs实现翻书效果

需求:要做一个效果,类似于阅读器上的翻书效果。 咱们要实现这个需求就需要使用turnjs这个插件,他的官网是turnjs官网。 进入官网后可以点击 这个按钮去下载官网的demo。 这个插件依赖于jQuery,所以你的先安装jQuery. npm insta…