面试让HR都能听懂的MySQL锁机制,欢声笑语中搞懂MySQL锁

腾讯云数据库负责人林晓斌说过:“我们面试MySQL同事时只考察两点,索引和锁”。言简意赅,MySQL锁的重要性不言而喻。
本文通过同事“侨总”的一场面试,带你通俗易懂的掌握MySQL各种锁机制,希望可以帮到你!近期会继续整理深入性的锁机制文章,有兴趣的老铁,记得关注一下,到时叫你~

今天的主人公是我们公司同事侨总,传说中手上有10个比特币的男人。自从比特币大涨以来,养成了几个小爱好:周末听戏坐包厢,骑马酒吧滑雪场。

这不,前两天侨总又双叒叕出来体验面试了,晚上请我烧烤时跟我聊了聊这次有趣的面试经历,真是意犹未尽,趁他回味之余我又吃了十几串儿腰子和羊肉~ 嗯,真香!

对不住,跑题了。。人到中年嘛,保温杯里泡枸杞之余总会。。。

来不及解释了,快上车!

大家好,我是陈哈哈的同事“侨总”,领导一般不敢喊我名字,都叫我小侨~

下面是我的一次面试经历,面试官是技术经理和HR,大家吃好喝好~

在这里插入图片描述

侨总:马…小马哥好!

面试官:你好,小侨啊,看你简历写着精通MySQL锁,你认为精通应该是啥水平呢?

侨总:马哥我是个老实人,我认为精通就是,比面试官知道的多就完了。。

面试官:(怎么有种似曾相识的感觉?《听我讲完redo log、binlog原理,面试官老脸一红》)

面试官:行,那你先给我说说MySQL设计这个锁是干啥用的呀?

侨总:数据库锁设计的初衷是处理并发问题。作为多用户共享的资源,当出现并发访问的时候,为了保证数据的一致性,数据库需要合理地控制资源的访问规则。而锁就是用来实现这些访问规则的重要机制。

简单说,数据表就像公共厕所。emmm…换个下饭的说法,数据表就好比您开的一家酒店,而每行数据就像酒店的房间,如果大家随意进出,就会出现多人抢夺同一个房间的情况,而在房间上装上锁,申请到钥匙的人才可以入住并且将房间锁起来,其他人只有等他用完退房后才可以再次使用,这样保证了房间的一致性,方便酒店进行管理。

MySQL锁机制的初衷便是如此,当然,MySQL数据库由于其自身架构的特点,存在多种数据存储引擎,每种存储引擎所针对的应用场景特点都不太一样,为了满足各自特定应用场景的需求,每种存储引擎的锁定机制都是为各自所面对的特定场景而优化设计,所以各存储引擎的锁定机制也有较大区别。

面试官:嗯,那你说一下MySQL都分为哪些锁。

在这里插入图片描述

侨总

  1. 按锁粒度从大到小分类:表锁页锁行锁;以及特殊场景下使用的全局锁
  2. 如果按锁级别分类则有:共享(读)锁排他(写)锁意向共享(读)锁意向排他(写)锁
  3. 以及Innodb引擎为解决幻读等并发场景下事务存在的数据问题,引入的Record Lock(行记录锁)Gap Lock(间隙锁)Next-key Lock(Record Lock + Gap Lock结合)等;
  4. 还有就是我们面向编程的两种锁思想:悲观锁、乐观锁。

面试官:袁芳你怎么看?

HR小姐姐:。。。

面试官:小侨啊,那你来谈一谈你对表锁、行锁的理解吧。

表锁

侨总:表级别的锁定是MySQL各存储引擎中最大颗粒度的锁定机制。该锁定机制最大的特点是实现逻辑非常简单,带来的系统负面影响最小。所以获取锁和释放锁的速度很快。由于表级锁一次会将整个表锁定,所以可以很好的避免困扰我们的死锁问题。

当然,锁定颗粒度大所带来最大的负面影响就是出现锁定资源争用的概率也会最高,大大降低并发度。

使用表级锁定的主要是MyISAM,MEMORY,CSV等一些非事务性存储引擎。

行锁

