【MySQL架构篇】SQL执行流程与缓冲池

文章目录

    • 1. SQL执行流程
    • 2. 数据库缓冲池(Buffer Pool)
      • 2.1 缓冲池概述
      • 2.2 缓冲池如何读取数据
      • 2.3 查看和设置缓冲池的大小
      • 2.4 多个Buffer Pool实例
      • 2.5 引申问题

1. SQL执行流程

在这里插入图片描述

  1. 查询缓存:因为查询效率往往不高,所以在MySQL8.0之后就抛弃了这个功能
  2. 解析器:在解析器中对SQL语句进行语法分析、语义分析
  3. 优化器:在优化器中会确定SQL语句的执行路径,比如是根据 全表检索 ,还是根据 索引检索 等,生成相应的 执行计划一条查询可以有很多种执行方式,最后都返回相同的结果。优化器的作用就是找到这其中最好的执行计划
  4. 执行器:在执行之前需判断该用户是否 具备权限。如果有权限,就打开表继续执行,打开表的时候,执行器就会根据表的引擎定义,调用存储引擎 API对表进行读写。存储引擎 API 只是抽象接口,下面还有存储引擎层,具体实现还是要看表选择的存储引擎

在这里插入图片描述

比如:表test中,ID字段没有索引,那么执行器的执行流程是这样的:

调用 InnoDB 引擎接口取这个表的第一行,判断 ID 值是不是1,如果不是则跳过,如果是则将这行存在结果集中;
调用引擎接口取“下一行”,重复相同的判断逻辑,直到取到这个表的最后一行。执行器将上述遍历过程中所有满足条件的行组成的记录集作为结果集返回给客户端。

至此,这个语句就执行完成了。对于有索引的表,执行的逻辑也差不多。

SQL 语句在 MySQL 中的流程是:SQL语句—>查询缓存->解析器->优化器->执行器

在这里插入图片描述

2. 数据库缓冲池(Buffer Pool)

InnoDB 存储引擎是以页为单位来管理存储空间的,我们进行的增删改查操作其实本质上都是在访问页面(包括读页面、写页面、创建新页面等操作)。而磁盘 I/0 需要消耗的时间很多,而在内存中进行操作,效率则会高很多,为了能让数据表或者索引中的数据随时被我们所用,DBMS 会申请 占用内存来作为数据缓冲池,在真正访问页面之前,需要把在磁盘上的页缓存到内存中的 Buffer Pool 之后才可以访问。

这样做的好处是可以让磁盘活动最小化,从而 减少与磁盘直接进行 I/0 的时间。要知道,这种策略对提升 SQL语句的查询性能来说至关重要。如果索引的数据在缓冲池里,那么访问的成本就会降低很多。

2.1 缓冲池概述

缓冲池和查询缓存不是同一个东西

在Innodb存储引擎中,有一部分数据会放入内存中,缓冲池则占了这部分内存的大部分,它用来存储各种数据的缓存,如下图所示:

在这里插入图片描述

在InnoDB缓冲池中包括了数据页、索引页、插入缓存、锁信息、自适应Hash和数据字典信息等。

InnoDB存储引擎在处理客户端的请求时,当需要访问某个页的数据时,就会把 完整的页的数据全部加载到内存中,也就是说即使我们只需要访问一个页的一条记录,那也需要先把整个页的数据加载到内存中。将整个页加载到内存中后就可以进行读写访问了,在进行完读写访问之后并不着急把该页对应的内存空间释放掉,而是将其 缓存 起来,这样将来有请求再次访问该页面时,就可以 省去磁盘IO 的开销了。

缓存原则

  • “位置 * 频次” 这个原则,可以帮我们对 I/0 访问效率进行优化。
  • 首先,位置决定效率,提供缓冲池就是为了在内存中可以直接访问数据
  • 其次,频次决定优先级顺序。因为缓冲池的大小是有限的,比如磁盘有 200G,但是内存只有 16G,缓冲池大小只有1G,就无法将所有数据都加载到缓冲池里,这时就涉及到优先级顺序,会 优先对使用频次高的热数据进行加载

缓冲池的预读特性

缓冲池的作用就是提升 I/0 效率,而我们进行读取数据的时候存在一个“局部性原理”,也就是说我们使用了一些数据,大概率还会使用它周围的一些数据,因此采用“预读”的机制提前加载,可以减少未来可能的磁盘 I/O 操作。

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';

在这里插入图片描述

即 innoDB 的默认的缓冲池大小只有 134217728/1024/1024=128MB。我们可以修改缓冲池大小,比如改为256MB,方法如下:

set global innodb_buffer_pool_size = 268435456;

或者修改配置文件

[server]
innodb_buffer_pool_size = 268435456

2.4 多个Buffer Pool实例

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

可以在服务器启动的时候通过设置 innodb_buffer_pool_instances 的值来修改Buffer Pool实例的个数比方说这样,下述值默认为1:

