第19章_体系结构

文章目录

  • 1. 逻辑架构剖析
    • 1.1 服务器处理客户端请求
    • 1.2 Connectors
    • 1.3 第1层:连接层
    • 1.4 第2层:服务层
      • 1.4.1 SQL Interface: SQL接口
      • 1.4.2 Parser: 解析器
      • 1.4.3 Optimizer: 查询优化器
      • 1.4.4 Caches & Buffers: 查询缓存组件
    • 1.5 第3层:引擎层
    • 1.6 存储层
    • 1.7 小结
  • 2. 数据库缓冲池(buffer pool)
    • 2.1 缓冲池 vs 查询缓存
      • 2.1.1 缓冲池(Buffer Pool)
      • 2.1.2 查询缓存
    • 2.2 缓冲池如何读取数据
    • 2.3 查看/设置缓冲池的大小
    • 2.4 多个Buffer Pool实例
    • 2.5 引申问题

1. 逻辑架构剖析

1.1 服务器处理客户端请求

那服务器进程对客户端进程发送的请求做了什么处理,才能产生最后的处理结果呢?这里以查询请求为例展示:
在这里插入图片描述
下面具体展开看一下(数字标号展示了5.7查询的顺序):
在这里插入图片描述
Connectors: MySQL服务器之外的客户端程序,和具体编程语言相关的内容
Management Service &Utilities–>基础服务组件: MySQL服务器的基础服务组件
Connection Pool -->连接池: 提供了多个用于客户端和服务器端进行交互的线程,这些线程使用完后交还到连接池,供其他客户端使用,从而保证资源不被浪费
SQL Interface–>SQL接口: 作用是用来接收SQL指令并返回查询结果
Parser–>解析器: 用来解析SQL接口中的SQL,分为语法解析和语义解析。解析后会生成一个语法树,该语法树可用于后续的查询优化。解析器将SQL语句“肢解”为关键字、表名、字段名等内容
Optimlzer–>优化器: 核心组件,对SQL进行优化:分为逻辑上的优化和物理上的优化。物理优化—使用索引
Cache & Buffers–>查询缓存: 在8.0中已经弃用。以key - value的方式缓存查询结果,查询结果作为value,SQL语句作为key。当下一次查询和缓存的查询语句完全一致时查询命中
pluggable Storage Engines–>插件式存储引擎: 与底层的文件系统进行交互
File system–>文件系统
File & Logs–>日志文件

5.7查询顺序: Connectors–>Connection Pool (连接池)–>SQL Interface(SQL接口)–>Cache & Buffers(查询缓存)–>Parser(解析器)–>Optimlzer(优化器)–>pluggable Storage Engines(插件式存储引擎)–>File system(文件系统)–>Cache & Buffers(查询缓存)–>SQL Interface(SQL接口)

1.2 Connectors

Connectors,指的是不同语言中与SQL的交互。MySQL首先是一个网络程序,在TCP之上定义了自己的应用层协议。所以要使用MySQL,我们可以编写代码,跟MySQL Server建立TCP连接,之后按照其定义好的协议进行交互。或者比较方便的办法是调用SDK,比如Native C API、JDBC、PHP等各语言MysQL Connector,或者通过ODBC。但通过SDK来访问MysQL,本质上还是在TCP连接上通过MySQL协议跟MySQL进行交互。
接下来的MysQL Server结构可以分为如下的三层:
一、连接层
二、服务层
三、引擎层

1.3 第1层:连接层

系统(客户端)访问 MySQL 服务器前,做的第一件事就是建立 TCP 连接。
经过三次握手建立连接成功后, MySQL 服务器对 TCP 传输过来的账号密码做身份认证、权限获取。

用户名或密码不对,会收到一个Access denied for user错误,客户端程序结束执行
用户名密码认证通过,会从权限表查出账号拥有的权限与连接关联,之后的权限判断逻辑,都将依赖于此时读到的权限
TCP 连接收到请求后,必须要分配给一个线程专门与这个客户端的交互。所以还会有个线程池,去走后面的流程。每一个连接从线程池中获取线程,省去了创建和销毁线程的开销。

1.4 第2层:服务层

1.4.1 SQL Interface: SQL接口

  • 接收用户的SQL命令,并且返回用户需要查询的结果。比如SELECT … FROM就是调用SQL Interface
  • MySQL支持DML(数据操作语言)、DDL(数据定义语言)、存储过程、视图、触发器、自定义函数等多种SQL语言接口

