《我想进大厂》之 MYSQL 夺命连环13问

来源 | 科技缪缪

想进大厂,mysql不会那可不行,来接受mysql面试挑战吧,看看你能坚持到哪里?


能说下 myisam 和 innodb 的区别吗?

myisam引擎是5.1版本之前的默认引擎,支持全文检索、压缩、空间函数等,但是不支持事务和行级锁,所以一般用于有大量查询少量插入的场景来使用,而且myisam不支持外键,并且索引和数据是分开存储的。

innodb是基于聚簇索引建立的,和myisam相反它支持事务、外键,并且通过MVCC来支持高并发,索引和数据存储在一起。


说下mysql的索引有哪些吧,聚簇和非聚簇索引又是什么?

索引按照数据结构来说主要包含B+树和Hash索引。

假设我们有张表,结构如下:

create table user(id int(11) not null,age int(11) not null,primary key(id),key(age)
);

B+树是左小右大的顺序存储结构,节点只包含id索引列,而叶子节点包含索引列和数据,这种数据和索引在一起存储的索引方式叫做聚簇索引,一张表只能有一个聚簇索引。假设没有定义主键,InnoDB会选择一个唯一的非空索引代替,如果没有的话则会隐式定义一个主键作为聚簇索引。

这是主键聚簇索引存储的结构,那么非聚簇索引的结构是什么样子呢?非聚簇索引(二级索引)保存的是主键id值,这一点和myisam保存的是数据地址是不同的。

最终,我们一张图看看InnoDB和Myisam聚簇和非聚簇索引的区别。


 那你知道什么是覆盖索引和回表吗?

覆盖索引指的是在一次查询中,如果一个索引包含或者说覆盖所有需要查询的字段的值,我们就称之为覆盖索引,而不再需要回表查询。

而要确定一个查询是否是覆盖索引,我们只需要explain sql语句看Extra的结果是否是“Using index”即可。

以上面的user表来举例,我们再增加一个name字段,然后做一些查询试试。

explain select * from user where age=1; //查询的name无法从索引数据获取
explain select id,age from user where age=1; //可以直接从索引获取锁的类型有哪些呢

mysql锁分为共享锁排他锁,也叫做读锁和写锁。

读锁是共享的,可以通过lock in share mode实现,这时候只能读不能写。

写锁是排他的,它会阻塞其他的写锁和读锁。从颗粒度来区分,可以分为表锁行锁两种。

表锁会锁定整张表并且阻塞其他用户对该表的所有读写操作,比如alter修改表结构的时候会锁表。

行锁又可以分为乐观锁悲观锁,悲观锁可以通过for update实现,乐观锁则通过版本号实现。


你能说下事务的基本特性和隔离级别吗?

事务基本特性ACID分别是:

原子性指的是一个事务中的操作要么全部成功,要么全部失败。

一致性指的是数据库总是从一个一致性的状态转换到另外一个一致性的状态。比如A转账给B100块钱,假设中间sql执行过程中系统崩溃A也不会损失100块,因为事务没有提交,修改也就不会保存到数据库。

隔离性指的是一个事务的修改在最终提交前,对其他事务是不可见的。

持久性指的是一旦事务提交,所做的修改就会永久保存到数据库中。

而隔离性有4个隔离级别,分别是:

read uncommit 读未提交,可能会读到其他事务未提交的数据,也叫做脏读。

用户本来应该读取到id=1的用户age应该是10,结果读取到了其他事务还没有提交的事务,结果读取结果age=20,这就是脏读。

read commit 读已提交,两次读取结果不一致,叫做不可重复读。

不可重复读解决了脏读的问题,他只会读取已经提交的事务。

用户开启事务读取id=1用户,查询到age=10,再次读取发现结果=20,在同一个事务里同一个查询读取到不同的结果叫做不可重复读。

repeatable read 可重复复读,这是mysql的默认级别,就是每次读取结果都一样,但是有可能产生幻读。

