MySQL面试-1

server/2024/11/26 15:20:31/

 InnoDB中ACID的实现

先说一下原子性是怎么实现的。 事务要么失败,要么成功,不能做一半。聪明的InnoDB,在干活儿之前,先将要做的事情记录到一个叫undo log的日志文件中,如果失败了或者主动rollback,就可以通过undo log的内容,将事务回滚。


那undo log里面具体记录了什么信息呢?


undo log属于逻辑日志,它记录的是sql执行相关的信息。当发生回滚时,InnoDB会根据undo log的内容做与之前相反的工作,使数据回到之前的状态


那隔离性怎么实现呢?


MySQL能支持Repeatable Read这种高隔离级别,主要是锁和MVCC一起努力的结果。 我先说锁吧。事务在读取某数据的瞬间,必须先对其加行级共享锁,直到事务结束才释放;事务在更新某数据的瞬间,必须先对其加行级排他锁,直到事务结束才释放; 为了防止幻读,还会有间隙锁进行区间排它锁定。
然后是MVCC,多版本并发控制,主要是为了实现可重复读,虽然锁也可以,但是为了更高性能考虑,使用了这种多版本快照的方式。
因为是快照,所以一个事务针对同一条Sql查询语句的结果,不会受其它事务影响。

MySQL为什么用树做索引?


一般而言,能做索引的,要么Hash,要么树,要么就是比较特殊的跳表。Hash不支持范围查询,跳表不适合这种磁盘场景,而树支持范围查询,且多种多样,很多树适合磁盘存储。所以MySQL选择了树来做索引。

MySQL锁的分类吧。


MySQL从锁粒度粒度上讲,有表级锁、行级锁。从强度上讲,又分为意向共享锁、共享锁、意向排它锁和排它锁。


间隙锁就是对索引行进行加锁操作,不仅锁住其本身,还会锁住周围邻近的范围区间。间隙锁的目的是为了解决幻影读,但也因此带来了更大的死锁隐患。
比如,一个任务表里面有个状态字段,是一个非唯一索引,有一个任务id,是唯一索引。 一个sql将状态处于执行中的任务设置为等待中,另一个sql正好通过任务id更新在范围内的一条任务信息。那么因为是在不同索引加锁的,所以都能成功。但是最后去更新主键数据的时候,就会死锁。

那要怎么找到MySQL执行慢的语句呢?


我们可以看慢查询日志,它是MySQL提供的一种日志记录,用来记录在MySQL中响应时间超过阀值的语句,这个阈值通常默认为10s,也可以按需配置。
Mysql是默认关闭慢查询日志的,所以需要我们手动开启。set global slow_query_log=1


那找到慢语句之后,怎么查看它的执行计划?


使用explain命令,它可以获取到MySQL语句的执行计划 ,包括会使用的索引、扫描行数、表如何连接等信息。 通过这个命令,我们很容易就看出一条语句是否使用了我们预期的索引,并进行相应的调整。

 MySQL如果查询压力太大该怎么办?


如果SQL语句已经足够优秀。那么就看请求压力是否符合二八原则,也就是说80%的压力都集中在20%的数据。 如果是,我们可以增加一层缓存,常用的实现是在MySQL前加个Redis缓存。当然,如果实在太大了,那么只能考虑分库分表啦。


如果是写入压力太大呢?


写缓冲。一般而言可以增加消息队列来缓解。这样做有两个好处,一个是缓解数据库压力,第二个可以控制消费频率。

如果发现线上Insert导致cpu很高,你会怎么解决?


1.查看是不是请求量突然飙升导致,如果是攻击,则增加对应的防护;
2.查看是否因为数据规模达到一个阈值,导致MySQL的处理能力发生了下降;
3.查看二级索引是否建立过多,这种情况需要去清理非必要索引。

Count操作的性能怎么优化?


第一种,是用Redis缓存来计数。每次服务启动,就将个数加载进Redis,这种方案适用于对数据精确度,要求不是特别高的场景。
第二种,为count的筛选条件建立联合索引。这样可以实现索引覆盖,在二级索引表中就可以得到结果,不用再回表,回表可是O(n)次随机I/O呢。这种方案适用于有where条件的情况,并且与其它方案不冲突,可共同使用。 第三种,可以多维护一个计数表,通过事务的原子性,维持一个准确的计数。这种方案适用于对数据精度高,读多写少场景。
你对MySQL分表有了解吗?
随着业务持续扩张,单表性能一定会达到极限,分表是把一个数据库中的数据表拆分成多张表,通过分布式思路提供可扩展的性能。
那你做过的项目中,分表逻辑怎么实现的?
分表逻辑一定是在一个公共的,可复用的位置来实现。我之前做的项目,是实现了一个本地依赖包,即将分表逻辑写在公共的代码库里,每个需要调用服务的客户方都集成该公共包,就接入了自动分表的能力。 优点在于简单,不引入新的组件,不增加运维难度。缺点是公共包更改后每个客户端都需要更新。

如果初期没做分表,已有3000W数据,此时要分库分表怎么做?