1.4.2 Parser: 解析器

  • 在解析器中对 SQL 语句进行语法分析、语义分析。将SQL语句分解成数据结构,并将这个结构传递到后续步骤,以后SQL语句的传递和处理就是基于这个结构的。如果在分解构成中遇到错误,那么就说明这个SQL语句是不合理的。
  • 在SQL命令传递到解析器的时候会被解析器验证和解析,并为其创建语法树 ,并根据数据字典丰富查询语法树,会验证该客户端是否具有执行该查询的权限。创建好语法树后,MySQL还会对SQl查询进行语法上的优化,进行查询重写。

1.4.3 Optimizer: 查询优化器

  • SQL语句在语法解析之后、查询之前会使用查询优化器确定 SQL 语句的执行路径,生成一个执行计划。
  • 这个执行计划表明应该使用哪些索引进行查询(全表检索还是使用索引检索),表之间的连接顺序如何,最后会按照执行计划中的步骤调用存储引擎提供的方法来真正的执行查询,并将查询结果返回给用户。

它使用“ 选取-投影-连接 ”策略进行查询。例如:
SELECT id,name FROM student WHERE gender = '女';

这个SELECT查询先根据WHERE语句进行 选取 ,而不是将表全部查询出来以后再进行gender过滤。 这个SELECT查询先根据id和name进行属性投影 ,而不是将属性全部取出以后再进行过滤,将这两个查询条件 连接 起来生成最终查询结果。

1.4.4 Caches & Buffers: 查询缓存组件

  • MySQL内部维持着一些Cache和Buffer,比如Query Cache用来缓存一条SELECT语句的执行结果,如果能够在其中找到对应的查询结果,那么就不必再进行查询解析、优化和执行的整个过 程了,直接将结果反馈给客户端。
  • 这个缓存机制是由一系列小缓存组成的。比如表缓存,记录缓存,key缓存,权限缓存等 。
  • 这个查询缓存可以在不同客户端之间共享 。
  • 从MySQL 5.7.20开始,不推荐使用查询缓存,并在 MySQL 8.0中删除 。

1.5 第3层:引擎层

插件式存储引擎层( Storage Engines),真正的负责了MySQL中数据的存储和提取,对物理服务器级别维护的底层数据执行操作, 服务器通过API与存储引擎进行通信。不同的存储引擎具有的功能不同,这样我们可以根据自己的实际需要进行选取。

1.6 存储层

所有的数据,数据库、表的定义,表的每一行的内容,索引,都是存在文件系统上,以文件的方式存在的,并完成与存储引擎的交互。当然有些存储引擎比如InnoDB,也支持不使用文件系统直接管理裸设备,但现代文件系统的实现使得这样做没有必要了。在文件系统之下,可以使用本地磁盘,可以使用DAS、NAS、SAN等各种存储系统。

1.7 小结

MySQL架构图本节开篇所示。下面为了熟悉SQL执行流程方便,我们可以简化如下:

  • 连接层:客户端和服务器端建立连接,客户端发送 SQL 至服务器端;
  • SQL 层(服务层):对 SQL 语句进行查询处理;与数据库文件的存储方式无关;
  • 存储引擎层:与数据库文件打交道,负责数据的存储和读取。

2. 数据库缓冲池(buffer pool)

InnoDB 存储引擎是以页为单位来管理存储空间的,我们进行的增删改查操作其实本质上都是在访问页面(包括读页面、写页面、创建新页面等操作)。而磁盘 I/O 需要消耗的时间很多,而在内存中进行操作,效率则会高很多,为了能让数据表或者索引中的数据随时被我们所用,DBMS 会申请 占用内存来作为数据缓冲池 ,在真正访问页面之前,需要把在磁盘上的页缓存到内存中的 Buffer Pool 之后才可以访问。
这样做的好处是可以让磁盘活动最小化,从而减少与磁盘直接进行 I/O 的时间 。要知道,这种策略对提升 SQL 语句的查询性能来说至关重要。如果索引的数据在缓冲池里,那么访问的成本就会降低很多。

2.1 缓冲池 vs 查询缓存

缓冲池和查询缓存是一个东西吗?不是。

2.1.1 缓冲池(Buffer Pool)

