热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

MySQL的架构组成

导读为了更深刻的理解MySQL的运行和架构组成,写下这篇博客便于以后进行复习,你可以在这篇博客中学习到:1.MySQL的逻辑架构2.一条查询语句是如何执行的3.一条更新语句是如何执

导读

为了更深刻的理解 MySQL 的运行和架构组成,写下这篇博客便于以后进行复习,

你可以在这篇博客中学习到:

1.MySQL的逻辑架构

2.一条查询语句是如何执行的

3.一条更新语句是如何执行的

我想你在阅读之前带着几个疑问:

1.MySQL的架构有几个组件, 各是什么作用?

2.Server层和存储引擎层各是什么作用?

3.执行器的执行查询语句的流程是什么样的?


一:MySQL的逻辑架构

MySQL逻辑架构简单示意图:

image

MySQL在逻辑架构上包含了 Server 层和存储引擎层两大部分。



  • Server层:覆盖了MySQL的大多数核心服务,包含了连接池、查询缓存、分析器、优化器。执行器等,还有存储过程,触发器,视图等都在这一层,简单来说就是负责功能层面的事

  • 存储引擎层:负责数据的存储和提取,MySQL采用插件式的存储引擎,支持InnoDB、MyISAM、Memory等多个存储引擎,简单来说就是负责存储相关的事,

1.连接器

连接器用于用户权限验证,建立连接。从权限表里边查询用户权限并保存在一个变量里边以供查询缓存,分析器,执行器在检查权限的时候使用。



  • 如果客户端太长时间没有动静,连接器就会自动将它断开,断开时间参数 wait_timeout,默认是8小时,在连接断开之后,客户端再发生请求则会收到一个错误提醒

  • 长连接:连接成功后,如果客户端持续有请求,则一直使用同一个连接。

  • 短链接:每次执行完很少的几次查询就断开连接,下次查询再建立连接

由于连接过程始是复杂的,尽量减少连接动作,而使用长连接,但是临时使用的内存是管理在连接对象里面的,需要等到连接断开时才释放,从而导致内存占用太大,被系统强行杀掉。解决办法有两种

方法一:定期断开长连接,执行一个占用内存大的操作后,断开连接

方法二:每次执行一个比较大的操作后,执行 mysql_reset_connection 来初始化连接资源,不需要重连和重新做权限验证

2.查询缓存

用户权限通过,建立连接之后,Mysql 拿到查询请求,先去缓存中查询是否执行过这条语句,在缓存中,执行过的语句及结果,可能会以 key-value 的形式存储,如果执行过则返回结果,不需要再执行下面的步骤,极大的提高了效率。如果没有执行过,则继续执行后面的阶段,执行完成后,将结果存入缓存当中。但是大多数情况下不建议使用查询缓存,使用查询缓存往往弊大于利。因为查询缓存的失效非常频繁,只要有对一个表的更新,这个表上所有的查询缓存都会被清空,对于更新压力大的数据库来说,查询缓存的命中率会非常低。除非你的业务就是有一张静态表,很长时间才会更新一次。

3.分析器

缓存没有命中,则开始真正的执行语句了。Mysql 需要对 SQL语句进行解析,首先进行词法分析,主要是根据Mysql 的关键字进行验证和解析,然后做语法分析,进行表名和字段名的验证和解析。如果语句不对,则收到错误提醒。

注意:这个阶段才会打开表,知道有哪些表,进行语法分析,词法分析,检查sql语法顺序得到解析树

4.优化器

从分析器出来后,就到了优化阶段。优化器是在表里面有多个索引的时候,决定使用哪个索引;或者在一个语句有多表关联(join)的时候,决定各个表的连接顺序。不同的执行方法的逻辑结果是一样的,但是执行的效率会有不同,而优化器的作用就是根据不同的方案挑选出效率最高的执行方案

5.执行器

执行器阶段,开始执行 SQL 语句,开始执行的时候,要先判断一下你对这个表 T 有没有执行查询的权限,如果没有,就会返回没有权限的错误。如果有权限,就打开表继续执行。打开表的时候,执行器就会根据表的引擎定义,去使用这个引擎提供的接口。这个阶段是真正执行 SQL 语句的阶段,调用 InnoDB 接口从存储引擎中获取结果集

执行器的执行流程

select * from T where ID=10;
1.调用 InnoDB 引擎接口取表的第一行,判断 ID 值是否为10,不是则跳过,是则将这行存在结果集中
2.执行引擎接口取下一行,重复执行判断逻辑,直到取到表的最后一行
3.执行器将遍历过程中所有满足条件的行组成记录集作为结果集返回给客户端