serializable 串行,一般是不会使用的,他会给每一行读取的数据加锁,会导致大量超时和锁竞争的问题。


那ACID靠什么保证的呢?

A原子性由undo log日志保证,它记录了需要回滚的日志信息,事务回滚时撤销已经执行成功的sql。

C一致性一般由代码层面来保证。

I隔离性由MVCC来保证。

D持久性由内存+redo log来保证,mysql修改数据同时在内存和redo log记录这次操作,事务提交的时候通过redo log刷盘,宕机的时候可以从redo log恢复。


那你说说什么是幻读,什么是MVCC?

要说幻读,首先要了解MVCC,MVCC叫做多版本并发控制,实际上就是保存了数据在某个时间节点的快照。

我们每行数实际上隐藏了两列,创建时间版本号,过期(删除)时间版本号,每开始一个新的事务,版本号都会自动递增。

还是拿上面的user表举例子,假设我们插入两条数据,他们实际上应该长这样。

这时候假设小明去执行查询,此时current_version=3:

select * from user where id<=3;

同时,小红在这时候开启事务去修改id=1的记录,current_version=4:

update user set name='张三三' where id=1;

执行成功后的结果是这样的:

如果这时候还有小黑在删除id=2的数据,current_version=5,执行后结果是这样的。

由于MVCC的原理是查找创建版本小于或等于当前事务版本,删除版本为空或者大于当前事务版本,小明的真实的查询应该是这样:

select * from user where id<=3 and create_version<=3 and (delete_version>3 or delete_version is null);

所以小明最后查询到的id=1的名字还是'张三',并且id=2的记录也能查询到。这样做是为了保证事务读取的数据是在事务开始前就已经存在的,要么是事务自己插入或者修改的。

明白MVCC原理,我们来说什么是幻读就简单多了。举一个常见的场景,用户注册时,我们先查询用户名是否存在,不存在就插入,假定用户名是唯一索引。

1、小明开启事务current_version=6查询名字为'王五'的记录,发现不存在。

2、小红开启事务current_version=7插入一条数据,结果是这样:

3、小明执行插入名字'王五'的记录,发现唯一索引冲突,无法插入,这就是幻读。


那你知道什么是间隙锁吗?

间隙锁是可重复读级别下才会有的锁,结合MVCC和间隙锁可以解决幻读的问题。我们还是以user举例,假设现在user表有几条记录:

当我们执行:

begin;
select * from user where age=20 for update;begin;
insert into user(age) values(10); #成功
insert into user(age) values(11); #失败
insert into user(age) values(20); #失败
insert into user(age) values(21); #失败
insert into user(age) values(30); #失败

只有10可以插入成功,那么因为表的间隙mysql自动帮我们生成了区间(左开右闭)。

(negative infinity,10],(10,20],(20,30],(30,positive infinity)

由于20存在记录,所以(10,20],(20,30]区间都被锁定了无法插入、删除。

如果查询21呢?就会根据21定位到(20,30)的区间(都是开区间)。

需要注意的是唯一索引是不会有间隙索引的。


你们数据量级多大?分库分表怎么做的?

首先分库分表分为垂直和水平两个方式,一般来说我们拆分的顺序是先垂直后水平。

垂直分库

基于现在微服务拆分来说,都是已经做到了垂直分库了。

垂直分表

如果表字段比较多,将不常用的、数据较大的等等做拆分。

水平分表

首先根据业务场景来决定使用什么字段作为分表字段(sharding_key),比如我们现在日订单1000万,我们大部分的场景来源于C端,我们可以用user_id作为sharding_key,数据查询支持到最近3个月的订单,超过3个月的做归档处理,那么3个月的数据量就是9亿,可以分1024张表,那么每张表的数据大概就在100万左右。

比如用户id为100,那我们都经过hash(100),然后对1024取模,就可以落到对应的表上了。


那分表后的ID怎么保证唯一性的呢?

