MySQL的底层原理与架构

前言

了解MySQL的架构和原理对于很多的后续很多的操作会有很大的帮助与理解。并且很多知识都与底层架构相关联。

了解MySQL架构

通过上面的架构图可以得知,Server层中主要由 连接器、查询缓存、解析器/分析器、优化器、执行器 几部分组成的,下面将主要描述下这几部分。

1、连接器:

客户端想要对数据库进行操作时,前提是与数据库建立好连接;而连接器就是用来负责跟客户端建立连接、获取权限、维持和管理连接的。

(1)连接方式:

MySQL既支持短连接,也支持长连接。短连接就是操作完毕后,马上close关掉。长连接可以保持打开,减少服务端创建和释放连接的消耗,后续程序访问的时候还可以使用这个连接。

(2)连接池:

与客户端的连接池一样,为了减少频繁创建和销毁连接造成的不必要的性能损失,这里也采用了“池化”的思想,通过数据库连接池去管理连接。一般我们会在连接池中使用长连接,例如:druid、c3p0、dbcp等

2、查询缓存:

MySQL缓存是默认关闭的,也就是说不推荐使用缓存,并且在 MySQL 8.0 版本直接将查询缓存的整块功能删掉了。因为缓存中的格式是kye(sql),value(数据)的方式保存的,如果SQL只要有一点不同那么就不会走缓存。其次是表中的数据很多时候都是会变化的,而数据变化了那么缓存也就没有意义。

3、分析/解析器:

分析器的工作主要是对要执行的SQL语句进行解析,最终得到抽象语法树,然后再使用预处理器判断抽象语法树中的表是否存在,如果存在的话,在接着判断select投影列字段是否在表中存在等。

(1)词法分析:

词法分析用于将SQL拆解为不可再分的原子符号,称为Token。并根据不同数据库方言所提供的字典,将其归类为关键字,表达式,字面量和操作符。

(2)语法分析:

语法分析就是根据词法分析拆解出来的Token(原子符号)将SQL语句转换为抽象语法树。

(3)预处理器:

预处理是用来对生成的 抽象语法树 进行语义校验,语义校验就是对查询的表、select投影列字段进行校验,判断表、字段是否存在等;

SELECT id, name FROM t_user WHERE status = ‘ACTIVE’ AND age > 18

以上述SQL为例,经过词法分析与语法分析后会得到的抽象语法树如下图。

4、优化器:

优化器的作用主要是将SQL经过词法解析/语法解析后得到的语法树,通过MySQL的数据字典和统计信息的内容,经过一系列运算 ,最终得出一个执行计划,包括选择使用哪个索引。

在优化过程中,经过的一系列运算是什么呢?

(1)逻辑变换:例如SQL的where条件中存在 8>9,那逻辑转换就是将语法树中存在的这种常量表达式直接进行化简,化简为 false;除了化简还有常量表达式计算等。

(2)代价优化:就是通过付出一些数据统计分析的代价,来得到这个SQL执行是否可以走索引,以及走哪些索引;除此之外,在多表关联查询中,确定最终表join的顺序等

在分析是否走索引查询时,是通过进行动态数据采样统计分析出来;只要是统计分析出来的,那就可能会存在分析错误的情况,所以在SQL执行不走索引时,也要考虑到这方面的因素

5、执行器:

MySQL 通过分析器知道了你要做什么,通过优化器知道了该怎么做,于是就进入了执行器阶段,开始执行语句。执行器最终就是根据一系列的执行计划去调用存储引擎提供的API接口去调用操作数据,完成SQL的执行

开始执行的时候,要先判断一下建立连接的对象对这个表有没有执行操作的权限,如果没有,就会返回没有权限的错误;如果有,就按照生成的执行计划进行执行。

InnoDB存储引擎:

存储引擎是对底层物理数据执行实际操作的组件,为Server服务器层提供各种操作数据的 API,数据是被存放在内存或者是磁盘中的。MySQL 支持插件式的存储引擎,包括 InnoDB 、MyISAM、Memory 等。一般情况下,MySQL默认使用的存储引擎是 InnoDB。如下图所示,InnoDB存储引擎整体分为内存架构(Memory Structures)和磁盘架构(Disk Structures)

1、Buffer Pool:

Buffer Pool (缓冲池)是 InnoDB 存储引擎中非常重要的内存结构,类似 Redis 一样的作用,起到一个缓存的作用。MySQL 的数据最终是存储在磁盘中的,如果没有 Buffer Pool,那么每次的数据库请求都会磁盘中查找,这样必然会存在 IO 操作。但是有了 Buffer Pool,在第一次查询时就会将查询的结果保存到 Buffer Pool 中,这样后面再有请求时就会先从缓冲池中去查询如果没有再去磁盘中查找,然后在放到 Buffer Pool 中,如下图:

UPDATE students SET stuName = ‘小强’ WHERE id = 1

以上述SQL为例,那么它的执行顺序大致如下

  • (1)innodb 存储引擎先在缓冲池中查找 id=1 的这条数据是否存在
  • (2)如果缓存不存在,那么就去磁盘中加载,并将其存放在缓冲池中
  • (3)该条记录会被加上一个独占锁

**??**buffer pool 和 前面提到的查询缓存的区别:

(1)查询缓存:查询缓存位于Server层,MySQL Server首选会从查询缓存中查看是否曾经执行过这个SQL,如果曾经执行过的话,之前执行的查询结果会以Key-Value的形式保存在查询缓存中。key是SQL语句,value是查询结果。我们将这个过程称为查询缓存!

(2)Buffer Pool位于存储引擎层Buffer Pool就是MySQL存储引擎为了加速数据的读取速度而设计的缓冲机制

2、undo log日志文件(回滚日志):记录数据被修改前的样子

Innodb 存储引擎的最大特点就是支持事务,如果事务提交失败,那么该事务中所有的操作都必须回滚到执行前的样子,而这个回滚的操作,就是利用 undo log文件完成的。

  • Undo Log用于实现事务的原子性和一致性,用于撤销事务对数据的修改

上面我们介绍了,在准备更新一条SQL语句的时候,该条语句对应的数据已经被加载到 Buffer pool 中了,实际上这里还有这样的操作,就是在将该条语句加载到 Buffer Pool 中的时候同时会往 undo log 日志文件中插入一条日志,也就是将 id=1 的这条记录的原来的值记录下来,便于事务失败后进行回滚

到这一步,我们执行的 SQL 语句对应的数据已经被加载到 Buffer Pool 中了,然后开始更新这条语句,更新的操作实际是在Buffer Pool中执行的。那问题来了,更新完数据之后,Buffer Pool缓冲池中的中的数据就会和数据库中的数据库不一致,那就是说Buffer Pool 中的数据成了脏数据?没错,目前这条数据就是脏数据,Buffer Pool 中的记录是“小强”数据库中的记录是“旺财” ,这种情况 MySQL是怎么处理的呢?我们接着往下看

3、redo log 日志文件(重做日志):记录数据被修改后的样子

redo 日志文件是 InnoDB 特有的,他是存储引擎级别的

  • Redo Log用于实现事务的持久性,用于在数据库异常崩溃时恢复数据的一致性。MySQL通过Undo Log和Redo Log的配合,确保了数据库的事务安全性和持久性。

该日志文件由两部分组成:重做日志缓冲(redo log buffer)以及重做日志文件(redo log file)前者是在内存中,后者在磁盘中。当事务提交之后会把所有修改信息都存到该日志文件中,用于在刷新脏页到磁盘,发生错误时,供数据恢复用。

除了从磁盘中加载文件和将操作前的记录保存到 undo 日志文件中之外,其他的操作是在内存中完成的,内存中的数据的特点就是:断电丢失。如果此时 MySQL 所在的服务器宕机了,那么 Buffer Pool 中的数据会全部丢失的。这个时候 redo log 日志文件就需要来大显神通了

redo 就是准备去做、将要去做的意思,redo log 记录的是将要做的一些操作。例如,此时将要做的是 update students set stuName=‘小强’ where id=1; 那么这条操作就会被记录到 redo log buffer 中,redo log buffer 是 MySQL 为了提高效率,所以将这些操作都先放在内存中去完成

这时候假设服务器宕机了,那么缓存中的数据还是丢失了。那能不能不要放在内存中,直接保存到磁盘呢?很显然不行,在内存中操作目的是为了提高效率。如果此时 MySQL 真的宕机了,那么没关系的,因为 MySQL 会认为本次事务是失败的,会利用 undo log 的日志信息进行回滚,并不会有任何的影响。

到了这里,SQL语句也更新好了,那么需要将更新的值提交了,也就是需要提交本次的事务,只要事务成功提交了,才会将最后的变更保存到数据库。在提交事务前会将 redo Log Buffer 中的数据写入到磁盘文件 redo log 中,进行持久化,而刷入磁盘的时机则是根据 innodb_flush_log_at_trx_commit 参数来决定的:

0:表示每次事务提交时都只是把redo log留在redo log buffer中,数据库宕机有可能会丢失数据。

1(默认值):每次事务提交时,都将redo log直接持久化到磁盘,数据最安全,不会因为数据库宕机丢失数据,但是效率稍微差一点,线上系统推荐设置

2:每次事务提交时都只把redo log写到操作系统的缓存page cache里,这种情况如果数据库宕机是不会丢失数据的(os cache里还有数据),但是如果操作系统宕机了,那么page cache里的数据还没来得及写入磁盘文件就有可能会丢失数据。

InnoDB有一个后台线程,每隔1秒就会把redo log buffer中的日志,调用操作系统函数write写到文件系统page cache,然后调用操作系统函数fsync持久化到磁盘文件中。

关于这个参数的设定,需要根据具体的项目以及业务场景来定,如果设置合理那么可以带来很大的性能提升。

redo log Buffer 刷入磁盘后,就完成了数据的持久化了,就算数据库宕机了,我们也可以再下次重启的时候将 redo log 日志文件的内容恢复到 Buffer Pool 中。

前面提到,如果每次修改都直接以落盘的形式处理,那么必定有大量的随机IO,如果使用机械磁盘更会存在大量的disk seek时间,数据库性能极低,那为什么写入 redo log 就能提高性能呢?这是因为写 redo log 至磁盘属于磁盘顺序写,只需 append log 到下一位置,所以 redo log 的落盘速度是非常快的

到此SQL语句的执行就如下

1.准备SQL语句

2.MySQL会先在Buffer pool(缓冲池)中进行查找需要的数据,如果没有那么就从磁盘中取出然后放到Buffer pool中进行操作

3.在加载到Buffer pool的同时,会将这条数据的原始记录加载到undo日志文件中。

4.在Buffer Pool中完成数据操作

5.更新后的数据会记录在Redo Log Buffer中,然后根据 innodb_flush_log_at_trx_commit 参数来决定什么时候将数据刷入磁盘文件redo log进行持久化

6.MySQL重启时会将redo log恢复到缓冲池中。

4、bin log日志文件:记录整个操作过程

前言:bin log 和 redo log 有些相似,两者的主要区别有:

(1)redo log是 InnoDB 存储引擎特有的日志文件,而 bin log属于是 MySQL 级别的日志

(2)redo log 适用于崩溃恢复,bin log 适用于主从复制和数据恢复

(3)redo log 记录的东西是偏向于物理性质的,如:“对什么数据,做了什么修改”。bin log是偏向于逻辑性质的,类似于:“对 students 表中的 id 为 1 的记录租了更新操作” 。

bin log文件是如何刷入磁盘的 bin log的刷盘策略可以通过 sync_bin log 来修改,默认为0,表示先写入 os cache,也就是说在提交事务的时候,数据不会直接到磁盘中,这样如果宕机 bin log 数据仍然会丢失。所以建议将sync_bin log设置为 1,表示直接将数据写入到磁盘文件中

既然 bin log 也是日志文件,那它是在什么时候记录数据的呢?其实 MySQL 在提交事务时,不仅会将 redo log buffer 中的数据写入到 redo log 文件中,也会将本次修改的数据记录到 bin log 文件中,同时会将本次修改的 bin log 文件名和修改的内容在 bin log 中的位置记录到 redo log 中,最后还会在 redo log 最后写入 commit 标记,这样就表示本次事务被成功的提交了

如果在数据在写入 bin log文件时,刚写完,数据库宕机了,数据会丢失吗?首先可以确定的是,只要 redo log 最后没有 commit 标记,说明本次的事务一定是失败的。但是数据是没有丢失的,因为已经被记录到 redo log 的磁盘文件了,在 MySQL 重启的时候,就会将 redo log 中的数据恢复(加载)到Buffer Pool中

到目前为止,一个更新操作基本介绍得差不多,但是你有没有感觉少了哪件事情还没有做?是不是你也发现这个时候被更新记录仅仅是在内存中执行的,哪怕是宕机又恢复了也仅仅是将更新后的记录加载到 Buffer Pool 中,这个时候 MySQL 数据库中的这条记录依旧是旧值,也就是说内存中的数据在我们看来依旧是脏数据,那这个时候怎么办呢?

其实 MySQL 会有一个后台线程,它会在某个时机将我们 Buffer Pool 中的脏数据刷到 MySQL 数据库中,这样就将内存和数据库的数据保持统一了。刷新脏页的时机如下:

(1)redo log 写满时,停止所有更新操作,将 checkpoint 向前推进,推进那部分日志的脏页更新到磁盘;

(2)需要将一部分数据页淘汰,如果是干净页,直接淘汰就行了,脏页的话,需要全部同步到磁盘;

(3)mysql自认为空闲时

(4)mysql正常关闭之前

关于图中的OS cache是操作系统中内存中的一块区域,为了提升应用的写入磁盘的性能解决内存和磁盘交互的性能瓶颈。很多应用如kafka、MQ等写入硬盘的操作那么就把os cache当做硬盘来写入,提升性能。

总结

(1)首先 MySQL 执行器根据执行计划调用存储引擎的API查询数据

(2)存储引擎先从缓存池 buffer pool 中查询数据,如果没有就会去磁盘中查询,如果查询到了就将其放到缓存池中

(3)在数据加载到 Buffer Pool 的同时,会将这条数据的原始记录保存到 undo log 日志文件中

(4)innodb 会在 Buffer Pool 中执行更新操作

(5)更新后的数据会记录在 redo log buffer 中

(6)提交事务在提交的同时会做以下三件事

(7)(第一件事)将 redo log buffer 中的数据刷入到redo log文件中

(8)(第二件事)将本次操作记录写入到 bin log 文件中

(9)(第三件事)将bin log文件名字和更新内容在 bin log 中的位置记录到redo log中,同时在 redo log 最后添加 commit 标记

(10)使用一个后台线程,它会在某个时机将我们Buffer Pool中的更新后的数据刷到 MySQL 数据库中,这样就将内存和数据库的数据保持统一了

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

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

相关文章

自动化测试工具selenium的安装踩坑

先安装Python 然后pip install selenium 浏览器安装驱动 火狐版本:132.0 geckodriver应用W3C WebDriver兼容远程服务器与根据gecko的浏览器互动的代理,该程序流程出示WebDriver协议书叙述的HTTP API,用以与Gecko浏览器(如Firefox)通讯 下…

apisix网关ip-restriction插件使用说明

ip-restriction插件可以在网关层进行客户端请求ip拦截。 当然了,一般不推荐使用该方法,专业的事专业工具做。建议有条件,还是上防火墙或者waf来做。 官方文档:ip-restriction | Apache APISIX -- Cloud-Native API Gateway whit…

Baklib赋能数字内容体验个性化推荐提升用户体验的未来之路

内容概要 随着数字化时代的不断发展,用户对内容消费的需求日益多样化,个性化推荐成为提升用户体验的重要手段。Baklib以其先进的技术手段,在数字内容领域内积极推动个性化推荐的实施,从而满足用户在信息获取和内容消费中的独特需…

【SqlServer】SQL Server Management Studio (SSMS) 下载、安装、配置使用及卸载——保姆级教程

超详细的 SQL Server Management Studio (SSMS) 下载、安装、连接数据库配置及卸载教程 SQL Server Management Studio (SSMS) 是微软提供的图形化管理工具,主要用于连接、管理和开发 SQL Server 数据库。以下是详细的 SSMS 下载、安装、连接数据库以及卸载的完整教…

【慕伏白教程】Zerotier 连接与简单配置

文章目录 下载与安装 WindowsLinux apt安装官方脚本安装 Zerotier 配置 新建网络网络配置 终端配置 WindowsLinux 下载与安装 Windows 进入Zerotier官方下载网站,点击下载 在下载目录找到安装文件,双击打开后点击 Install 开始安装 安装完成后&…

BUU22 [护网杯 2018]easy_tornado 1