[server]
innodb_buffer_pool_instances=2

查看缓冲池的个数,使用命令:

show variables like 'innodb_buffer_pool_instances';

每个 Buffer Pool实例占用内存空间为总共的大小除以实例的个数,即如下公式:

innodb_buffer_pool_size/innodb_buffer_pool_instances

即上面设置缓冲池总大小为256MB后,再设置缓冲池实例数为2后,计算结果为每个实例占用内存空间位128MB。

注意:不是说Buffer Pool实例创建的越多越好,分别管理各个Buffer Pool也是需要 性能开销 的,InnoDB规定:当innodb_buffer_pool_size的值小于1G的时候设置多个实例是无效的,InnoDB会默认把innodb_buffer _pooL instances 的值修改为1。而我们鼓励在Buffer Pool大于或等于1G的时候设置多个Buffer Pool实例

2.5 引申问题

当我们查询数据的时候,会先去Buffer Pool中查询。如果Buffer Pool中不存在,存储引擎会先将数据从磁盘加载到Buffer Pool中,然后将数据返回给客户端;同理,当我们更新某个数据的时候,如果这个数据不存在于Buffer Pool,同样会先将数据加载进来,然后修改内存的数据。被修改过的数据会在之后统一刷入磁盘。

在这里插入图片描述

这个过程看似没啥问题,实则是有问题的。假设我们修改Buffer Pool中的数据成功,但是还没来得及将数据刷入磁盘MySQL就挂了怎么办? 按照上图的逻辑,此时更新之后的数据只存在于Buffer Pool中,如果此时MySQL宕机了,这部分数据将会永久地丢失;
再者,我更新到一半突然发生错误了,想要回滚到更新之前的版本,该怎么办?连数据持久化的保证、事务回滚都做不到还谈什么崩溃恢复?

答:

Redo Log:解决未及时刷盘MySQL宕机的问题

Undo Log:解决发生错误,事务需要回滚的问题

以上两个Log将在日志篇再详细分析。

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

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

相关文章

C使用指针注意事项(学习笔记)

一、数组使用指针 1、数组名是数组元素首地址。 2、只有在函数原型或函数定义头中,才可以用int arr[]代替int * arr int sum(int * arr,int n); int sum(int arr[],int n);//等效3、一个整形数组表名处理元素的个数有2种方式 /*方式1*/int sum(int * arr,int n); …

lvs+keepalived: 高可用集群

lvskeepalived: 高可用集群 keepalived为lvs应运而生的高可用服务。lvs的调度器无法做高可用,于是keepalived软件。实现的是调度器的高可用。 但是:keepalived不是专门为集群服务的,也可以做其他服务器的高可用。 lvs的高可用集群&#xf…

纵行科技携ZETA亮相世界物联网博览会,助力全球物联网生态合作

纵行科技携ZETA亮相世界物联网博览会,助力全球物联网生态合作 10月20日至23日,2023世界物联网博览会(简称“物博会”)在江苏省无锡市举行。本届物博会以“智联世界,融合赋能”为主题,围绕“打造世界级物联网产业集群”和“物联网…

【Eclipse Maven Tycho】如何通过maven执行eclipse application

通过maven执行eclipse application 前言命令行下运行通过maven tycho运行 前言 eclipse其实不只是一个桌面(GUI)程序,他还可以是一个命令行程序。如果你的产品或软件是基于eclipse开发的,并且他没有UI相关的功能,那么…

使用CompletableFuture多线程异步任务优化查询接口性能

一、需求:文书报告接口信息内容过多,涉及几十张表,十多个接口 由于积木报表是串行执行接口响应时间过长需要优化,而各个接口之间无顺序要求 1、创建异步任务 (1)supplyAsync介绍 supplyAsync是创建带有返回…

Ingress典型配置

Ingress 是 Kubernetes 中用于管理 HTTP 和 HTTPS 路由的资源。以下是一个典型的 Ingress 配置示例,用于将流量引导到两个不同的服务: apiVersion: networking.k8s.io/v1 kind: Ingress metadata:name: example-ingress spec:rules:- host: example.com…

力扣第1005题 K 次取反后最大化的数组和 c++ 贪心 双思维

题目 1005. K 次取反后最大化的数组和 简单 相关标签 贪心 数组 排序 给你一个整数数组 nums 和一个整数 k ,按以下方法修改该数组: 选择某个下标 i 并将 nums[i] 替换为 -nums[i] 。 重复这个过程恰好 k 次。可以多次选择同一个下标 i 。 以…

创建Secret(使用kubectl)

创建Secret(使用kubectl) 假设某个 Pod 需要访问数据库。在您执行 kubectl 命令所在机器的当前目录,创建文件 ./username.txt 文件和 ./password.txt 暂存数据库的用户名和密码,后续我们根据这两个文件配置 kubernetes secrets。…