侨总:与表锁正相反,行锁最大的特点就是锁定对象的颗粒度很小,也是目前各大数据库管理软件所实现的锁定颗粒度最小的。由于锁定颗粒度很小,所以发生锁定资源争用的概率也最小,能够给予应用程序尽可能大的并发处理能力从而提高系统的整体性能。

虽然能够在并发处理能力上面有较大的优势,但是行级锁定也因此带来了不少弊端。由于锁定资源的颗粒度很小,所以每次获取锁和释放锁需要做的事情也更多,带来的消耗自然也就更大了。此外,行级锁定也最容易发生死锁

使用行级锁定的主要是InnoDB存储引擎。

  • 适用场景:从锁的角度来说,表级锁更适合于以查询为主,只有少量按索引条件更新数据的应用,如Web应用;而行级锁则更适合于有大量按索引条件并发更新数据的情况,同时又有并发查询的应用场景。

页锁

除了表锁、行锁外,MySQL还有一种相对偏中性的页级锁,页锁是MySQL中比较独特的一种锁定级别,在其他数据库管理软件中也并不是太常见。页级锁定的特点是锁定颗粒度介于行级锁定与表级锁之间,所以获取锁定所需要的资源开销,以及所能提供的并发处理能力也同样是介于上面二者之间。另外,页级锁定和行级锁定一样,会发生死锁。

使用页级锁定的主要是BerkeleyDB存储引擎。

面试官:那全局锁是什么时候用的呢?

全局锁

侨总:首先全局锁,是对整个数据库实例加锁。使用场景一般在全库逻辑备份时。

MySQL提供加全局读锁的命令:Flush tables with read lock (FTWRL)

这个命令可以使整个库处于只读状态。使用该命令之后,数据更新语句、数据定义语句和更新类事务的提交语句等修改数据库的操作都会被阻塞。

风险:

  1. 如果在主库备份,在备份期间不能更新,业务停摆
  2. 如果在从库备份,备份期间不能执行主库同步的binlog,导致主从延迟同步

还有一种锁全局的方式:set global readonly=true ,相当于将整个库设置成只读状态,但这种修改global配置量级较重,和全局锁不同的是:如果执行Flush tables with read lock 命令后,如果客户端发生异常断开,那么MySQL会自动释放这个全局锁,整个库回到可以正常更新的状态。但将库设置为readonly后,客户端发生异常断开,数据库依旧会保持readonly状态,会导致整个库长时间处于不可写状态,试想一下微信只能看,不能打字~~

HR小姐姐:那微信不就完蛋了?

侨总:是啊,抓紧找老实人背锅!

面试官:不错,你把这几种锁的侧重点都表述清楚了。那你再说一下你对不同级别的那几种锁的使用场景和理解吧?

侨总:MySQL基于锁级别又分为:共享(读)锁排他(写)锁意向共享(读)锁意向排他(写)锁

共享(读)锁、排他(写)锁、意向共享(读)锁、意向排他(写)锁

侨总:对于共享(读)锁排他(写)锁,比如咱们住酒店,入住前顾客都是有权看房的,只看不住想白嫖都是可以的,前台小姐姐会把门给你打开。当然,也允许不同的顾客一起看(共享 读),比如和这位杀马特小伙子。

在这里插入图片描述

看房时房间相当于公共场所,小姐姐嘱咐不能乱涂乱画,也不能偷喝免费的矿泉水。。如果你觉得不错,偷偷跑到前台要定这间房,交钱后会给你这个房间的钥匙并将房间状态改为已入住,不再允许其他人看房(排他 写)。

对了,当办理入住时前台小姐姐也会通知看房的杀马特小伙子说这间房已经有人定了!!等看房的杀马特小伙儿骂骂咧咧出门后,看到满头大汗的你,鄙夷着咽了一口口水,咳tui!然后你锁上门哼着歌儿,开始干那些见不得人的事儿~~直到你退房前,其他人无法在看你的房

可见,读锁是可以并发获取的(共享的),而写锁只能给一个事务处理(排他的)。当你想获取写锁时,需要等待之前的读锁都释放后方可加写锁;而当你想获取读锁时,只要数据没有被写锁锁住,你都可以获取到读锁,然后去看房。