因为我们主键默认都是自增的,那么分表之后的主键在不同表就肯定会有冲突了。有几个办法考虑:

  1. 设定步长,比如1-1024张表我们分别设定1-1024的基础步长,这样主键落到不同的表就不会冲突了。

  2. 分布式ID,自己实现一套分布式ID生成算法或者使用开源的比如雪花算法这种。

  3. 分表后不使用主键作为查询依据,而是每张表单独新增一个字段作为唯一主键使用,比如订单表订单号是唯一的,不管最终落在哪张表都基于订单号作为查询依据,更新也一样。

分表后非sharding_key的查询怎么处理呢?

  1. 可以做一个mapping表,比如这时候商家要查询订单列表怎么办呢?不带user_id查询的话你总不能扫全表吧?所以我们可以做一个映射关系表,保存商家和用户的关系,查询的时候先通过商家查询到用户列表,再通过user_id去查询。

  2. 打宽表,一般而言,商户端对数据实时性要求并不是很高,比如查询订单列表,可以把订单表同步到离线(实时)数仓,再基于数仓去做成一张宽表,再基于其他如es提供查询服务。

  3. 数据量不是很大的话,比如后台的一些查询之类的,也可以通过多线程扫表,然后再聚合结果的方式来做。或者异步的形式也是可以的。

List<Callable<List<User>>> taskList = Lists.newArrayList();
for (int shardingIndex = 0; shardingIndex < 1024; shardingIndex++) {taskList.add(() -> (userMapper.getProcessingAccountList(shardingIndex)));
}
List<ThirdAccountInfo> list = null;
try {list = taskExecutor.executeTask(taskList);
} catch (Exception e) {//do something
}public class TaskExecutor {public <T> List<T> executeTask(Collection<? extends Callable<T>> tasks) throws Exception {List<T> result = Lists.newArrayList();List<Future<T>> futures = ExecutorUtil.invokeAll(tasks);for (Future<T> future : futures) {result.add(future.get());}return result;}
}

说说mysql主从同步怎么做的吧?

首先先了解mysql主从同步的原理

  1. master提交完事务后,写入binlog。

  2. slave连接到master,获取binlog。

  3. master创建dump线程,推送binglog到slave。

  4. slave启动一个IO线程读取同步过来的master的binlog,记录到relay log中继日志中。

  5. slave再开启一个sql线程读取relay log事件并在slave执行,完成同步。

  6. slave记录自己的binglog。

由于mysql默认的复制方式是异步的,主库把日志发送给从库后不关心从库是否已经处理,这样会产生一个问题就是假设主库挂了,从库处理失败了,这时候从库升为主库后,日志就丢失了。由此产生两个概念。

全同步复制

主库写入binlog后强制同步日志到从库,所有的从库都执行完成后才返回给客户端,但是很显然这个方式的话性能会受到严重影响。

半同步复制

和全同步不同的是,半同步复制的逻辑是这样,从库写入日志成功后返回ACK确认给主库,主库收到至少一个从库的确认就认为写操作完成。


那主从的延迟怎么解决呢?

这个问题貌似真的是个无解的问题,只能是说自己来判断了,需要走主库的强制走主库查询。

更多阅读推荐

  • 超详细 | 21张图带你领略集合的线程不安全

  • 云起云涌:PaaS 体系架构与运维系统上云实践

  • 该买哪家二手手机呢?程序员爬取京东告诉你!

  • 苹果秋季发布会于9月16日召开;华为搜索业务将在国内亮相;Android 11正式版发布 | 极客头条

  • 腾讯微博即将关停,十年了,你用过吗?

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

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

相关文章

心动网络:PolarDB助力心动网络打造爆款手游

公司介绍 心动网络&#xff0c;国内极具知名度的游戏公司&#xff0c;中国互联网百强企业。旗下业务涉及游戏研发运营、动画制作、偶像娱乐等多个产业。公司创立于2002年&#xff0c;前身为中国最早的互联网分享网站之一的VeryCD。2009年起&#xff0c;公司开始打造心动网络的…