首先我们需要了解在 InnoDB 存储引擎中,缓冲池都包括了哪些。
在 InnoDB 存储引擎中有一部分数据会放到内存中,缓冲池则占了这部分内存的大部分,它用来存储各种数据的缓存,如下图所示:
在这里插入图片描述
从图中,你能看到 InnoDB 缓冲池包括了数据页、索引页、插入缓冲、锁信息、自适应 Hash 和数据字典信息等。
缓存池的重要性:
对于使用InnoDB作为存储引擎的表来说,不管是用于存储用户数据的索引(包括聚簇索引和二级索引),还是各种系统数据,都是以页的形式存放在表空间中的,而所谓的表空间只不过是InnoDB对文件系统上一个或几个实际文件的抽象,也就是说我们的数据说到底还是存储在磁盘上的。但是各位也都知道,磁盘的速度慢的跟乌龟一样,怎么能配得上"快如风,疾如电"的CPU呢?这里,缓冲池可以帮助我们消除CPU和磁盘之间的鸿沟。所以InnoDB存储引擎在处理客户端的请求时,当需要访问某个页的数据时,就会把完整的页的数据全部加载到内存中,也就是说即使我们只需要访问一个页的一条记录,那也需要先把整个页的数据加载到内存中。将整个页加载到内存中后就可以进行读写访问了,在进行完读写访问之后并不着急把该页对应的内存空间释放掉,而是将其缓存起来,这样将来有请求再次访问该页面时,就可以省去磁盘IO的开销了。
缓冲池的预读特性:
了解了缓冲池的作用之后,我们还需要了解缓冲池的另一个特性:预读。
缓冲池的作用就是提升IO效率,而我们进行读取数据的时候存在一个"“局部性原理”,也就是说我们使用了一些数据,大概率还会使用它周周的一些数据,因此采用“预读”的机制提前加载,可以减少未来可能的磁盘I/O操作。
缓冲池淘汰策略:
采用LRU算法。

2.1.2 查询缓存

查询缓存是提前把查询结果缓存 起来,这样下次不需要执行就可以直接拿到结果。需要说明的是,在MySQL 中的查询缓存,不是缓存查询计划,而是查询对应的结果。因为命中条件苛刻,而且只要数据表发生变化,查询缓存就会失效,因此命中率低。

2.2 缓冲池如何读取数据

缓冲池管理器会尽量将经常使用的数据保存起来,在数据库进行页面读操作的时候,首先会判断该页面是否在缓冲池中,如果存在就直接读取,如果不存在,就会通过内存或磁盘将页面存放到缓冲池中再进行读取。

如果我们执行 SQL 语句的时候更新了缓存池中的数据,那么这些数据会马上同步到磁盘上吗?
实际上,当我们对数据库中的记录进行修改的时候,首先会修改缓冲池中页里面的记录信息,然后数据库会以一定的频率刷新到磁盘上。注意并不是每次发生更新操作,都会立刻进行磁盘回写。缓冲池会采用一种叫做checkpoint 的机制将数据回写到磁盘上,这样做的好处就是提升了数据库的整体性能。
比如,当缓冲池不够用时,需要释放掉一些不常用的页,此时就可以强行采用checkpoint的方式,将不常用的脏页回写到磁盘上,然后两从缓冲池中将这些页释放掉。这里脏页(dirty page)指的是缓冲池中被修改过的页,与磁盘上的数据页不一致。

2.3 查看/设置缓冲池的大小

如果你使用的是MySQL MyISAM存储引擎,它只缓存索引,不缓存数据,对应的键缓存参数为key_buffer_size,你可以用它进行查看。

如果你使用的是 InnoDB 存储引擎,可以通过查看 innodb_buffer_pool_size 变量来查看缓冲池的大小。命令如下:

show variables like 'innodb_buffer_pool_size';
/*输出
+-------------------------+-----------+
| Variable_name           | Value     |
+-------------------------+-----------+
| innodb_buffer_pool_size | 134217728 |
+-------------------------+-----------+
*/

你能看到此时 InnoDB 的缓冲池大小只有 134217728/1024/1024=128MB。我们可以修改缓冲池大小,比如改为256MB,方法如下:
set global innodb_buffer_pool_size = 268435456;
或者:

[server]
innodb_buffer_pool_size = 268435456
#然后再来看下修改后的缓冲池大小,此时已成功修改成了 256 MB:

2.4 多个Buffer Pool实例

Buffer Pool本质是InnoDB向操作系统申请的一块连续的内存空间,在多线程环境下,访问Buffer Pool中的数据都需要加锁处理。在Buffer Pool特别大而且多线程并发访问特别高的情况下,单一的Buffer Pool可能会影响请求的处理速度。所以在Buffer Pool特别大的时候,我们可以把它们拆分成若干个小的Buffer Pool,每个Buffer Pool都称为一个实例,它们都是独立的,独立的去中请内存空间,独立的管理各种链表。所以在多线程并发访问时并不会相互影响,从而提高并发处理能力。