另外还有意向读\写锁,严格来说他们并不是一种锁,而是存放表中所有行锁的信息。就像我们在酒店,当我们预定一个房间时,就对该行(房间)添加 意向写锁,但是同时会在酒店的前台对该行(房间)做一个信息登记(旅客姓名、男女、住多长时间、家里几头牛等)。大家可以把意向锁当成这个酒店前台,它并不是真正意义上的锁(钥匙),它维护表中每行的加锁信息,是共用的。后续的旅客通过酒店前台来看哪个房间是可选的,那么,如果没有意图锁,会出现什么情况呢?假设我要住房间,那么我每次都要到每一个房间看看这个房间有没有住人,显然这样做的效率是很低下的。杀马特小伙儿表示支持!

读写锁、意向锁的兼容性如下所示;

锁类型读锁写锁意向读锁意向写锁
读锁兼容冲突兼容冲突
写锁冲突冲突冲突冲突
意向读锁兼容冲突兼容兼容
意向写锁冲突冲突兼容兼容

侨总:再回到MySQL原理上讲

1 共享(读)锁(Share Lock)

共享锁,又叫读锁,是读取操作(SELECT)时创建的锁。其他用户可以并发读取数据,但在读锁未释放前,也就是查询事务结束前,任何事务都不能对数据进行修改(获取数据上的写锁),直到已释放所有读锁。

如果事务A数据B(1024房)加上读锁后,则其他事务只能对数据B上加读锁,不能加写锁。获得读锁的事务只能读数据,不能修改数据。

SQL显示加锁写法:

SELECTLOCK IN SHARE MODE;

在查询语句后面增加LOCK IN SHARE MODE,MySQL就会对查询结果中的每行都加读锁,当没有其他线程对查询结果集中的任何一行使用写锁时,可以成功申请读锁,否则会被阻塞。其他线程也可以读取使用了读锁的表,而且这些线程读取的是同一个版本的数据。

2 排他(写)锁(Exclusive Lock)

排他锁又称写锁、独占锁,如果事务A数据B加上写锁后,则其他事务不能再对数据B加任何类型的锁。获得写锁的事务既能读数据,又能修改数据

SQL显示加锁写法:

SELECTFOR UPDATE;

在查询语句后面增加FOR UPDATE,MySQL 就会对查询结果中的每行都加写锁,当没有其他线程对查询结果集中的任何一行使用写锁时,可以成功申请写锁,否则会被阻塞。另外成功申请写锁后,也要先等待该事务前的读锁释放才能操作。

3 意向锁(Intention Lock)

意向锁属于表级锁,其设计目的主要是为了在一个事务中揭示下一行将要被请求锁的类型。InnoDB 中的两个表锁:

  • 意向共享锁(IS):表示事务准备给数据行加入共享锁,也就是说一个数据行加共享锁前必须先取得该表的IS锁;
  • 意向排他锁(IX):类似上面,表示事务准备给数据行加入排他锁,说明事务在一个数据行加排他锁前必须先取得该表的IX锁。

意向锁是 InnoDB 自动加的,不需要用户干预。

再强调一下,对于INSERT、UPDATE和DELETE,InnoDB 会自动给涉及的数据加排他锁;对于一般的SELECT语句,InnoDB 不会加任何锁,事务可以通过以下语句显式加共享锁或排他锁。

共享锁:SELECT … LOCK IN SHARE MODE;
排他锁:SELECT … FOR UPDATE;

面试官:(这小子有两下子)嗯,袁芳你怎么看?

HR:通俗易懂,我听懂了~~

面试官:好,那最后一个问题,你上面提到了乐观锁和悲观锁,谈谈你对它的看法吧。

侨总:其实悲观锁和乐观锁,也并不是 MySQL 或者数据库中独有的概念,而是并发编程的基本概念。主要区别在于,操作共享数据时,“悲观锁”即认为数据出现冲突的可能性更大,而“乐观锁”则是认为大部分情况不会出现冲突,进而决定是否采取排他性措施。

