第19章_体系结构

news2024/12/23 13:15:42

文章目录

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

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

相关文章

详细创建Prism架构wpf项目

方案一&#xff1a; 1.创建一个普通wpf项目 2、安装NuGet包&#xff1a;Prism.DryIoc 3、App.xaml.cs中: 将原本的父类Application改为&#xff1a;PrismApplication&#xff0c;并且实现抽象类 CreateShell方法中写上&#xff1a;”return Container.Resolve<MainWindow>…

YOLO目标检测——交通标志识别数据集【含对应voc、coco和yolo三种格式标签】

实际项目应用&#xff1a;交通标志识别数据集在自动驾驶、交通安全监控、智能交通系统、驾驶员辅助系统和城市规划等领域都有广泛应用的潜力数据集说明&#xff1a;交通标志识别数据集&#xff0c;真实场景的高质量图片数据&#xff0c;数据场景丰富&#xff0c;含有交通标识6类…

电源模块的测试方法都有哪些?如何用ATECLOUD进行测试?

电源模块的测试方法主要包括以下步骤&#xff1a; 连接设备&#xff1a;通过LAN通讯总线、测试夹具以及其它线缆对测试所需的设备和需要测试的电源模块进行连接&#xff0c;同时接入纳米box进入登录ATECLOUD云测试平台。 创建测试项目&#xff1a;根据所以的设备仪器搭建所需…

clumsy 0.3 发布,十年前推出的差网络环境模拟工具

clumsy 0.3 现已发布&#xff0c;距离 v0.1 版本已经过去了十年的时间。clumsy 能在 Windows 平台下人工造成不稳定的网络状况&#xff0c;方便你调试应用程序在极端网络状况下的表现。 0.3 二进制文件与一年半前发布的 0.3 RC4 相同。 将滞后时间上限提高到 15 秒改用 zig 0.…

彻底改变日常生活:面向消费类应用的物联网

在本文中&#xff0c;我们将探讨消费应用的物联网世界&#xff0c;包括其关键用途、优势、挑战以及它为消费者带来的令人兴奋的未来。 物联网 (IoT) 正在重塑我们的生活、工作以及与环境互动的方式。 通过物联网&#xff0c;日常物品和设备连接到互联网&#xff0c;创建一个可以…

jenkins部署job

apt install fontconfig openjdk-11-jre wget https://mirrors.tuna.tsinghua.edu.cn/jenkins/war/2.429/jenkins.wardeb包安装 wget https://mirrors.tuna.tsinghua.edu.cn/jenkins/debian-stable/jenkins_2.414.3_all.debdpkg -i jenkins_2.414.3_all.deb 访问 http://…

波形的哪些事

一.静音波形制造(波形卡顿制造) 二.pop波形制造 三.示波器探头设置 四.示波器的差分输入和单端输入的接法不一样 差分的接法&#xff0c;需要配差分探头(如下图)&#xff0c;差分探头的两个脚分别和功放输出通道的两个脚连接 单端的接法&#xff0c;需要单端的探头&#xff0c…

【算法与数据结构】216、LeetCode组合总和 III

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;本题可以直接利用77题的代码【算法与数据结构】77、LeetCode组合&#xff0c;稍作修改即可使用。   …

Linux文件系统的功能规划

对于运行的进程来说&#xff0c;内存就像一个纸箱子&#xff0c;仅仅是一个暂存数据的地方&#xff0c;而且空间有限。如果我们想要进程结束之后&#xff0c;数据依然能够保存下来&#xff0c;就不能只保存在内存里&#xff0c;而是应该保存在外部存储中。就像图书馆这种地方&a…

第三章:人工智能深度学习教程-基础神经网络(第二节-ANN 和 BNN 的区别)

在本文中&#xff0c;我们将了解单层感知器及其使用 TensorFlow 库在Python中的实现。神经网络的工作方式与我们的生物神经元的工作方式相同。 生物神经元的结构 生物神经元具有三个基本功能 接收外部信号。 处理信号并增强是否需要发送信息。 将信号传递给目标细胞&#x…

