【MYSQL】MySQL整体结构

无论你是前端还是后端,只要是一个合格的开发者,对于MySQL这个名词相信都不陌生,MySQL逐渐成为了最受欢迎的关系型数据库,无论你是大前端,亦或是Java、Go、Python、C/C++、PHP....等这些语言的程序员,对于MySQL是必然要掌握的核心技术之一,程序员不能没有MySQL,就像西方不能失去耶路撒冷一般。

   当然,MySQL也不仅仅是唯一的数据库,与它类似的关系型数据库竞品还有很多,例如Oracle、SQLServer、PostgreSQL、DB2....,这其中使用最为广泛的是Oracle,但Oracle实际上并不怎么受程序员欢迎,或者说Oracle并不怎么受中小企业的Boss欢迎,原因嘛大家都清楚,无非因为它收费罢了。

也正是由于Oracle收费的原因,才导致MySQL像如今这么流行,正所谓时势造英雄,MySQL作为免费的开源数据库,也正是抓住了这个风口,所以才越发流行。对于MySQL,用一句话形容很贴切:“天不生我MySQL,编程万古如长夜”。

一、MySQL概述与系列预告

MySQL数据库是由瑞典的MySQL AB公司开发的,后面这家企业被Sun公司收购,最后Sun公司又被Oracle74亿美元收购,所以本质上MySQL现在隶属于Oracle旗下,因此大家也会发现,MySQL后面的高版本会有收费版出现。

实际上如果MySQL没有并入Oracle的话,是有很大几率问鼎数据库榜首的,造化弄人。

整个MySQL系列会按上述目录进行全面阐述,但上述目录只是预期规划内容,实际撰写过程中可能会适当调整,但给出的技术点都会事无巨细的讲到,内容只多不少,因此大家感兴趣的话,可以点个关注,由我伴随诸君一同彻底掌握MySQL数据库。

二、MySQL整体结构浅析

   本章作为MySQL系列的开篇之作,当然也有一定的原因,毕竟只有先对MySQL的整体架构有了一个宏观的认知,才能更好的理解每个细节点的知识。

   MySQL与我们开发项目时相同,为了能够合理的规划整体架构设计,也会将整个MySQL服务抽象成几个大的模块,然后在内部进行实现,因此先来看看MySQL的整体架构,开局先上一张图:

从上往下看,依次会分为网络连接层、系统服务层、存储引擎层、以及文件系统层,往往编写SQL后,都会遵守着MySQL的这个架构往下走。

  • 连接层:主要是指数据库连接池,会负责处理所有客户端接入的工作。
  • 服务层:主要包含SQL接口、解析器、优化器以及缓存缓冲区四块区域。
  • 存储引擎层:这里是指MySQL支持的各大存储引擎,如InnoDB、MyISAM等。
  • 文件系统层:涵盖了所有的日志,以及数据、索引文件,位于系统硬盘上。

OK~,除了上述的四层外,还有客户端,这个客户端可以是各类编程语言,如Java、Go、Python、C/C++、PHP、Node、.Net....,也可以是一些数据库的可视化软件,例如Navicat、SQLyog等,也可以是mysql-cli命令行工具。总之,只要能与MySQL建立网络连接,都可以被称为是MySQL的客户端。

MySQL-Server就是上述图中的那玩意儿,一般来说,客户端负责编写SQL,而服务端则负责SQL的执行与数据的存储。

MySQL的整体架构有了简单了解后,接下来详细的拆解一下MySQL-Server的每个层面。

三、网络连接层

   在之前的《网络之旅》的文章中,我们提到过一点:当一个客户端尝试与MySQL建立连接时,MySQL内部都会派发一条线程负责处理该客户端接下来的所有工作。而数据库的连接层负责的就是所有客户端的接入工作,MySQL的连接一般都是基于TCP/IP协议建立网络连接,因此凡是可以支持TCP/IP的语言,几乎都能与MySQL建立连接。

其实MySQL还支持另一种连接方式,就是Unix系统下的Socket直连,但这种方式一般使用的较少。

   虽然MySQL是基于TCP/IP协议栈实现的连接建立工作,但并非使用HTTP协议建立连接的,一般建立连接的具体协议,都会根据不同的客户端实现,如jdbc、odbc...这类的。在这里先暂且不纠结连接MySQL时的协议类型,先来看看一般是怎么连接MySQL的?如下:

mysql -h 127.0.0.1 -uroot -p123456

例如上述这条指令,-h表示MySQL所在的服务器IP地址,-u表示本次连接所使用的用户名,-p则代表着当前用户的账号密码,当执行这条指令后,会与MySQL-Server建立网络连接,也就是会经历《TCP的三次握手过程》。当然,MySQL也支持SSL加密连接,如果采用这种方式建立连接,那还会经过《SSL多次握手过程》,当握手结束,网络建立成功后,则会开始正式的数据库连接建立工作。