反映到 MySQL 数据库应用开发中,悲观锁一般就是利用类似 SELECT … FOR UPDATE 这样的语句,对数据加锁,避免其他事务意外修改数据。乐观锁则与 Java 并发包中的 AtomicFieldUpdater 类似,也是利用 CAS 机制,并不会对数据加锁,而是通过对比数据的时间戳或者版本号,来实现乐观锁需要的版本判断

MySQL的多版本并发控制 (MVCC),其本质就可以看作是种乐观锁机制,而排他性的读写锁、两阶段锁等则是悲观锁的实现。

面试官:好,小侨我看你对MySQL锁这块儿确实研究得比较透彻,连HR都听懂了,还是让我比较满意的。

面试官:你平时有什么爱好么?

侨总:我除了周末听戏坐包厢,骑马酒吧滑雪场。就是喜欢炒比特币啦!

面试官:哦,不好意思,我们公司反对炒比特币的行为,回去等通知吧。

侨总:???
在这里插入图片描述

说着面试官马经理走出了会议室,HR小姐姐表示我哪壶不开提哪壶,马老板高点买的比特币,现在泡沫炸了,亏成马,老板都差点亏没了。

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

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

相关文章

MySQL锁机制,行锁jingran加在索引上

锁概述 锁是计算机协调多个进程或线程并发访问某一资源的机制,应该都不陌生。?但在这之前我们先来看看并发控制,理清MVCC多版本并发控制和锁的关系,这也是之前我很迷惑的一个点 并发控制技术 在数据库中,数据可以允许多个用户…

闲置服务器 虚拟服务器,闲置主机搭建服务器