Vue文件在VsCode工具中红色波浪线的问题解决方法

在setting.json种添加 "vetur.validation.template": false, //vue文件取消波浪线

数云:PolarDB助力数云轻松应对双十一

公司介绍 我们杭州数云信息技术有限公司成立于2011年&#xff0c;伴随着电子商务、大数据应用和零售企业互联网化的趋势快速发展&#xff0c;目前已成为国内领先的数据化营销软件产品和服务提供商。我们致力于为消费品牌和零售品牌商提供整合软件产品、数据模型和专业服务的一…

点触科技:构建实时计算和数据仓库解决方案

公司介绍 厦门点触科技股份有限公司&#xff0c;新三板挂牌企业&#xff08;股票代码&#xff1a;870702&#xff09;&#xff0c;成立于2013年&#xff0c;是一家以历史养成类游戏研发与发行为主&#xff0c;专业从事手机游戏的策划、研发制作、商业化运营的创新型发展公司。…

定位云原生数据中台,「智领云」获数千万元A轮融资

来源 | 智领云科技据消息&#xff0c;「智领云」获金沙江联合资本领投&#xff0c;线性资本跟投的数千万元A轮融资。本轮融资将主要用于市场拓展和产品线完善。此前&#xff0c;智领云在2019年5月获得线性资本千万级人民币Pre-A轮融资。智领云成立于2016年&#xff0c;是一家数…

写给大家看的“不负责任” K8s 入门文档

作者 | 邓青琳&#xff08;轻零&#xff09; 阿里巴巴技术专家 导读&#xff1a;本文转载自阿里巴巴技术专家邓青琳(轻零)在内部的分享&#xff0c;他从阿里云控制台团队转岗到 ECI 研发团队&#xff08;Serverless Kubernetes 背后的实现基石&#xff09;&#xff0c;从零开…

腾讯智慧交通战略重磅升级 打造以人为中心的未来交通

在新基建加速布局下&#xff0c;智慧交通正在成为新基建的主力军&#xff0c;不仅可以助力新基建与传统基建融合&#xff0c;还将推动智慧城市建设&#xff0c;推动我国实现“交通大国”向“交通强国”的升级。9月10日&#xff0c;腾讯全球数字生态大会智慧交通分论坛云上召开&…

GitHub 标星 11000+,阿里开源微服务如何连续 10 年扛住双十一大促

云栖号资讯&#xff1a;【点击查看更多行业资讯】 在这里您可以找到不同行业的第一手的上云资讯&#xff0c;还在等什么&#xff0c;快来&#xff01; 作者 | 宿何&#xff0c;阿里云高级开发工程师 责编 | 唐小引 封图 | CSDN 下载自东方 IC 出品 | CSDN&#xff08;ID&#x…

轻松构建基于 Serverless 架构的弹性高可用音视频处理系统

作者 | 罗松(西流) 阿里巴巴技术专家 本文整理自架构师成长系列 2 月 12 日直播课程。 关注“阿里巴巴云原生”公众号&#xff0c;回复 “212”&#xff0c;即可获取对应直播回放链接及 PPT 下载链接。 前言 随着计算机技术和 Internet 的日新月异&#xff0c;视频点播技…

学不动?Apache Member 教你评估实用技术的思路

导读&#xff1a;笔者从 2008 年开始工作到现在也有 11 个年头了&#xff0c;一路走来都在和数据打交道&#xff0c;做过很多大数据底层框架内核的开发 ( Hadoop&#xff0c;Pig&#xff0c;Tez&#xff0c;Spark&#xff0c;Livy )&#xff0c;现在是多个 Apache 项目的 PMC。…

linux异步IO的几种方法及重点案例