最复杂的情况,持续比较大的访问流量下,并且要求不停服。我们可以分几个阶段来操作:
1. 双写读老阶段:通过中间件,对write sql同时进行两次转发,也就是双写,保持新数据一致,同时开始历史数据拷贝。本阶段建议施行一周;
2. 双写双读阶段:采用灰度策略,一部分流量读老表,一部分流量读新表,读新表的部分在一开始,还可以同时多读一次老表数据,进行比对检查,观察无误后,随着时间慢慢切量到新表。本阶段建议施行至少两周; 3. 双写读新阶段:此时基本已经稳定,可以只读新表,为了安全保证,建议还是多双写一段时间,防止有问题遗漏。本阶段建议周期一个月; 4. 写新读新阶段:此时已经完成了分表的迁移,老表数据可以做个冷备;

MySQL都有哪些锁?举出所有例子,各个锁的作用是什么?区别是什么?
1.从数据操作的类型分类
共享锁(S锁):也称为读锁,对于其他事务而言是可读不可写的。多个事务可以同时持有共享锁,并且共享锁之间不会互斥。
排他锁(X锁):也称写锁,对于其他事务而言是不可读也不可写的,确保在多个事务中,对同一资源,只有一个事务能写入,并防止其他用户读取正在写入的资源。
2.从锁的粒度分类
2.1 表锁(Table Lock)
锁定整张表。表锁又可分为:表级别的S锁和X锁、意向锁、元数据锁、自增锁
2.11 表级别的S锁和X锁
一般情况下,不会使用到InnoDB中提供的表级别的S锁和X锁,只会在一些特殊情况下,比方说崩溃恢复过程中用到;而在MyISM比较常用。
2.1.2 意向锁
假如有事务T1和T2,T1获取了某表中最后一行记录的行锁(S锁),此时T2想加表锁(X锁),这是不允许的(S锁和X锁互斥),但是T2并不知道该表有没有加过行锁,需要一行一行的去检查,直到最后一行,效率非常低。但是如果有意向锁的话,T1获取行锁时,会额外加上表级别的意向锁,告诉其他事务该表已经有人加过锁了。此时T2只需要检查该表上是否有意向锁即可。
意向锁的作用就是加快表锁的检查过程。
意向锁是由存储引擎自己维护的 ,用户无法手动获取,在为数据行加共享/排他锁之前,InooDB会先获取该数据所在表的对应意向锁。意向锁可分为:
●意向共享锁(IS):事务有意向对表中的某些行加共享锁(S锁),会自动加上意向共享锁
●意向排他锁(IX):事务有意向对表中的某些行加排他锁(X锁),会自动加上意向排它锁
2.1.3 自增锁
表中有自增列时,插入记录会使用到自增锁,一个事务持有自增锁时,其他事务的插入语句会被阻塞。了解即可。
2.1.4 元数据锁
在对某个表执行一些诸如ALTER TABLE 、DROP TABLE这类的DDL语句时,其他事务对这个表并发执行诸如SELECT、INSERT、DELETE、UPDATE的语句会发生阻塞。同理,某个事务中对某个表执行SELECT、INSERT、DELETE、UPDATE语句时,在其他事务中对这个表执行DDL语句也会发生阻塞。这个过程其实是通过在server层使用一种称之为元数据锁(英文名: Metadata Locks ,简称 MDL)结构来实现的。
MDL主要是为了避免DML和DDL冲突,保证读写的正确性。
2.2 行锁
2.21 记录锁(Record Locks)
记录锁就是行级别的X锁和S锁,仅仅锁住一行记录,分S型记录锁和X型记录锁;
2.22 间隙锁(Gap Locks)
gap锁的提出仅仅是为了防止插入幻影记录而提出的,没有额外其他功能。
2.23 临键锁(Next-Key Locks)
InnoDB默认的锁就是Next-Key locks。
临键锁 = 记录锁 + 间隙锁
在可重复读隔离级别下默认加的行锁就是临键锁,防止幻读。但是有些时候InnoDB会将它优化为记录锁或间隙锁:
2.3全局锁
全局锁就是对整个数据库实例加锁。当你需要让整个库处于只读状态的时候,可以使用这个命令,主要是做全库逻辑备份;备份时应该锁定整个库,保证数据的完整性。
3.从锁的态度分类
分为悲观锁和乐观锁。需要注意的是,乐观锁和悲观锁并不是锁,而是锁的设计思想 。
1.悲观锁(Pessimistic Locking)
假设最坏的情况,每次操作数据都会加上锁,如行锁、表锁等,都是在做操作之前先上锁,当其他线程想要访问数据时,都需要阻塞挂起。Java中synchronized和ReentrantLock等独占锁就是悲观锁思想的实现。
2.乐观锁(Optimistic Locking)
乐观锁认为对同一数据的并发操作不会总发生,属于小概率事件,不用每次都对数据上锁,它不采用数据库自身的锁机制,而是通过程序来实现。
在程序上,我们可以采用版本号机制或者CAS机制实现。乐观锁适用于多读和冲突不激烈的应用类型,这样可以提高吞吐量。在Java中通过CAS实现的。
4.死锁
●直接进入等待,直到超时。这个超时时间可以通过参数innodb_lock_wait_timeout来设置。
●发起死锁检测,发现死锁后,主动回滚死锁链条中的某一个事务,让其他事务得以继续执行。将参数innodb_deadlock_detect设置为on ,表示开启这个逻辑。