show variables like 'innodb_buffer_pool_instances';
/*默认有一个Buffer Pool实例
+------------------------------+-------+
| Variable_name                | Value |
+------------------------------+-------+
| innodb_buffer_pool_instances | 1     |
+------------------------------+-------+
*/

可以在服务器启动的时候通过设置innodb_buffer_pool_instances的值来修改Buffer Pool实例的个数:

[server]
innodb_buffer_pool_instances = 2

这样就表明我们要创建2个 Buffer Pool 实例。
我们看下如何查看缓冲池的个数,使用命令:
show variables like 'innodb_buffer_pool_instances';

那每个 Buffer Pool 实例实际占多少内存空间呢?其实使用这个公式算出来的:
innodb_buffer_pool_size/innodb_buffer_pool_instances
也就是总共的大小除以实例的个数,结果就是每个 Buffer Pool 实例占用的大小。
不过也不是说Buffer Pool实例创建的越多越好,分别管理各个Buffer Pool也是需要性能开销的,InnoDB规定:当innodb_buffer_pool_size的值小于1G的时候设置多个实例是无效的,InnoDB会默认把innodb_buffer_pool_instances 的值修改为1。而我们鼓励在Bufer Pool大于或等于1G的时候设置多个Buffer Pool实例。

2.5 引申问题

Buffer Pool是MySQL内存结构中十分核心的一个组成,你可以先把它想象成一个黑盒子。
黑盒下的更新数据流程
当查询数据的时候,会先去Buffer Pool中查询。如果Buffer Pool中不存在,存储引擎会先将数据从磁盘加载到Buffer Pool中,然后将数据返回给客户端;同理,当更新某个数据的时候,如果这个数据不存在于BufferPool,同样会先将数据加载进来,然后修改内存的数据。被修改过的数据会在之后统一刷入磁盘。
在这里插入图片描述
这个过程看似没啥问题,实则是有问题的。假设修改Buffer Pool中的数据成功,但是还没来得及将数据刷入磁盘MySQL就挂了怎么办?按照上图的逻辑,此时更新之后的数据只存在于Buffer Pool中,如果此时MySQL宕机了,这部分数据将会永久地丢失;

再者,更新到一半突然发生错误了,想要回滚到更新之前的版本,该怎么办?连数据持久化的保证、事务回滚都做不到还谈什么崩溃恢复?
答案:Redo Log & Undo Log
Redo Log :解决刷盘时刷到一半宕机的问题
Undo Log:解决回滚的问题

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

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

相关文章

Xshell如何下载文件到本地

法一:命令下载 1、连接到远程服务器并登录 2、使用cd命令进入要下载文件的目录 3、使用以下命令下载文件: scp usernameremote:/path/to/file /path/to/local/directoryusername 远程服务器的用户名 remote 远程服务器的IP地址或主机名 /path/to/file …

SpringCloud之Seata基本介绍与安装

目录 基本介绍 概述 核心组件 四种方案 部署TC服务(安装) 下载 修改registry.conf nacos添加配置 建表(仅db) 启动 基本介绍 概述 Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将…

IOS渲染流程之提交图层数据至RenderThread进程

大致链路 UIView/CALayer---->CoreAnimation./Core Graphics/Core Image---->GPU Drive-->GPU 图层树/视图树 一个UIView(视图)对应一个CALayer(图层),CALayer对应显示的数据其有个content代表Bitamp&#…

【第2章 Node.js基础】2.2 Node.js回调函数

学习目标 (1)理解Node.js的回调函数; (2)掌握回调函数的使用。 什么是回调函数 回调函数是一种特殊的函数,它作为参数传递给另一个函数,并在特定的事件或条件发生时被调用。回调函数通常用于异…

Jekyll框架编译GithubPages,提示没有docs

Jekyll Converters::Scss build issue: No such file or directory dir_chdir - /github/workspace/docs Error: No such file or directory dir_chdir - /github/workspace/docs 解决方案: 修改github page仓库中–> 设置—> pages 把里面的\docs&#xf…

Microsoft Edge浏览器不兼容解决办法

找到 Edge 的安装位置,一般在 C:\Program Files (x86)Microsoft Edge\Application\ 这个目录,把 edge.exe 或msedge.exe 修改为 chrome.exe 再重启电脑。

蓝桥杯双周赛算法心得——串门(双链表数组+双dfs)