asp.net乡村旅游管理系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio

一、源码特点 asp.net乡村旅游管理系统是一套完善的web设计管理系统系统,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为vs2010,数据库为sqlserver2008,使用c# 语言开发 asp.net乡村旅游管理系统 二、…

【在英伟达nvidia的jetson-orin-nx和PC电脑ubuntu20.04上-装配ESP32开发调试环境-基础测试】

【在英伟达nvidia的jetson-orin-nx和PC电脑ubuntu20.04上-装配ESP32开发调试环境-基础测试】 1、概述2、实验环境3、 物品说明4、参考资料与自我总结5、实验过程1、创建目录2、克隆下载文件3、 拉取子目录安装和交叉编译工具链等其他工具4、添加环境变量6、将样例文件拷贝到桌面…

SQL比较两次的字段集合,找出并返回差异,主要用于更新记录事件

Create PROCEDURE [dbo].[SysGetTableFieldsCompare] -- Description: <比较两次的字段集合&#xff0c;找出并返回差异&#xff0c;主要用于更新记录事件> -- Return 0- 成功&#xff0c; -1- 没有这个表 -- Rev: 1.00 -- FieldsSource Nvarchar(max) , FieldsTarg…

【分布式技术专题】「分布式技术架构」MySQL数据同步到Elasticsearch之N种方案解析,实现高效数据同步

MySQL数据同步到Elasticsearch之N种方案解析&#xff0c;实现高效数据同步 前提介绍MySQL和ElasticSearch的同步双写优点缺点针对于缺点补充优化方案 MySQL和ElasticSearch的异步双写优点缺点 定时延时写入ElasticSearch数据库机制优点缺点 开源和成熟的数据迁移工具选型Logsta…

软考系列(系统架构师)- 2016年系统架构师软考案例分析考点

试题一 软件架构&#xff08;质量属性、架构风格对比、根据描述填空&#xff09; 试题二 系统开发&#xff08;用例图参与者、用例关系、类图关系&#xff09; 学生、教师、管理员、时间、打印机【问题2】&#xff08;7分&#xff09; 用例是对系统行为的动态描述&#xff0c;用…

ant框架下 a-input-number组件的宽度问题

如图所示&#xff0c;在使用a-input-number组件时虽然设置了宽度但是没有生效&#xff0c;加上了一个!important就好了&#xff1a;

【Java 进阶篇】使用 Java 和 Jsoup 进行 XML 处理

XML&#xff08;可扩展标记语言&#xff09;是一种常用的数据交换格式&#xff0c;它被广泛用于在不同系统之间传递和存储数据。Java作为一种强大的编程语言&#xff0c;提供了多种方式来处理XML数据。其中&#xff0c;Jsoup 是一个流行的Java库&#xff0c;用于解析和操作XML文…

Leetcode—2678.老人的数目【简单】

2023每日刷题&#xff08;八&#xff09; Leetcode—2678.老人的数目 int countSeniors(char ** details, int detailsSize){ int ans 0; int i; int tens 0; int ones 0; for(i 0; i < detailsSize; i) { tens ((details i) 11) - ‘0’; ones ((details i) 12)…

FOC系列(一)----DRV8301芯片的学习

一、 写在前面 从今年四五月份一直就想玩个无刷直流电机&#xff08;BLDC&#xff09;&#xff0c;但是碍于一直没时间。其实很早就做出来了测试板的控制板&#xff0c;可以当做开发板使用&#xff0c;考虑到成本问题&#xff0c;最后选用STM32F103CBT6芯片&#xff0c;下面是很…

Hadoop核心机制详细解析

Hadoop核心机制详细解析 Hadoop的核心机制是通过HDFS文件系统和MapReduce算法进行存储资源、内存和程序的有效利用与管理。在现实的实例中&#xff0c;通过Hadoop&#xff0c;可以轻易的将多台普通的或低性能的服务器组合成分布式的运算-存储集群&#xff0c;提供大数据量的存…

Python爬虫网易云音乐,Tkinter制作音乐播放器

目录 一、效果展示 二、环境 三、实现过程 四、源码 一、效果展示 页面的美化以及功能还有待升级~ 先来说一下已有功能吧&#xff1a; 可以在搜索框中通过歌曲或歌手名称进行搜索&#xff0c;效果和在网易云官网搜索一样。 点击开始下载&#xff0c;就会将搜索结果的第一…

关于语雀 23 日故障的公告

10 月 23 日语雀出现重大服务故障&#xff0c;且持续 7 个多小时才完全恢复&#xff0c;给用户使用造成极大不便&#xff0c;对此我们深感抱歉。经过复盘&#xff0c;我们在这里向大家进一步说明故障原因、修复过程和改进措施。 故障原因及处理过程&#xff1a; 10 月 23 日下…