MySQL面试-1

news2024/11/25 11:37:10

 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.coloradmin.cn/o/2247264.html

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

相关文章

使用树莓派安装shairport-sync使老音响变身AirPlay音响

借助shairport-sync,可以让普通音响变成AirPlay无线音响,由于树莓派天生的低功耗,做这种事情最适合。所以架构就是树莓派安装Ubuntu24.04,在树莓派上安装shairport-sync,树莓派再通过3.5mm线连接音响。 安装Ubuntu24.…

Linux---ps命令

​​​​​​Linux ps 命令 | 菜鸟教程 (runoob.com) process status 用于显示进程的状态 USER: 用户名,运行此进程的用户名。PID: 进程ID(Process ID),每个进程的唯一标识号%CPU: 进程当前使用的CPU百分比%MEM: 进程当前使用的…

VLAN是什么,一个好的网络为什么要划分VLAN呢?

前言 在上一篇中讲解了交换机的工作原理,知道了交换机处理数据的转发方式,其中有两种情况会以广播方式进行发送数据,第一种是目的MAC是全F的,以及组播MAC,第二种是未知单播帧,那这个会带来什么样的问题呢&…

衡山派D133EBS 开发环境安装及SDK编译烧写镜像烧录

1.创建新文件夹,用来存放SDK包(其实本质就是路径要对就ok了),右键鼠标通过Open Git Bash here来打开git 输入命令 git clone --depth1 https://gitee.com/lcsc/luban-lite.git 来拉取,如下所示:&#xff0…

基于Gradle搭建Spring6.2.x版本源码阅读环境

前言 阅读源码是程序猿成长的必经一环,正所谓知其然知其所以然。我们在开发成长道路上不仅需要知道如何使用,更要懂得其背后的原理,如此方可得心应手。本篇文章旨在指导大家搭建Spring6.0以上版本的源码阅读环境,方便大家在学习源…

C++自动化测试:GTest 与 GitLab CI/CD 的完美融合

在现代软件开发中,自动化测试是保证代码质量和稳定性的关键手段。对于C项目而言,自动化测试尤为重要,它能有效捕捉代码中的潜在缺陷,提高代码的可维护性和可靠性。本文将重点介绍如何在C项目中结合使用Google Test(GTe…

ubuntu16.04在ros使用USB摄像头-解决could not open /dev/video0问题

首先检查摄像头 lsusb 安装 uvc camera 功能包 sudo apt-get install ros-indigo-uvc-camera 安装 image 相关功能包 sudo apt-get install ros-kinetic-image-* sudo apt-get install ros-kinetic-rqt-image-view运行 uvc_camera 节点 首先输入roscore 然后另外开一个终端输入…

Linux:文件管理(二)——文件缓冲区

目录 一、缓冲区概念 二、缓冲区刷新机制 三、用缓冲区刷新解释下面现象。 一、缓冲区概念 缓冲区,本质就是一块内存区域。 设计缓冲区就是为了让本来要一次一次传的数据,都暂时传到缓冲区,让缓冲区刷新一次,这样只发生了一次传…

PH热榜 | 2024-11-24

DevNow 是一个精简的开源技术博客项目模版,支持 Vercel 一键部署,支持评论、搜索等功能,欢迎大家体验。 在线预览 1. AutoFlow Studio 标语:借助简化的AI质检,更快发布产品,更聪明地进行测试。 介绍&…

hubuctf-2024校赛-复现wp

web easyweb1 <?php error_reporting(0); highlight_file(__FILE__);$flag getenv("GZCTF_FLAG");if(isset($_GET[num])){$num $_GET[num];if(preg_match("/[0-9]/", $num)){die("You are failed.");}if(intval($num)){echo $flag;} } 利…

飞书会话消息左右排列

飞书会话消息左右排列 1. 飞书登录后&#xff0c;点击头像&#xff0c;弹出菜单有个按钮设置 2. 3.

《图像形态学运算全解析:原理、语法及示例展示》

简介&#xff1a; 本文详细介绍了图像形态学中的多种运算&#xff0c;包括腐蚀、膨胀、开运算、闭运算、形态学梯度运算、礼帽运算以及黑帽运算。分别阐述了各运算的原理、语法格式&#xff0c;并通过 Python 代码结合具体示例图片&#xff08;如erode.JPG、dilate.JPG、close.…

链路聚合实验

1、聚合方式 &#xff08;1&#xff09;、lacp 静态链路聚合、 动态链路聚合&#xff08;开启lacp模式&#xff0c;常用&#xff09; &#xff08;2&#xff09;、手工负载分担 静态端口聚合&#xff08;两台交换机都按照下面的命令配置&#xff09; <H3C>sys System Vi…

电子电气架构 -- ASIL D安全实现策略

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 所有人的看法和评价都是暂时的&#xff0c;只有自己的经历是伴随一生的&#xff0c;几乎所有的担忧和畏惧…

禁止Chrome的自动升级

一、需求分析 因为用Chromeselenium做了网页自动化填写任务&#xff0c;如果Google Chrome浏览器自动升级&#xff0c;就会导致chromedriver加载失败&#xff0c;自动化任务失效&#xff0c;因此需要禁止Chrome浏览器的自动升级。 二、当前环境 三、实际配置 运行注册表编辑…

C0034.在Ubuntu中安装的Qt路径

Qt安装路径查询 在终端输入qmake -v如上中/usr/lib/x86_64-linux-gnu就是Qt的安装目录&#xff1b;

C++从零到满绩——类和对象(中)

目录 1>>前言 2>>构造函数&#xff08;我称之为初始化函数&#xff09; 3>>析构函数&#xff08;我称之为销毁函数&#xff09; 4>>拷贝构造函数&#xff08;我称之为复制函数&#xff09; 5>>运算符重载 5.2>>赋值运算符重载 ​编辑…

oracle 12c查看执行过的sql及当前正在执行的sql

V$SQL 提供了已经执行过及正在执行的SQL语句的信息。 一 查看共享池中所有sql的统计信息 #统计共享池中某类sql执行次数&#xff0c;总体执行时长&#xff0c;平均执行时长等信息&#xff0c;并按总体执行时长降序排序 SELECT INST_ID,SQL_ID,SQL_TEXT,SQL_FULLTEXT,EXECUTI…

解锁PPTist的全新体验:Windows系统环境下本地部署与远程访问

文章目录 前言1. 本地安装PPTist2. PPTist 使用介绍3. 安装Cpolar内网穿透4. 配置公网地址5. 配置固定公网地址 前言 在Windows系统环境中&#xff0c;如何本地部署开源在线演示文稿应用PPTist&#xff0c;并实现远程访问&#xff1f;本文将为您提供详细的部署和配置指南。 P…

C语言中的指针和字符串的赋值

前言&#xff1a;温习下以前学过的C语言知识&#xff0c;温故而知新。 实例说明 本文用一段实例代码阐述指针和字符串的联系。 #include <iostream> #include <cstring> int main() {using namespace std;char animal[20] "bear";const char * bird …