[ Linux Busybox ] flash_eraseall 命令解析

文章目录 相关结构体flash_eraseall 函数实现flash_eraseall 实现流程图 文件路径&#xff1a;busybox-1.20.2/miscutils/flash_eraseall.c 相关结构体 MTD 相关信息结构体 struct mtd_info_user {__u8 type; // MTD 设备类型__u32 flags; // MTD设…

网络安全深入学习第八课——正向代理(工具:ReGeorg)

文章目录 一、环境配置二、开始模拟1、拿下跳板机的Webshell权限&#xff0c;并上传shell文件1.1、查看跳板机网络环境1.2、查看arp表 2、使用ReGeorg来建立连接2.1、生产ReGeorg隧道文件2.2、上传ReGeorg隧道的PHP脚本到跳板机2.3、连接隧道2.4、尝试浏览器连接 3、使用Proxif…

栈,线性dp,P1310 [NOIP2011 普及组] 表达式的值

P1310 [NOIP2011 普及组] 表达式的值 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 这道题很有意义 题目描述 对于1 位二进制变量定义两种运算&#xff1a; 运算的优先级是&#xff1a; 先计算括号内的&#xff0c;再计算括号外的。 “ ”运算优先于“⊕”运算&#xf…

reduxjs/toolkit的使用

用法&#xff1a; 下载包进行安装&#xff0c;store主入口&#xff0c;hooks简化store(复制粘贴进去即可)&#xff0c;slice相当于store中的模块化&#xff0c;最后在页面根入口导入store&#xff0c;并使用即可 1、安装 npm install reduxjs/toolkit react-redux -D2、目录结…

【网络编程】传输层——TCP协议

文章目录 TCP协议TCP协议格式窗口大小六个标志位确认应答机制超时重传机制连接管理机制三次握手四次挥手 流量控制滑动窗口拥塞控制延迟应答捎带应答面向字节流粘包问题TCP异常情况TCP小结基于TCP的应用层协议TCP与UDP的对比 TCP相关实验CLOSE_WAIT状态实验TIME_WAIT状态实验TI…

为你提供5个解决“找不到msvcp120.dll无法继续执行代码”

在使用电脑计算机运行软件时&#xff0c;我们可能会遇到一些错误提示&#xff0c;其中之一就是“找不到msvcp120.dll无法继续执行代码”。这个问题通常是由于缺少相应的运行库文件或者文件损坏导致的。下面我将为你提供5个解决方法&#xff0c;帮助你解决这个问题。 第1个方法.…

​软考-高级-信息系统项目管理师教程 第四版【第18章-项目绩效域-思维导图】​

软考-高级-信息系统项目管理师教程 第四版【第18章-项目绩效域-思维导图】 课本里章节里所有蓝色字体的思维导图

MATLAB画图由于线段太多导致导出图片模糊的解决办法

Matlab画图如果figure内的线条过多&#xff0c;或者散点过多&#xff0c;导出的图片会模糊&#xff0c;解决方案 解决方法就在于figure的导出设置中。 在设置的渲染选项中&#xff0c;渲染器有两个&#xff0c;分别为painters和OpenGL&#xff0c;分别为矢量格式输出和位图输出…

【原创】java+swing+mysql爱心捐赠管理系统设计与实现

摘要&#xff1a; 爱心捐赠管理系统旨在管理和优化捐赠过程&#xff0c;提高效率&#xff0c;增强透明度&#xff0c;并鼓励更多的个人和企业参与公益捐赠&#xff0c;用户可以捐款或者捐物。本系统采用javaswing界面可视化技术&#xff0c;数据库使用mysql。 功能分析&#…

数据库的进阶增删查改操作(一)

进阶操作 一.约束1.约束类型2.NULL约束3.unique:唯一约束4.default:默认值约束5.primary key:主键约束6.foreign key:外键约束7.check约束(了解内容) 二.表的设计1.一对一2.一对多3.多对多 三.新增四.查询1.聚合函数1.1 count1.2 sum1.3 avg1.4 max1.5 min 2.group by 字句3.ha…