西安知名网站建设公司,什么网站权重高,视频直播软件有哪些平台,自己做的网站怎么放视频教程腾讯云数据库负责人林晓斌说过#xff1a;“我们面试MySQL同事时只考察两点#xff0c;索引和锁”。言简意赅#xff0c;MySQL锁的重要性不言而喻。 本文通过同事“侨总”的一场面试#xff0c;带你通俗易懂的掌握MySQL各种锁机制#xff0c;希望可以帮到你#xff01;近… 腾讯云数据库负责人林晓斌说过“我们面试MySQL同事时只考察两点索引和锁”。言简意赅MySQL锁的重要性不言而喻。 本文通过同事“侨总”的一场面试带你通俗易懂的掌握MySQL各种锁机制希望可以帮到你近期会继续整理深入性的锁机制文章有兴趣的老铁记得关注一下到时叫你~ 今天的主人公是我们公司同事侨总传说中手上有10个比特币的男人。自从比特币大涨以来养成了几个小爱好周末听戏坐包厢骑马酒吧滑雪场。
这不前两天侨总又双叒叕出来体验面试了晚上请我烧烤时跟我聊了聊这次有趣的面试经历真是意犹未尽趁他回味之余我又吃了十几串儿腰子和羊肉~ 嗯真香
对不住跑题了。。人到中年嘛保温杯里泡枸杞之余总会。。。
来不及解释了快上车 大家好我是陈哈哈的同事“侨总”领导一般不敢喊我名字都叫我小侨~ 下面是我的一次面试经历面试官是技术经理和HR大家吃好喝好~ 侨总马…小马哥好
面试官你好小侨啊看你简历写着精通MySQL锁你认为精通应该是啥水平呢
侨总马哥我是个老实人我认为精通就是比面试官知道的多就完了。。
面试官怎么有种似曾相识的感觉《听我讲完redo log、binlog原理面试官老脸一红》
面试官行那你先给我说说MySQL设计这个锁是干啥用的呀
侨总数据库锁设计的初衷是处理并发问题。作为多用户共享的资源当出现并发访问的时候为了保证数据的一致性数据库需要合理地控制资源的访问规则。而锁就是用来实现这些访问规则的重要机制。
简单说数据表就像公共厕所。emmm…换个下饭的说法数据表就好比您开的一家酒店而每行数据就像酒店的房间如果大家随意进出就会出现多人抢夺同一个房间的情况而在房间上装上锁申请到钥匙的人才可以入住并且将房间锁起来其他人只有等他用完退房后才可以再次使用这样保证了房间的一致性方便酒店进行管理。
MySQL锁机制的初衷便是如此当然MySQL数据库由于其自身架构的特点存在多种数据存储引擎每种存储引擎所针对的应用场景特点都不太一样为了满足各自特定应用场景的需求每种存储引擎的锁定机制都是为各自所面对的特定场景而优化设计所以各存储引擎的锁定机制也有较大区别。 面试官嗯那你说一下MySQL都分为哪些锁。 侨总
按锁粒度从大到小分类表锁页锁和行锁以及特殊场景下使用的全局锁如果按锁级别分类则有共享读锁、排他写锁、意向共享读锁、意向排他写锁以及Innodb引擎为解决幻读等并发场景下事务存在的数据问题引入的Record Lock行记录锁、Gap Lock间隙锁、Next-key LockRecord Lock Gap Lock结合等还有就是我们面向编程的两种锁思想悲观锁、乐观锁。
面试官袁芳你怎么看
HR小姐姐。。。 面试官小侨啊那你来谈一谈你对表锁、行锁的理解吧。 表锁
侨总表级别的锁定是MySQL各存储引擎中最大颗粒度的锁定机制。该锁定机制最大的特点是实现逻辑非常简单带来的系统负面影响最小。所以获取锁和释放锁的速度很快。由于表级锁一次会将整个表锁定所以可以很好的避免困扰我们的死锁问题。
当然锁定颗粒度大所带来最大的负面影响就是出现锁定资源争用的概率也会最高大大降低并发度。
使用表级锁定的主要是MyISAMMEMORYCSV等一些非事务性存储引擎。
行锁
侨总与表锁正相反行锁最大的特点就是锁定对象的颗粒度很小也是目前各大数据库管理软件所实现的锁定颗粒度最小的。由于锁定颗粒度很小所以发生锁定资源争用的概率也最小能够给予应用程序尽可能大的并发处理能力从而提高系统的整体性能。
虽然能够在并发处理能力上面有较大的优势但是行级锁定也因此带来了不少弊端。由于锁定资源的颗粒度很小所以每次获取锁和释放锁需要做的事情也更多带来的消耗自然也就更大了。此外行级锁定也最容易发生死锁。
使用行级锁定的主要是InnoDB存储引擎。
适用场景从锁的角度来说表级锁更适合于以查询为主只有少量按索引条件更新数据的应用如Web应用而行级锁则更适合于有大量按索引条件并发更新数据的情况同时又有并发查询的应用场景。
页锁
除了表锁、行锁外MySQL还有一种相对偏中性的页级锁页锁是MySQL中比较独特的一种锁定级别在其他数据库管理软件中也并不是太常见。页级锁定的特点是锁定颗粒度介于行级锁定与表级锁之间所以获取锁定所需要的资源开销以及所能提供的并发处理能力也同样是介于上面二者之间。另外页级锁定和行级锁定一样会发生死锁。
使用页级锁定的主要是BerkeleyDB存储引擎。
面试官那全局锁是什么时候用的呢
全局锁
侨总首先全局锁是对整个数据库实例加锁。使用场景一般在全库逻辑备份时。
MySQL提供加全局读锁的命令Flush tables with read lock (FTWRL)
这个命令可以使整个库处于只读状态。使用该命令之后数据更新语句、数据定义语句和更新类事务的提交语句等修改数据库的操作都会被阻塞。
风险
如果在主库备份在备份期间不能更新业务停摆如果在从库备份备份期间不能执行主库同步的binlog导致主从延迟同步
还有一种锁全局的方式set global readonlytrue 相当于将整个库设置成只读状态但这种修改global配置量级较重和全局锁不同的是如果执行Flush tables with read lock 命令后如果客户端发生异常断开那么MySQL会自动释放这个全局锁整个库回到可以正常更新的状态。但将库设置为readonly后客户端发生异常断开数据库依旧会保持readonly状态会导致整个库长时间处于不可写状态试想一下微信只能看不能打字~~
HR小姐姐那微信不就完蛋了
侨总是啊抓紧找老实人背锅 面试官不错你把这几种锁的侧重点都表述清楚了。那你再说一下你对不同级别的那几种锁的使用场景和理解吧 侨总MySQL基于锁级别又分为共享读锁、排他写锁、意向共享读锁、意向排他写锁
共享读锁、排他写锁、意向共享读锁、意向排他写锁
侨总对于共享读锁、排他写锁比如咱们住酒店入住前顾客都是有权看房的只看不住想白嫖都是可以的前台小姐姐会把门给你打开。当然也允许不同的顾客一起看共享 读比如和这位杀马特小伙子。 看房时房间相当于公共场所小姐姐嘱咐不能乱涂乱画也不能偷喝免费的矿泉水。。如果你觉得不错偷偷跑到前台要定这间房交钱后会给你这个房间的钥匙并将房间状态改为已入住不再允许其他人看房排他 写。
对了当办理入住时前台小姐姐也会通知看房的杀马特小伙子说这间房已经有人定了等看房的杀马特小伙儿骂骂咧咧出门后看到满头大汗的你鄙夷着咽了一口口水咳tui然后你锁上门哼着歌儿开始干那些见不得人的事儿~~直到你退房前其他人无法在看你的房。
可见读锁是可以并发获取的共享的而写锁只能给一个事务处理排他的。当你想获取写锁时需要等待之前的读锁都释放后方可加写锁而当你想获取读锁时只要数据没有被写锁锁住你都可以获取到读锁然后去看房。
另外还有意向读\写锁严格来说他们并不是一种锁而是存放表中所有行锁的信息。就像我们在酒店当我们预定一个房间时就对该行房间添加 意向写锁但是同时会在酒店的前台对该行房间做一个信息登记旅客姓名、男女、住多长时间、家里几头牛等。大家可以把意向锁当成这个酒店前台它并不是真正意义上的锁钥匙它维护表中每行的加锁信息是共用的。后续的旅客通过酒店前台来看哪个房间是可选的那么如果没有意图锁会出现什么情况呢假设我要住房间那么我每次都要到每一个房间看看这个房间有没有住人显然这样做的效率是很低下的。杀马特小伙儿表示支持
读写锁、意向锁的兼容性如下所示
锁类型读锁写锁意向读锁意向写锁读锁兼容冲突兼容冲突写锁冲突冲突冲突冲突意向读锁兼容冲突兼容兼容意向写锁冲突冲突兼容兼容
侨总再回到MySQL原理上讲
1 共享读锁Share Lock
共享锁又叫读锁是读取操作SELECT时创建的锁。其他用户可以并发读取数据但在读锁未释放前也就是查询事务结束前任何事务都不能对数据进行修改获取数据上的写锁直到已释放所有读锁。
如果事务A对数据B1024房加上读锁后则其他事务只能对数据B上加读锁不能加写锁。获得读锁的事务只能读数据不能修改数据。
SQL显示加锁写法:
SELECT … LOCK IN SHARE MODE;在查询语句后面增加LOCK IN SHARE MODEMySQL就会对查询结果中的每行都加读锁当没有其他线程对查询结果集中的任何一行使用写锁时可以成功申请读锁否则会被阻塞。其他线程也可以读取使用了读锁的表而且这些线程读取的是同一个版本的数据。
2 排他写锁Exclusive Lock
排他锁又称写锁、独占锁如果事务A对数据B加上写锁后则其他事务不能再对数据B加任何类型的锁。获得写锁的事务既能读数据又能修改数据。
SQL显示加锁写法:
SELECT … FOR UPDATE;在查询语句后面增加FOR UPDATEMySQL 就会对查询结果中的每行都加写锁当没有其他线程对查询结果集中的任何一行使用写锁时可以成功申请写锁否则会被阻塞。另外成功申请写锁后也要先等待该事务前的读锁释放才能操作。
3 意向锁Intention Lock
意向锁属于表级锁其设计目的主要是为了在一个事务中揭示下一行将要被请求锁的类型。InnoDB 中的两个表锁
意向共享锁IS表示事务准备给数据行加入共享锁也就是说一个数据行加共享锁前必须先取得该表的IS锁意向排他锁IX类似上面表示事务准备给数据行加入排他锁说明事务在一个数据行加排他锁前必须先取得该表的IX锁。
意向锁是 InnoDB 自动加的不需要用户干预。
再强调一下对于INSERT、UPDATE和DELETEInnoDB 会自动给涉及的数据加排他锁对于一般的SELECT语句InnoDB 不会加任何锁事务可以通过以下语句显式加共享锁或排他锁。 共享锁SELECT … LOCK IN SHARE MODE; 排他锁SELECT … FOR UPDATE; 面试官这小子有两下子嗯袁芳你怎么看
HR通俗易懂我听懂了~~ 面试官好那最后一个问题你上面提到了乐观锁和悲观锁谈谈你对它的看法吧。 侨总其实悲观锁和乐观锁也并不是 MySQL 或者数据库中独有的概念而是并发编程的基本概念。主要区别在于操作共享数据时“悲观锁”即认为数据出现冲突的可能性更大而“乐观锁”则是认为大部分情况不会出现冲突进而决定是否采取排他性措施。
反映到 MySQL 数据库应用开发中悲观锁一般就是利用类似 SELECT … FOR UPDATE 这样的语句对数据加锁避免其他事务意外修改数据。乐观锁则与 Java 并发包中的 AtomicFieldUpdater 类似也是利用 CAS 机制并不会对数据加锁而是通过对比数据的时间戳或者版本号来实现乐观锁需要的版本判断。
MySQL的多版本并发控制 MVCC其本质就可以看作是种乐观锁机制而排他性的读写锁、两阶段锁等则是悲观锁的实现。
面试官好小侨我看你对MySQL锁这块儿确实研究得比较透彻连HR都听懂了还是让我比较满意的。
面试官你平时有什么爱好么
侨总我除了周末听戏坐包厢骑马酒吧滑雪场。就是喜欢炒比特币啦
面试官哦不好意思我们公司反对炒比特币的行为回去等通知吧。
侨总
说着面试官马经理走出了会议室HR小姐姐表示我哪壶不开提哪壶马老板高点买的比特币现在泡沫炸了亏成马老板都差点亏没了。