打开题目以后出现三个文件,查看源代码,突破口在于这三个文件都有特殊的格式 python的tornado漏洞 Tornado 是一个用 Python 编写的 Web 框架(和flask一样,只不过flask是轻量级的,而tornado可以处理高流量&#xff09…

Windows Docker笔记-Docker拉取镜像

通过在前面的章节《安装docker》中,了解并安装成功了Docker,本章讲述如何使用Docker拉取镜像。 使用Docker,主要是想要创建并运行Docker容器,而容器又要根据Docker镜像来创建,那么首当其冲,必须要先有一个…

接入 deepseek 实现AI智能问诊

1. 准备工作 注册 DeepSeek 账号 前往 DeepSeek 官网 注册账号并获取 API Key。 创建 UniApp 项目 使用 HBuilderX 创建一个新的 UniApp 项目(选择 Vue3 或 Vue2 模板)。 安装依赖 如果需要在 UniApp 中使用 HTTP 请求,推荐使用 uni.requ…

攻防世界 文件上传

题目名称-文件包含 今天的题大概提一下解题思路就好了 这里要使用php://filter 在此基础上因为网页过滤了一些关键字 我们要进行爆破 UCS-4* UCS-4BE UCS-4LE* UCS-2 UCS-2BE UCS-2LE UTF-32* UTF-32BE* UTF-32LE* UTF-16* UTF-16BE* UTF-16LE* UTF-7 UTF7-IMAP UTF-8* ASCII…

胜任力冰山模型:深入探索职业能力的多维结构

目录 1、序言 2、什么是胜任力? 3、任职资格和胜任力的区别 4、胜任力冰山模型:职场能力的多维展现 4.1、冰山水面上的部分 4.2、冰山水面下的部分 4.3、深层的个人特质与价值观 5、如何平衡任职资格与胜任能力 6、结语 1、序言 在快速发展的I…

在 Flownex 中创建自定义工作液

在这篇博文中,我们将了解如何在 Flownex 中为流网添加和定义一种新的流体温度相关工作材料。 Flownex 物料管理界面 在 Flownex 中使用与温度相关的流体材料时,了解其特性与温度的关系非常重要。这种了解可确保准确预测各种热条件下的流体行为&#xff0…

工业物联网平台-视频识别视频报警新功能正式上线

前言 视频监控作为中服云工业物联网平台4.0的功能已经上线运行。已为客户服务2年有余,为客户提供多路视频、实时在线监视和控制能力。服务客户实时发现现场、产线、设备出现随机故障、事故等,及时到场处理维修。 视频识别&视频报警新功能当前正式上…

4.PPT:日月潭景点介绍【18】

目录 NO1、2、3、4​ NO5、6、7、8 ​ ​NO9、10、11、12 ​ 表居中或者水平/垂直居中单元格内容居中或者水平/垂直居中 NO1、2、3、4 新建一个空白演示文稿,命名为“PPT.pptx”(“.pptx”为扩展名)新建幻灯片 开始→版式“PPT_素材.doc…

NetCore Consul动态伸缩+Ocelot 网关 缓存 自定义缓存 + 限流、熔断、超时 等服务治理

网关 OcelotGeteway 网关 Ocelot配置文件 {//单地址多实例负载均衡Consul 实现动态伸缩"Routes": [{// 上游 》》 接受的请求//上游请求方法,可以设置特定的 HTTP 方法列表或设置空列表以允许其中任何方法"UpstreamHttpMethod": [ "Get", &quo…

数据结构与算法(test1)

一、树和二叉树 1. 看图,完成以下填空 (1).树的度为________。 (2).树中结点的最大层次,称为树的_____或树的______,值是______。 (3).结点A和B的度分别为________ 和 ________。 (4).结点A是结点B的________。 (5).结点B是结点A的________…

【GitLab CI/CD 实践】从 0 到 1 搭建高效自动化部署流程

网罗开发 (小红书、快手、视频号同名) 大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等…

Kubernetes是什么?为什么它是云原生的基石

从“手工时代”到“自动化工厂” 想象一下,你正在经营一家工厂。在传统模式下,每个工人(服务器)需要手动组装产品(应用),效率低下且容易出错。而Kubernetes(k8s)就像一个…

算法与数据结构(删除有序数组的重复项)

思路 题目要求需要在原地删除重复的元素,这说明不能使用额外的空间。我们可以使用一个索引index来记录赋值的位置,以此来不断地删除重复的元素。 解题过程: 我们可以首先求得nums的长度len 若没有元素,直接返回0。 从第二个元素开始遍历…

[论文阅读] Knowledge Fusion of Large Language Models

Knowledge Fusion of Large Language Models (FuseLLM) Methodology 整体Pipeline如下图所示 不同的动物代表不同的LLM。左边第一,第二分别是Ensemble以及Weight Merging方法。最右侧为本文提出的FuseLLM。 Ensemble: 融合多个models的预测结果,比如…

2024~2025学年佛山市普通高中教学质量检测(一)【高三数学】

一、选择题 本题共8小题&#xff0c;每小题5分&#xff0c;共40分。在每小题给出的四个选项中。只有一项是符合题目要求的。 1、若 5 z 2 i 1 \frac{5}{z}2i1 z5​2i1&#xff0c;则 z z z A. 1-2i B. 12i C. 2-i D. 2i2、已知集合 A { x ∣ 1 < x < a } A\left\{…