MySQL面试复习1
来源:SegmentFault
2023-02-23 12:40:07
0浏览
收藏
本篇文章主要是结合我之前面试的各种经历和实战开发中遇到的问题解决经验整理的,希望这篇《MySQL面试复习1》对你有很大帮助!欢迎收藏,分享给更多的需要的朋友学习~
1.MySQL工作流程
- 客户端发送请求到连接器(授权认证处理)
- 认证通过后:请求被转发到查询分析器(查询、解析、优化、缓存等等)
- 查询缓存中如果存在数据直接返回,否则将请求再次转发给优化器(存储过程、触发器、视图等等)
- 然后将请求转发给执行器调用存储引擎(存储和提取数据)
- 最终所有数据根据本地文件系统存储在磁盘(内存)上
2.ACID特性
- 事务:访问和更新数据库的执行单元,包含着一个或多个SQL语句
-
标准SQL事务需要满足的特性:
- 原子性:事务是不可分割的最小执行单元,事务中的SQL语句只会全部执行成功或全部不执行
- 一致性:事务执行前后数据保持一致性,其他事务对同一个数据的访问结果是一致的
- 隔离性:并发访问数据库时,一个用户的事务不会被其他事务影响,并发事务之间是隔离的
- 持久性:事务被提交之后,发生任何情况,数据库中数据的改变是持久的
3.事务隔离级别
3-1.脏读/不可重复读/幻读
- 脏读:A事务能够读取其他事务的修改(update/delete/insert)操作
- 不可重复读:A事务能够读取其他事务已经提交的update/delete操作(同一条SQL查询读到不同的结果)
- 幻读: A事务能够读取其他事务已经提交的insert操作(同一条SQL查询读到多余结果)
3-2.标准的事务隔离级别
- 未提交读:允许读取其他未提交事务的数据变更(存在脏读/不可重复读/幻读问题)
- 提交读(不可重复读):允许读取其他已提交事务的数据变更(还存在不可重复读/幻读问题)
- 可重复读:不允许读取其他已提交事务的数据变更(还存在幻读问题)
- 可串行化:所有操作串行化,读加读锁,写加写锁,读写锁互斥(解决幻读问题)
3-3.实验现象
- 提交读相关实验
| A事务 | B事务 |
|---|---|
| begin; | begin; |
| update操作A记录的时候 | delete/update操作A记录时会等待锁释放而超时;select操作A记录时看不到更改后的数据 |
| commit(释放锁) | |
| delete/update操作A记录正常;select操作A记录时能看到更改后的数据 |
在RC级别下:当A事务进行update操作A记录时,为了并发操作过程中的冲突,会给A记录加锁并且如果没有commit时,B事务delete/update操作都会超时,但解决脏读问题;当A事务提交后,select操作存在不可重复读问题;当然如果A事务进行insert操作,B事务很容易通过select操作读到多余记录,没有任何办法`
- 可重复读相关实验
| A事务 | B事务 | C事务 |
|---|---|---|
| begin; | begin; | begin; |
| select操作1:查询到A和B两条记录 | ||
| update操作A记录 | ||
| commit; | ||
| insert操作C记录 | ||
| commit; | ||
| select操作1:同一条语句;没有读取到更新记录和插入记录 |
在INNODB存储引擎中的现象:同一条select查询读不到B事务的更新删除操作(因为读取的记录被加锁,其他事务无法执行更新删除操作),这样意味着解决了不可重读问题;也读取不到C事务添加操作,也解决了幻读问题(但是仅仅通过常规锁机制是无法阻止Insert操作的);所以在非INNODB存储引擎中都是采用串行化去解决幻读问题。`
- 以上是悲观锁的实现机制,但是为了减少开销,更多情况下会依赖于乐观锁的MVCC(多版本并发控制)来避免以上问题
4.多版本并发控制
4-1.悲观锁和乐观锁
- 悲观锁:假定大概率会发生并发更新冲突,访问和处理过程中都会加排他锁,整个事务过程中锁定数据,只有当事务提交或者回滚后才释放锁
- 乐观锁:假定大概率不会发生并发更新冲突,访问和处理数据过程中不加锁,只在更新数据时再根据版本号和时间戳判断是否有冲突(版本号不一致),有则处理,无则提交事务
4-2.MVCC
- MVCC(多版本并发控制)优点:读不加任何锁,读写不冲突,对于读操作多于写操作的应用,极大的增加了系统的并发性能;
-
MVCC:通过在每一行记录后面添加一个系统Version号(创建标识和删除标识),每开启新事务时系统Version号就自增1,然后将自增后的系统Version号作为当前事务的Version号,用来和查询到的每一行记录的系统Version号进行比较
-
Select操作:只有满足以下2个条件的记录才能返回作为查询结果
- 记录的创建Version号小于等于事务Version号的数据行;
- 记录的删除Version号未定义或者大于事务Version号的数据行;
- Insert操作:保存当前事务Version号作为该数据行的创建Version号
- Delete操作:保存当前事务Version号作为该数据行的删除Version号
- Update操作:插入一条新纪录,保存当前事务Version号为行创建Version号,同时保存当前事务Version本号到原来的行作为删除Version号
-
- 提交事务:准备更新数据的时候,会将记录的系统Version号加1与数据库的系统Version对比,如果大于给予更新处理,否则认为是过期数据。
5.当前读和快照读
- 当前读:即加锁读,读取记录的最新版本,会加锁保证其他并发事务不能修改当前记录,直至获取锁的事务释放锁
- 快照读:即不加锁读,读取记录的快照版本而非最新版本,通过MVCC实现
InnoDB默认的RR事务隔离级别下,不显式加『lock in share mode』与『for update』的『select』操作都属于快照读,保证事务执行过程中只有第一次读之前提交的修改和自己的修改可见,其他的均不可见;但我们读到的数据可能是历史数据,是不及时的数据,不是数据库当前的数据!这在一些对于数据的时效特别敏感的业务中,就很可能出问题。
- 事务的隔离级别实际上都是定义了当前读的级别,MySQL为了减少锁处理(包括等待其它锁)的时间,提升并发能力,引入了快照读的概念,使得select不用加锁。而update、insert这些“当前读”,就需要另外的模块来解决了
6.锁机制
-
InnoDB主要实现了三种行锁算法:
- Record Lock:记录锁,锁定一个行记录
- Gap Lock:间隙锁,锁定一个区间
- Next-key Lock:Record Lock+Gap Lock,锁定行记录+上下区间
- 不可重复读情况下:如果A事务select“当前读”操作(会给查询到的数据+记录锁),当B事务Insert新数据后,A事务再次执行相同条件的select“当前读”操作,是可能发现多余的数据,这就是“当前读”的幻读
- 可重复读情况下:如果A事务select“当前读”操作(会给查询到的记录+记录锁+间隙锁),当B事务Insert新数据后(如果在间隙空间中)会进行Waiting,此时A事务再次执行相同条件的select“当前读”操作, 是不可能发现多余的数据,这就解决了“当前读”的幻读问题。
- 间隙区间:根据不同的索引类型(数据结构)范围性扫描的索引和记录而确定的,如果没有Gap Lock,RR级别下是可以随意Insert的,从而导致“当前读”的幻读问题......
- 当前读下:行锁防止update/delete操作,GAP锁防止Insert操作,Next-Key锁解决了在RR级别下写数据时的幻读问题
- 我可以理解为:Gap锁解决一致性读问题;Next-Key锁解决一致性写问题吗?
参考
- 博客1:https://segmentfault.com/a/1190000014133576
- 博客2:https://www.cnblogs.com/csniper/p/5525477.html
- 推荐书籍:《MySQL技术内幕:InnoDB存储引擎》[3遍应该才会有收获吧]
好了,本文到此结束,带大家了解了《MySQL面试复习1》,希望本文对你有所帮助!关注golang学习网公众号,给大家分享更多数据库知识!
版本声明
本文转载于:SegmentFault 如有侵犯,请联系study_golang@163.com删除
墨天轮数据库周刊—第12期
- 上一篇
- 墨天轮数据库周刊—第12期
- 下一篇
- Mysql:Explain关键字
查看更多
最新文章
-
- 数据库 · MySQL | 1小时前 | MySQL · 数据类型 · JSON · SQL排错 · MEMBER OF · MySQL MEMBER OF MySQL JSON 数组成员判断 MEMBER OF 类型不匹配 JSON 数字字符串区别 MySQL JSON 查询
- MySQL MEMBER OF 判断 JSON 数组成员时为什么类型不匹配
- 167浏览 收藏
-
- 数据库 · MySQL | 3小时前 | MySQL · 数据库查询 · JSON 函数 · SQL 边界 · JSON 数组 · JSON_CONTAINS MySQL JSON_OVERLAPS JSON 数组相交 MySQL JSON 类型比较 MySQL NULL 边界
- MySQL JSON_OVERLAPS 判断两个数组相交时有哪些边界
- 130浏览 收藏
-
- 数据库 · MySQL | 4小时前 |
- MySQL JSON_VALUE 返回数字类型时如何避免字符串比较
- 418浏览 收藏
-
- 数据库 · MySQL | 5小时前 |
- MySQL 默认表达式引用其他列为什么无法创建表
- 410浏览 收藏
-
- 数据库 · MySQL | 6小时前 | MySQL · 数据校验 · 数据库约束 · 约束 MySQL CHECK
- MySQL CHECK 约束写入非法值时为什么没有报错
- 452浏览 收藏
-
- 数据库 · MySQL | 8小时前 |
- MySQL EXISTS 和 IN 遇到 NULL 条件时有什么区别
- 425浏览 收藏
-
- 数据库 · MySQL | 9小时前 |
- MySQL GROUP_CONCAT 如何按排序规则拼接稳定结果
- 488浏览 收藏
-
- 数据库 · MySQL | 11小时前 | SQL查询 · group by · MySQL教程 · mysql group by ONLY_FULL_GROUP_BY 函数依赖 ERROR 1055
- MySQL ONLY_FULL_GROUP_BY 遇到函数依赖时如何改写查询
- 440浏览 收藏
-
- 数据库 · MySQL | 1天前 | MySQL · DDL · InnoDB · mysql innodb ALGORITHM=INSTANT Instant DDL
- Instant DDL 表结构限制怎么配置或排查
- 486浏览 收藏
查看更多
课程推荐
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
查看更多
AI推荐
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 25次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 130次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 57次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 22次使用
-
- OpenCompass
- OpenCompass是上海AI实验室推出的开源大模型评测平台,提供CompassKit、CompassHub和CompassRank三大核心组件,支持LLM及多模态模型的一站式标准化评估与排行榜查询。
- 80次使用
查看更多
相关文章
-
- MySQL 明明加了索引,为什么查询还是很慢?先查这 6 个点
- 2026-06-27 374浏览
-
- golang MySQL实现对数据库表存储获取操作示例
- 2022-12-22 499浏览
-
- golang 基于 mysql 简单实现分布式读写锁
- 2023-01-07 384浏览
-
- 详解如何利用GORM实现MySQL事务
- 2023-01-07 184浏览
-
- Go语言实现操作MySQL的基础知识总结
- 2023-01-23 265浏览