二:一条查询语句是如何执行的

上面介绍 MySQL 组件的顺序,就是一条 SQL 查询语句执行的流程,我们大致的进行梳理一下。

1.连接验证: 我们需要通过 MySQL 的客户端工具机进行数据库的连接,首先遇到的就是连接池,进行权限验证。

2.查询缓存: 当连接通过之后,Mysql 拿到查询请求,先去缓存中查询是否执行过这条语句。如果执行过则返回结果,未命中则继续下面的流程。

3.语/词法分析: 缓存未命中后,进入分析器,进行语法和语义的分析,对关键字和表名字段进行验证和解析,如果不正确则收到错误提醒。

4.执行优化: 分析器通过后进入优化阶段,优化器选择执行效率最高的方案进行执行。

5.调用接口: 执行器就会根据表的引擎定义,去使用这个引擎提供的接口,获取结果集。


三:MySQL的物理组成

我们都直到 MySQL 可以恢复到半个月内任意一秒的状态,这是怎样做到的呢?

看一下 MySQL 的物理组成简单示意图:

image

可以分为日志文件和数据文件两大部分组成。

日志文件:包含了不同类型的日志文件

数据文件:数据文件主要指不同存储引擎的物理文件

1.二进制日志-binlog

位于Server 层的日志,是MySQL的重要日志模块,以二进制额形式,将所有修改数据的 query 记录到日志文件中,包括 query 语句、执行时间、相关事务信息等。

2.redo log

是存储引擎 InnoDB 生成的日志,是InnoDB引擎特有的,主要为了保证数据的可靠性。redo log 记录了 InnoDB 所做的所有物理变更和事务信息。

两种日志的区别:

1.redo log 是 InnoDB 引擎特有的;binlog 是 MySQL 的 Server 层实现的,所有引擎都可以使用。

2.redo log 是物理日志,记录的是“在某个数据页上做了什么修改”,;binlog 是逻辑日志,记录的是这个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ”,即SQL语句。

3.redo log 是循环写的,空间固定会用完;binlog 是可以追加写入的。“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。

4.redo log 是在事务执行过程不断的写入;binlog 是在事务最终提交前写入。

5.redo log 作为异常宕机或者介质故障后的数据恢复使用,binlog 可以应用于数据归档,主从搭建等场景。

那么为什么会有两份日志呢?

原因:在刚开始的时候,MySQL的执行引擎是MyISAM,不存在 crash-safe 的能力,只能用于数据归档,后来另一家公司Innobase Oy公司(2006年被甲骨文收购)创造了InnoDB,并且支持 crash-safe 能力,而且支持事务功能,所以再5.5之后的版本就默认使用 InnoDB 作为存储引擎

crash-safe:指数据库发生故障重启,之前提交的数据不会丢失


四:一条更新语句是如何执行的

更新语句内部执行流程:

update table_name set N=N+1 where id = 1;

1.执行器找引擎取 ID=2这一行,ID 是主键,引擎直接用树搜索找到这一行。如果这一行所在的数据页在内存当中,就直接返回给执行器,否则需要先从磁盘中读入内存,再返回

2.执行器拿到引擎给的行数据,把这个值加上 1,比如原来是 N,现在就是 N+1,得到新的一行数据,再调用引擎接口写入这行新数据

3.引擎将这行新数据更新到内存中,同时将这个更新操作记录到 redo log 里面,此时 redo log 处于 prepare 状态。然后告知执行器执行完成了,随时可以提交事务

4.执行器生成这个操作的 binlog,并把 binlog 写入磁盘

5.执行器调用引擎的提交事务接口,引擎把刚刚写入的 redo log 改成提交(commit)状态,更新完成

最后:

想要更深入学习的朋友可以去慕课看看:http://www.imooc.com/wiki/mysqladvanced/courseintroduction.html