TCP网络连接建立成功后,MySQL服务端与客户端之间会建立一个session会话,紧接着会对登录的用户名和密码进行效验,MySQL首先会查询自身的用户表信息,判断输入的用户名是否存在,如果存在则会判断输入的密码是否正确,如若密码错误或用户名不存在就会返回1045的错误码,如下信息:

ERROR 1045 (28000): Access denied for user 'zhuzi'@'localhost' (using password: YES)

如果你在连接数据库的过程中,出现了上述的错误信息,那绝对是你输入的用户名或密码错误导致的,当账号及密码正确时,此时就会进入MySQL的命令行,接下来可以执行SQL操作。

但实际上,在用户名和密码都正确的情况下,MySQL还会做一些些小动作,也就是会进行授权操作,查询每个用户所拥有的权限,并对其授权,后续SQL执行时,都会先判断是否具备执行相应SQL语句的权限,然后再执行。

OK~,经过上述流程后数据库连接就建立成功了,数据库连接建立成功后,MySQL与客户端之间会采用半双工的通讯机制工作,与之对应的还有“全双工、单工”的工作模式:

  • 全双工:代表通讯的双方在同一时间内,即可以发送数据,也可以接收数据。
  • 半双工:代表同一时刻内,单方要么只能发送数据,要么只能接受数据。
  • 单工:当前连接只能发送数据或只能接收数据,也就是“单向类型的通道”。

到这里,MySQL也会“安排”一条线程维护当前客户端的连接,这条线程也会时刻标识着当前连接在干什么工作,可以通过show processlist;命令查询所有正在运行的线程:

执行结果如下(root账号可以查询所有线程):

  • Id:当前线程的ID值,可以利用这个ID,使用kill强杀线程。
  • User:当前线程维护的数据库连接,与之对应的用户是谁。
  • Host:与当前线程保持连接关系的客户端地址(IP+Port)。
  • db:目前线程在哪个数据库中执行SQL
  • Command:当前线程正在执行的SQL类型,如:
    • Create DB:正在执行创建数据库的操作。
    • Drop DB:正在执行删除数据库的操作。
    • Execute:正在执行预编译的SQLPreparedStatement)。
    • Close Stmt:正在关闭一个PreparedStatement
    • Query:正在执行普通的SQL语句。
    • Sleep:正在等待客户端发送SQL语句。
    • Quit:当前客户端正在退出连接。
    • Shutdown:正在关闭MySQL服务端。
  • Time:表示当前线程处于目前状态的时间,单位是秒。
  • State:表示当前线程的状态,有如下几种:
    • Updating:当前正在执行update语句,匹配数据做修改操作。
    • Sleeping:正在等待客户端发送新的SQL语句。
    • Starting:目前正在处理客户端的请求。
    • Checking table:目前正在表中查询数据。
    • Locked:当前线程被阻塞,其他线程获取了执行需要的锁资源。
    • Sending Data:目前执行完成了Select语句,正在将结果返回给客户端。
  • Info:一般记录当前线程正在执行的SQL,默认显示前一百个字符,查看完整的SQL可以使用show full processlist;命令。

其实从这个结果上来看,我们能够很明显的看到数据库中各个线程的信息,这条指令对于以后做线上排查时有很大的作用,目前先简单了解,接着来看看数据库连接池。

3.1、数据库连接池(Connection Pool)

   Connection Pool翻译过来的意思就是连接池,那为什么需要有这个东西呢?因为前面聊到过,所有的客户端连接都需要一条线程去维护,而线程资源无论在哪里都属于宝贵资源,因此不可能无限量创建,所以这里的连接池就相当于Tomcat中的线程池,主要是为了复用线程、管理线程以及限制最大连接数的。

   连接池的最大线程数可以通过参数max-connections来控制,如果到来的客户端连接超出该值时,新到来的连接都会被拒绝,关于最大连接数的一些命令主要有两条:

  • show variables like '%max_connections%';:查询目前DB的最大连接数。
  • set GLOBAL max_connections = 200;:修改数据库的最大连接数为指定值。

对于不同的机器配置,可以适当的调整连接池的最大连接数大小,以此可以在一定程度上提升数据库的性能。除了可以查询最大连接数外,MySQL本身还会对客户端的连接数进行统计,对于这点可以通过命令show status like "Threads%";查询:

其中各个字段的释义如下:

  • Threads_cached:目前空闲的数据库连接数。
  • Threads_connected:当前数据库存活的数据库连接数。
  • Threads_createdMySQL-Server运行至今,累计创建的连接数。
  • Threads_running:目前正在执行的数据库连接数。