大家好,我是晴天学长,树和dfs的结合,其邻接表的存图方法也很重要。需要的小伙伴可以关注支持一下哦!后续会继续更新的。💪💪💪 1) .串门 2) .算法思路 串门(怎么存图很关键&#xf…

打包 广告

小米广告 Type android.support.v4.app.INotificationSideChannel is defined multiple times d8clsPath: Error in D:\ChannelFolder\JJChannelPackageForTest\ToolConfigPath\channels-ad\ATemp-100057\xiaomi\lib\xiaomi_ad_merge_20231104.jar:android/support/v4/app/IN…

8.spark自适应查询-AQE之自适应调整Shuffle分区数量

目录 概述主要功能自适应调整Shuffle分区数量原理默认环境配置修改配置 结束 概述 自适应查询执行(AQE)是 Spark SQL中的一种优化技术,它利用运行时统计信息来选择最高效的查询执行计划,自Apache Spark 3.2.0以来默认启用该计划。…

Mall4cloud 微服务商城系统 2.0 发布

导读现在 jdk17 和 spring boot 以及 spring cloud alibaba 2022 的第三方依赖已经趋于成熟,所以 mall4cloud 也一把梭哈做了升级嗷。 本次更新重点: 系统由 jdk8 最低要求升级到 jdk17spring boot 由 2.7.x 升级到 3.1.xjavax 升级到 jakartaspring-cl…

extractvalue报错注入理论及实战

报错注入 什么是报错注入 构造语句,让错误信息中夹杂可以显示数据库内容的查询语句,返回报错提示中包括数据库中的内容 如上图所示,通过group by的报错,我们可以知道列数是多少 输入正确的查询数据库的SQL语句,虽然可…

Cube MX 开发高精度电流源跳坑过程/SPI连接ADS1255/1256系列问题总结/STM32 硬件SPI开发过程

文章目录 概要整体架构流程技术名词解释技术细节小结 概要 1.使用STM32F系列开发一款高精度恒流电源,用到了24位高精度采样芯片ADS1255/ADS1256系列。 2.使用时发现很多的坑,详细介绍了每个坑的具体情况和实际的解决办法。 坑1:波特率设置…

小白学爬虫:通过关键词搜索1688商品列表数据接口|1688商品列表数据接口|1688商品列表数据采集|1688API接口

通过关键词搜索1688商品列表数据接口可以使用1688开放平台提供的API接口实现。以下是使用关键词搜索商品列表数据的基本步骤: 1、注册并获取AppKey。 2、构造请求参数,包括搜索关键词、页码、每页条数等。 3、通过API接口链接,将请求参数发送…

高校教务系统登录页面JS分析——西安外国语大学教务系统

高校教务系统密码加密逻辑及JS逆向 本文将介绍高校教务系统的密码加密逻辑以及使用JavaScript进行逆向分析的过程。通过本文,你将了解到密码加密的基本概念、常用加密算法以及如何通过逆向分析来破解密码。 本文仅供交流学习,勿用于非法用途。 一、密码加…

微信小程序登录后端

一、 概念 code code是用户登录凭证,个人理解为用户的授权码(需要用户本人授权给小程序,小程序才有权力获取到你这个用户的数据),code需要由小程序向微信服务器获取。 注意: 每个code只能使用一次,且有效…

单基因泛癌+实验简单验证,要素丰富,没研究方向的赶紧上车

今天给同学们分享一篇生信文章“Pan-Cancer Analysis Reveals CENPI as a Potential Biomarker and Therapeutic Target in Adrenocortical Carcinoma”,这篇文章发表在J Inflamm Res期刊上,影响因子为4.5。 结果解读: 正常组织、癌症细胞系…

影响金融软件开发价格的因素有哪些?

随着科技的发展,金融行业逐渐向数字化和信息化转型,在这个过程中,金融软件开发成为了重要的支撑,然而,金融软件开发的价格是一个复杂的问题,受到多种因素的影响,本文将详细解析影响金融软件开发…

深度图(Depth Map)

文章目录 深度图深度图是什么深度图的获取方式激光雷达或结构光等传感器的方法激光雷达RGB-D相机 双目或多目相机的视差信息计算深度采用深度学习模型估计深度 深度图的应用场景扩展阅读 深度图 深度图是什么 深度图(depth map)是一种灰度图像&#xf…

【qemu逃逸】HWS2017-FastCP

前言 虚拟机用户名:root 虚拟机密码:无密码 本题有符号,所以对于设备定位啥的就不多说了,直接逆向设备吧。 设备逆向 在 realize 函数中设置一个时钟任务,并且可以看到只注册了 mmio,大小为 0x100000。…

SpringBoot整合Kafka (二)

📑前言 本文主要讲了SpringBoot整合Kafka文章,如果有什么需要改进的地方还请大佬指出⛺️ 上文链接:SpringBoot整合Kafka (一) 🎬作者简介:大家好,我是青衿🥇 ☁️博客首页:CSDN主页…