推荐阅读
  • 阿里云MySQL与Oracle数据库的主从复制技术详解 ... [详细]
  • Presto:高效即席查询引擎的深度解析与应用
    本文深入解析了Presto这一高效的即席查询引擎,详细探讨了其架构设计及其优缺点。Presto通过内存到内存的数据处理方式,显著提升了查询性能,相比传统的MapReduce查询,不仅减少了数据传输的延迟,还提高了查询的准确性和效率。然而,Presto在大规模数据处理和容错机制方面仍存在一定的局限性。本文还介绍了Presto在实际应用中的多种场景,展示了其在大数据分析领域的强大潜力。 ... [详细]
  • PHP自学必备:从零开始的准备工作与工具选择 ... [详细]
  • 小王详解:内部网络中最易理解的NAT原理剖析,挑战你的认知极限
    小王详解:内部网络中最易理解的NAT原理剖析,挑战你的认知极限 ... [详细]
  • 如何有效防御网站中的SQL注入攻击
    本期文章将深入探讨网站如何有效防御SQL注入攻击。我们将从技术层面详细解析防范措施,并结合实际案例进行阐述,旨在帮助读者全面了解并掌握有效的防护策略。希望本文能为您的网络安全提供有益参考。 ... [详细]
  • Android中将独立SO库封装进JAR包并实现SO库的加载与调用
    在Android开发中,将独立的SO库封装进JAR包并实现其加载与调用是一个常见的需求。本文详细介绍了如何将SO库嵌入到JAR包中,并确保在外部应用调用该JAR包时能够正确加载和使用这些SO库。通过这种方式,开发者可以更方便地管理和分发包含原生代码的库文件,提高开发效率和代码复用性。文章还探讨了常见的问题及其解决方案,帮助开发者避免在实际应用中遇到的坑。 ... [详细]
  • 从运维繁忙到屡获殊荣:一位CIO的辉煌转型之路
    企业首席信息官(CIO)常常面临一个棘手的问题:如何有效推动公司的数字化转型?尽管数字化转型已成为企业未来发展的重要共识,但如何具体实施依然是许多CIO面临的重大挑战。在日常运营中,企业需要处理大量的业务问题和制定各种发展规划,这使得数字化转型往往被排在较低的优先级。此外,不断涌现的新问题和新规划也常常打乱原有的计划,进一步增加了转型的难度。 ... [详细]
  • REST与RPC:选择哪种API架构风格?
    在探讨REST与RPC这两种API架构风格的选择时,本文首先介绍了RPC(远程过程调用)的概念。RPC允许客户端通过网络调用远程服务器上的函数或方法,从而实现分布式系统的功能调用。相比之下,REST(Representational State Transfer)则基于资源的交互模型,通过HTTP协议进行数据传输和操作。本文将详细分析两种架构风格的特点、适用场景及其优缺点,帮助开发者根据具体需求做出合适的选择。 ... [详细]
  • 双精度除法与整数运算:性能与精度的权衡分析 ... [详细]
  • 在日常的项目开发中,测试环境和生产环境通常采用HTTP协议访问服务。然而,从浏览器的角度来看,这种访问方式会被标记为不安全。为了提升安全性,当前大多数生产环境已经转向了HTTPS协议。本文将详细介绍如何在Spring Boot应用中配置SSL证书,以实现HTTPS安全访问。通过这一过程,不仅可以增强数据传输的安全性,还能提高用户对系统的信任度。 ... [详细]
  • SSAS入门指南:基础知识与核心概念解析
    ### SSAS入门指南:基础知识与核心概念解析Analysis Services 是一种专为决策支持和商业智能(BI)解决方案设计的数据引擎。该引擎能够为报告和客户端应用提供高效的分析数据,并支持在多维数据模型中构建高性能的分析应用。通过其强大的数据处理能力和灵活的数据建模功能,Analysis Services 成为了现代 BI 系统的重要组成部分。 ... [详细]
  • 手指触控|Android电容屏幕驱动调试指南
    手指触控|Android电容屏幕驱动调试指南 ... [详细]
  • 老杨谈IT运维 | 快速实现日志异常检测与根源分析
    在智能运维领域,指标和日志是最常用的数据来源,能够有效反映系统的运行状况和健康状态。通过对这些数据的深入分析,可以为监控和告警系统提供关键信息,帮助快速实现日志异常检测与根源分析,提升整体运维效率。 ... [详细]
  • 在Android开发过程中,序列化是一个重要的概念,尤其是在数据传输和存储时。本文详细解析了Parcelable序列化的原理及其应用场景,并对比了其他序列化方式,如Serializable。通过具体的实例和代码示例,帮助开发者更好地理解和掌握Parcelable的使用方法,避免在实际开发和面试中遇到相关问题。 ... [详细]
  • 业务团队与独立团队在数据分析领域的效能对比:谁更胜一筹?
    业务团队与独立团队在数据分析领域的效能对比:谁更胜一筹? ... [详细]
author-avatar
米字格时光
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有