首页 > 数据库 >⭐MySQL的底层原理与架构

⭐MySQL的底层原理与架构

时间:2025-01-12 13:30:01浏览次数:3  
标签:架构 log Buffer 数据 MySQL 磁盘 redo 底层

前言

了解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)该条记录会被加上一个独占锁

标签:架构,log,Buffer,数据,MySQL,磁盘,redo,底层
From: https://blog.csdn.net/Tomkruse11/article/details/144959584

相关文章

  • 前端必知必会-Node.js连接MySQL
    文章目录Node.jsMySQLMySQL数据库安装MySQL驱动程序创建连接查询数据库总结Node.jsMySQLNode.js可用于数据库应用程序。最流行的数据库之一是MySQL。MySQL数据库为了能够试验代码示例,您应该在计算机上安装MySQL。您可以在https://www.mysql.com/down......
  • 【架构师从入门到进阶】第四章:前端优化思路——第三节:前置资源和缓存
    【架构师从入门到进阶】第四章:前端优化思路——第三节:前置资源和缓存前置资源缓存http缓存什么是http缓存http缓存如何做缓存风险更改文件名使用后端验证缓存的有效性基于资源最后修改时间验证基于资源版本号的验证方式客户端缓存各种客户端缓存风险本篇文章我们......
  • 【开发心得】-有了AI,还需要银行核心系统架构师吗?
    目录场景和痛点初级探讨1.深入理解业务需求与痛点2.模块化与灵活性设计3.数据驱动的智能决策4.安全与隐私保护6.成本与性能优化结语场景和痛点近日参与了一个银行核心系统方案的前期工作,与一名资深的银行资深架构师进行了交流,主要讨论在撰写银行核心系统方案......
  • MySQL 死锁
    死锁是指两个或两个以上的事务在执行过程中,因争夺锁资源而造成的一种互相等待的现象。1数据库层面解决死锁的两种方式1、解决死锁的问题最简单的方式是不要有等待,将任何的等待都转化为回滚,并且事务重新开始。 这种没有死锁问题的产生。在线上环境中,可能导致并发性能的下降,甚......
  • MySQL sleep 线程过多怎么解决
    1知道sleep线程过多原因首先要知道到底是什么原因导致的sleep线程过多的:程序逻辑问题,导致连接一直不释放;mysql参数的问题,是不是参数配置的不合理,一直不释放连接;mysql语句的问题,数据库查询不够优化,过度耗时。大并发情况问题,导致sleep情况过多;2临时解决s......
  • MySQL主从同步不一致解决办法
    一般主从同步错误首先要考虑是不是在从库中误操作导致的。结果发现,有人在从库中进行了一条针对有主键表的sql语句的插入,导致主库再插入相同sql的时候,主从状态出现异常。发生主键冲突的报错。解决方法:在确保主从数据一致性的前提下,可以在从库进行错误跳过。像从库如果不提供......
  • MySQL数据库出现乱码怎么解决
    为什么我的数据库总会出现中文乱码的情况。一堆中文乱码不知道怎么回事?当向数据库中写入创建表,并插入中文时,会出现这种问题。此报错会涉及数据库字符集的问题。.1解决乱码的几个方面对于中文乱码的情况,从三个方面数据终端:就是我们连接数据库的工具设置为utf8操作系统层面:l......
  • MySQL can't opet file(errno:24)
    有的时候,数据库跑得好好的,突然报不能打开数据库文件的错误了。解决思路:首先我们要先查看数据库的errorlog。然后判断是表损坏,还是权限问题。还有可能磁盘空间不足导致的不能正常访问表,操作系统的限制也要关注下,相关应用限制也要关注下;123#ulimit-n查看系统的......
  • MySQL 中删除重复数据 SQL 写法
    要在MySQL中删除重复的数据并只保留一条,可以使用下面的方法(要用的时候直接复制小改下条件和表名称即即可)方法一:使用leftjoin+子查询删除重复数据(推荐)温馨提示:本人在500w数据下执行此SQL耗费15s-30s左右使用leftjoin(推荐方法删除重复数据,添加唯一组......
  • MySQL练习2
    1.单表查询(1)素材表名:worker--表中字段均为中文,比如“部门号,工资,职工号,参加工作”等(2)创建worker表CREATETABLEworker (部门号 int(11) NOT NULL, 职工号 int(11) NOT NULL, 工作时间 date NOT NULL, 工资 float(8,2) NOT NULL, 政......