一条sql更新的执行流程?

1.通过连接器建立连接;

2.解析SQL语句执行计划,交给执行器执行;

3.从磁盘加载page页到内存的buffer pool;

4.记录undolog日志,用于mvcc和回滚操作;

5.更新buffer pool的数据,记录page页的更改;

6.写入redo log,把redo log状态记为prepare;

7.记录bin log逻辑日志,用于主从同步和数据备份;

8.提交事务,将redo log状态改为commit;

MySQL的Server和引擎层有什么区别?为什么要分层?

连接层:用户与MYSQL服务进行TCP链接,校验用户身份,用户权限。

服务层:用户写的SQL语句会到服务层进行解析,生成语法树。优化SQL语句,生成执行计划。

引擎层:真正与磁盘进行交互,对数据进行存储和读取。

区别:

分层架构使得MySQL可以更加容易地扩展新的功能和服务。

MySQL可以更加高效地进行查询处理和事务管理。

MySQL有缓存机制吗?buffer pool和change buffer作用是什么?

Buffer Pool(缓冲池):

内存中以页(page)为单位缓存磁盘数据,减少磁盘IO,提升访问速度

缓冲池大小默认128M,独立的MySQL服务器推荐设置缓冲池大小为总内存的80%。主要存储数据页、索引页更新缓冲(change buffer)等

Change Buffer(写缓冲)

如果每次写操作,数据库都直接更新磁盘中的数据,会很占磁盘IO。为了减少磁盘IO,

InnoDB在Buffer Pool中开辟了一块内存,用来存储变更记录,为了防止异常宕机丢失缓存,

当事务提交时会将变更记录持久化到磁盘(redo log),等待时机更新磁盘的数据文件(刷脏),

用来缓存写操作的内存,就是Change Buffer

Change Buffer默认占Buffer Pool的25%,最大设置占用50%:


http://www.ppmy.cn/server/145095.html

相关文章

基于YOLOv8深度学习的智慧课堂教师上课行为检测系统研究与实现(PyQt5界面+数据集+训练代码)

随着人工智能技术的迅猛发展,智能课堂行为分析逐渐成为提高教学质量和提升教学效率的关键工具之一。在现代教学环境中,能够实时了解教师的课堂表现和行为,对于促进互动式教学和个性化辅导具有重要意义。传统的课堂行为分析依赖于人工观测&…

使用 OpenCV 进行视频中的行人检测

在计算机视觉领域,行人检测是一个重要的研究方向,它在视频监控、自动驾驶、人机交互等领域都有着广泛的应用。本文将介绍如何使用 OpenCV 库来实现视频中的行人检测。 环境准备 首先,我们需要安装 OpenCV 库。可以通过以下命令来安装&#…

react 中解决 类型“never”上不存在属性“value”。

在 React 中,当你使用 useState 钩子来管理状态时,TypeScript 会尝试推断你的状态变量的类型。在你的例子中,listchannel 被初始化为一个空数组,因此 TypeScript 推断出 listchannel 的类型是 never[],即一个空数组类型…

跨境出海安全:如何防止PayPal账户被风控?

今天咱们聊聊那些让人头疼的事儿——PayPal账户被风控。不少跨境电商商家反馈,我们只是想要安安静静地在网上做个小生意,结果不知道为什么,莫名其妙账户就被冻结了。 但其实每个封禁都是有原因的,今天就来给大家分享分享可能的原…

即时通讯平台-音视频即时通讯平台就选WorkPlus

在现代社会,企业和组织对沟通的需求日益增加,尤其是在瞬息万变的商业环境中,音视频即时通讯已成为沟通的主流形式。WorkPlus作为一款专注于音视频即时通讯的平台,凭借其强大的功能和出色的用户体验,成为了企业和团队的…

ajax基础

一:express框架 在终端输入nodejs文件名 // 引入express const express require(express); //创建应用对象 const app express(); //创建路由规则 app.get(/,(request,response) > {//设置响应response.send(Hello Express); }); // 监听3000端口 app.lis…

云网络基础- TCP/IP 协议

文章目录 典型服务模式TCP/IP 协议设置和查看IPIP地址的分类:IP地址组成: 网络位主机位组成克隆:产生一台新的虚拟机win2008 典型服务模式 • C/S,Client/Server架构 – 由服务器提供资源或某种功能 – 客户机使用资源或功能 TCP/IP 协议 • TCP/IP是最广泛支持的通信协议集合…

CPU性能优化--skylake 微架构事件编码示例

Event 事件 编码 Umask 掩码值 事件掩码助记符 描述 C0H 00H INST_RETIRED.ANY_P 退休的指令数量 C4H 00H BR_INST_RETIRED 退休的分支跳转指令 linux perf提供常用性能计数器的映射,可以通过映射的事件名称来访问,而不是指定Event 和Umask十六进制值。…