异步IO的方法 在Linux下&#xff0c;有几种常见的异步I/O&#xff08;Asynchronous I/O&#xff09;机制可供选择。以下是其中一些主要的异步I/O机制&#xff1a; POSIX AIO&#xff08;Asynchronous I/O&#xff09;&#xff1a;POSIX AIO是一种标准的异步I/O机制&#xff0c…

AI赋能案例—阿里云身份证OCR识别助力实现“无接触”式政务服务!

2020年初的这场疫情&#xff0c;是一场对突发性公共卫生事件应急处置的大考&#xff0c;也是对数字政务体系能力的检验。在保证不影响办事效率的情况&#xff0c;如何减少人员的接触是政务场景下的“防疫”关键&#xff01;日前由一窗&#xff08;北京&#xff09;互联网科技研…

Hive 终于等来了 Flink

Apache Spark 什么时候开始支持集成 Hive 功能&#xff1f;笔者相信只要使用过 Spark 的读者&#xff0c;应该都会说这是很久以前的事情了。 那 Apache Flink 什么时候支持与 Hive 的集成呢&#xff1f;读者可能有些疑惑&#xff0c;还没有支持吧&#xff0c;没用过&#xff1…

AWS拓展中国合作伙伴生态 加速企业数字化转型进程

在2020年9月9日举办的AWS合作伙伴峰会2020上&#xff0c;亚马逊云服务&#xff08;AWS&#xff09;宣布将携手APN合作伙伴进一步拓展中国合作伙伴生态&#xff0c;以更好地服务客户的数字化转型和数字创新需求。AWS宣布与毕马威、神州数码分别达成战略合作关系&#xff0c;结合…

如何在 Flink 中规划 RocksDB 内存容量?

本文描述了一些配置选项&#xff0c;这些选项将帮助您有效地管理规划 Apache Flink 中 RocksDB state backend 的内存大小。在前面的文章[1]中&#xff0c;我们描述了 Flink 中支持的可选 state backend 选项&#xff0c;本文将介绍跟 Flink 相关的一些 RocksDB 操作&#xff0…

能力差的程序员90%输在这点上!CTO:其实都是瞎努力!

在大数据浪潮当中&#xff0c;数据分析是这个时代的不二“掘金技能”。我们每一个人&#xff0c;每天无时无刻都在生产数据&#xff0c;一分钟内&#xff0c;微博上新发的数据量超过10万&#xff0c;b站的视频播放量超过600万......这些庞大的数字&#xff0c;意味着什么&#…

DNS高可用设计--软件高可用

DNS是网络的基础服务&#xff0c;网络上的各种应用对DNS的依赖性很高。DNS的稳定&#xff0c;直接决定了上层应用服务的稳定。那如何保障DNS服务的高可用呢&#xff1f; 我们先来看下高可用的概念&#xff1a; 高可用 高可用&#xff08;High availability&#xff09;&#…

十年磨一剑!支付宝自研数据库OceanBase通过阿里云向全球开放

近日&#xff0c;由支付宝自研的金融级分布式数据库OceanBase正式通过阿里云向全球开放&#xff0c;提供高可用、高性能、低成本的计算服务&#xff0c;企业可在云上获得“支付宝同款”的世界顶级数据库处理能力。 数据库和操作系统一样&#xff0c;是IT行业的重要基础软件&am…

20张图,带你搞懂高并发中的线程与线程池!

来源 | 码农的荒岛求生从这篇开始将会开启高性能、高并发系列&#xff0c;本篇是该系列的开篇&#xff0c;主要关注多线程以及线程池。一切要从CPU说起你可能会有疑问&#xff0c;讲多线程为什么要从CPU说起呢&#xff1f;原因很简单&#xff0c;在这里没有那些时髦的概念&…

React 常用UI库

流行的开源React UI组件库 http://www.material-ui.com/#/ 组件总览 - Ant Designhttps://ant.design/components/overview-cn/ 安装方式&#xff1a;yarn add antd ## 按需加载antd库样式 1. 安装&#xff1a;yarn add react-app-rewired customize-cra 2. 修改 package.j…