闲置主机搭建服务器 内容精选换一换安装传输工具在本地主机和Windows云服务器上分别安装数据传输工具,将文件上传到云服务器。例如QQ.exe。在本地主机和Windows云服务器上分别安装数据传输工具,将文件上传到云服务器。例如QQ.exe。本地磁盘映射(推荐使用…

浏览器接收响应数据过大_交互响应性能之优化FID

由于 FID 需要一个真实用户的交互,所以无法用实验数据测试。为了在实验数据下预测 FID,通常会用 TBT(Total Blocking Time),具体这个指标后面文章会介绍。他们测量的内容不同,但改善 TBT 通常也能改善 FID。一个糟糕的 FID 主要原…

postman如何发送application/json类的post请求

​ 当接口类型限制为只接受application/json类型的请求,我们使用postman测试的时候怎么选择呢?如下图: 我们需要先在postman上选择POST请求方法,后边输入要请求的地址即可。 在Body选项卡选择raw,然后再后边的下拉选项…

fe文件服务器,FE File Explorer

FE File Explorer是Mac电脑上的一款文件管理应用。FE File Explorer可以访问FTP,SFTP,WebDAV服务器和网络共享上的文件。在这些位置之间传输文件。将电影和歌曲流式传输到Mac。直接在远程位置查看和编辑文档,照片,文件&#xff0c…

swift中文文档_Flutter 中文文档:使用 Packages

Flutter 支持使用其他开发者向 Flutter 和 Dart 生态系统贡献的共享 package,这意味着你可以快速构建应用而不是一切从零开始。现有的 package 支持许多使用场景,例如,网络请求 (http),自定义导航/路由处理 (fluro),集…

Spring深入理解之ComponentScan___@ComponentScan 详解

Spring深入理解之ComponentScan 一、概述 ComponentScan顾名思义包扫描,底层其实就可以通过递归算法反射将其装载成bean来实现的,实在开发过程中,Spring已经帮我们实现好了,我们其实就可以直接使用XML或者注解的形式来进行业务处…

云服务器centos怎么还原系统还原,云服务器centos怎么还原系统还原

云服务器centos怎么还原系统还原 内容精选换一换云耀云服务器(Halo Elastic Cloud Server,HECS)是可以快速搭建简单应用的新一代云服务器,具备独立、完整的操作系统和网络功能。提供快速地应用部署和简易的管理能力,适用于网站搭建、开发环境…

高倍数泡沫装置PHP_泡沫灭火系统,了解这几点就好

1 集输站库泡沫灭火系统的构成油区的泡沫灭火系统主要由消防水泵、消防水源、泡沫灭火剂储存装置、泡沫比例混合装置、泡沫产生装置及管道等组成。泡沫液按发泡倍数不同可分为低倍数泡沫液、中倍数泡沫液和高倍数泡沫液。发泡倍数 20 以下的称为低倍数泡沫液, 发泡倍…

python自动化_Python 实现Excel自动化办公上

今天的文章分享Python 如何轻松操作Excel 这款office 办公软件的,在Python 中你要针对某个对象进行操作,是需要安装与其对应的第三方库的,这里对于Excel 也不例外,它也有对应的第三方库,即xlrd 库。什么是xlrd库Python…

utf8编码为什么这么普遍,优势在哪里?

为什么需要字符集 计算机存储的和认识的东西就是0和1,我们存储的任何东西最后都会转为0和1的组合计算机才能处理,更贴切的说是我们看到的英文、中文等都是0和1组合的二进制经过一定规则转换为我们认识的字符,这个规则就是字符集。 有哪些字…

SpringBoot默认包扫描机制及@ComponentScan指定扫描路径详解

SpringBoot默认包扫描机制及ComponentScan指定扫描路径详解 SpringBoot默认包扫描机制 标注了Component和Component的衍生注解如Controller,Service,Repository就可以把当前的Bean加入到IOC容器中。那么SpringBoot是如何知道要去扫描Component注解的呢。ComponentScan做的事情…

raid卡组不同raid_RAID 类型介绍

RAID (Redundant Array of Independent/InexpensiveDisks),独立磁盘冗余阵列,是一种将多块独立的硬盘(物理硬盘)按不同的组合方式形成一个硬盘组(逻辑硬盘),从而提供比单块硬盘更大的存储容量、更高的可靠性和 更快的读写性能等。该概念最早由…

springboot前端传参date类型后台处理方式

springboot前端传参date类型后台处理方式 先说结论:建议大家直接使用JsonFormat,原因如下: 1、针对json格式:在配置文件中加以下配置 spring.jackson.date-formatyyyy-MM-dd HH:mm:ssspring.jackson.time-zoneGMT82、针对form表…

SpringBoot:解决日期转换问题和日期展示问题

本次我们解决问题:日期展示问题(返回的json中日期的格式是:“birthday”:“1988-08-07T15:00:00.0000000”);需要转化成指定的格式(年月日时分秒格式) 1、问题如 2、解决方案 在配置中加入 #时间戳统一转换 spring.jackson.date-formatyyy…

日期格式化时注解@DateTimeFormat无效的问题分析

日期格式化时注解DateTimeFormat无效的问题分析 背景 有时候我们在写接口时,需要把前台传来的日期String类型转为Date类型 这时我们可能会用到DateTimeFormat注解 在请求数据为非JSON格式时,这个注解是没有问题的,可用的; 但…

12 - java 类加载内存图

栈是线程私有的、堆是线程公有的如果不加 static 就是堆里面的属性,加了static 就是元数据区的属性

source code怎么用_code-builder代码生成器

背景本来code-builder是专门为MyBatis Enhance来编写的一块代码生成器code-builder可以用来做什么?code-builder是一款代码生成maven mojo插件,通过简单的配置就可以完成数据库内Table转换Entity或者其他实体类,想怎么生成完全根据你的个人业…

@Transactional注解的失效场景

Transactional注解的失效场景 引言 Transactional 注解相信大家并不陌生,平时开发中很常用的一个注解,它能保证方法内多个数据库操作要么同时成功、要么同时失败。使用Transactional注解时需要注意许多的细节,不然你会发现Transactional总是…

Spring 事务方法与非事务方法相互调用 @Transactional 注解失效不回滚?

写这篇文章的初衷呢就是最近遇到了一个Spring事务的大坑。与其说是坑,还不如说是自己事务这块儿太薄弱导致的(自嘲下)。 项目环境 Spring Boot 下面开始问题描述,发生的过程有点长,想直接看方案的直接跳过哦~&#x…