对于几个字段很容易理解,额外要说明的一点是Threads_cached这个字段,从名称上来看,似乎跟缓存有关系,其实也没错,因为这里是有一个数据库内部的优化机制。当一个客户端连接断开后,对于数据库连接却不会立马销毁,而是会先放入到一个缓存连接池当中。这样就能在下次新连接到来时,省去了创建线程、分配栈空间等一系列动作,但这个值不会是无限大的,一般都在32左右。

连接池的优化思想与Java线程池相同,会将数据库创建出的连接对象放入到一个池中,一旦出现新的访问请求会复用这些连接,一方面提升了性能,第二方面还节省了一定程度上的资源开销。

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

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

相关文章

蓝牙技术在智能硬件中应用火热,你的蓝牙适配测试如何解决?

蓝牙技术在物联网中的应用非常广泛,可以为人们的生活和工作带来更多的便利和智能化体验,主要五大核心应用场景,具体如下: 1、智能家居 通过蓝牙连接智能家居设备,如智能灯泡、智能插座、智能恒温器等,可以…

Android Emulator 构建和启动

Android Emulator 构建和启动 AVD 的创建和启动 欢迎入群交流 编译模拟器 下载Android源码 参考文章 Android AOSP 下载和编译 source ./build/envsetup.sh编译x86-64,userdebug版本 lunch sdk_phone_x86_64-userdebug编译arm64,userdebug版本 lunch sdk_phone_arm64-userd…

Python列表到Excel表格第一列的转换技术详解

目录 一、Python列表与Excel表格的关系 二、所需工具与库 三、使用openpyxl将列表写入Excel第一列 四、使用pandas将列表写入Excel第一列 五、案例分析与注意事项 六、扩展应用与进阶学习 七、总结与展望 在数据处理和分析中,经常需要将Python中的数据&#…

【复习笔记】FreeRTOS(六) 队列操作

本文是FreeRTOS复习笔记的第六节,队列操作。 上一篇文章: 【复习笔记】reeRTOS(四) 列表项的插入和删除 文章目录 1.队列操作1.1.队列操作过程1.2.队列操作常用的API函数 二、实验设计三、测试例程四、实验效果 1.队列操作 队列是为了任务与任务、任务与…

Java编程练习之多重继承

在Java中类不允许多重继承,但使用接口可以实现多重继承,因为一个类可以同时实现多个接口,这样可以将所有需要实现的接口放在implements关键字后,并使用英文逗号隔开,但这可能会在一个类中产生庞大的代码量,…

【C++】1390-请从键盘读入一个四位整数,求这个四位整数各个位的和是多少?

问题:1390-请从键盘读入一个四位整数,求这个四位整数各个位的和是多少? 类型:基础问题 题目描述: 请从键盘读入一个四位整数,求这个四位整数各个位的和是多少? 输入: 一个四位整…

有条件的打破IBGP水平分割----反射规则和联邦+实验举例

背景:在一个AS中的设备运行了BGP协议,那么正常应该都连接了其他的AS,存在EBGP邻居关系;又由于IBGP的水平分割规则,导致从外部学习到的路由传递给本地AS时,需要和本地AS中运行BGP协议都要建立IBGP邻居关系&a…

python中time库的time.time()函数的作用是什么?

python中time库的time.time()函数的作用是什么? 作用:Python time time() 返回当前时间的时间戳(1970纪元后经过的浮点秒数)。 time()方法语法:time.time() #!/usr/bin/python # Write Python 3 code in this onlin…

PostgreSQL入门到实战-第二十八弹

PostgreSQL入门到实战 PostgreSQL中数据分组操作(三)官网地址PostgreSQL概述PostgreSQL中GROUPING SETS命令理论PostgreSQL中GROUPING SETS命令实战更新计划 PostgreSQL中数据分组操作(三) 使用PostgreSQL grouping sets子句在查询中生成多个分组集。 官网地址 声明: 由于操…

C++ UML 类图介绍与设计

1 类图概述 UML(Unified Modeling Language),即统一建模语言,是用来设计软件的可视化建模语言。它的特点是简单、统一、图形化、能表达软件设计中的动态与静态信息。UML从目标系统的不同角度出发,定义了用例图、类图、对象图、状态图、活动图…

Unity 通过权重做随机

我们可以通过Random.Range方法结合权重来实现随机选择。具体步骤如下: 首先,创建一个数组,其中包含你要选择的项目,并为每个项目分配一个权重值。 计算所有权重值的总和。 使用Random.Range生成一个介于0和总权重之间的随机数。…

消除 BEV 空间中的跨模态冲突,实现 LiDAR 相机 3D 目标检测

Eliminating Cross-modal Conflicts in BEV Space for LiDAR-Camera 3D Object Detection 消除 BEV 空间中的跨模态冲突,实现 LiDAR 相机 3D 目标检测 摘要Introduction本文方法Single-Modal BEV Feature ExtractionSemantic-guided Flow-based AlignmentDissolved…