单进程多线程数据库
可以看下 这里 了解 mysql 各层的介绍 ebc5f39f527d427995c698af582feb81.png

1. mysql 分层:

客户端和 server 的连接,主要有以下几种方式:(进程间通信以及通信协议有关)
https://dev.mysql.com/doc/refman/8.0/en/transport-protocols.html#transport-protocol-selection

  1. 对于本地的数据库连接,客户端和 Mysql 服务器在同一台电脑时:使用 Unix 套接字 ( 非网络协议 ) 和 管道进行通信(即进程间通信)

看下操作系统(点这里)

  1. 对于任何系统下都可使用 TCP / IP ,对于同一主机使用进程间通信,对于不同主机则需要TCP/ IP 协议

不记得的话 看这里(tcp / ip 协议)


1.1.2 通信过程 (授权认证过程以及权限相关)

https://www.cnblogs.com/qiumingcheng/p/10655142.html

1.1.2.1 握手认证过程

握手认证阶段为客户端与服务器建立连接后进行,交互过程如下:
服务器 -> 客户端:握手初始化消息
客户端 -> 服务器:登陆认证消息
服务器 -> 客户端:认证结果消息

1.1.2.2 命令执行过程

客户端认证成功之后,进入命令执行阶段,交互过程:
客户端 -> 服务器:执行命令消息
服务器 -> 客户端:命令执行结果
image.png

  • 为什么在握手认证的时候,是由服务器发送握手初始化,这和 http 中的三次握手不一致:
  • 为什么服务器能在没有请求的情况下主动进行相应
  1. 首先 http 中的 三次握手 只要有 url 地址,就能发送请求,进行操作,但是 mysql 必须登录之后才能进行操作,这和 http 不一致。
  2. 服务器主动发送握手初始化,是存在原因的,我们可以通过mysql 官方文档来看

Mysql 服务器官方文档 MySQL 的服务器,进行初始化后,需要我们主动启动服务器,也就是 netstart,然后会自动监听端口。mysqld 是一个单一的多线程程序。


1.1.3 Mysql 的连接方式(进行完物理连接以及通信认证之后,开始发送sql 命令)

假如有连接,那就存在 短连接 和 长连接 (关于 短连接 和 长连接

  • 对于短连接,每次操作数据库都需要打开和关闭数据库,连接 -> 数据传输 -> 关闭连接
  • 对于长连接,程序之间的连接建立之后,就一直打开,被后续程序重复使用。

两者都存在问题:短连接 的话,每次创建线程的开销较大,端口资源可能不够用。对于 长连接,假如建立了长连接,则有可能有很多长连接处于 无请求 状态,同样导致内存的浪费。

所以使用 连接池 和 线程池 组合,来进行性能提升

1.1.3.1 连接池:

在客户端部署。客户端创建预先创建一定的连接,利用这些连接服务于客户端所有的DB请求。如果某一个时刻,空闲的连接数小于DB的请求数,则需要将请求排队,等待空闲连接处理。通过连接池可以复用连接,避免连接的频繁创建和释放,从而减少请求的平均响应时间,并且在请求繁忙时,通过请求排队,可以缓冲应用对DB的冲击。当连接断开,连接将回归连接池。

连接池主要用来管理客户端的连接,避免重复的连接/断开操作,是将空闲的连接缓存起来,可以复用。从而减少了连接mysql server/断开mysql server的开销与成本,从而提升性能。

1.1.3.2 线程池:

在服务器端部署。通过创建一定数量的线程服务DB请求,有了线程池,当有了新连接,可以直接从线程池里拿线程,断开时,也不销毁线程,而是回放进线程池。与一个线程服务一个连接的方式对比,线程池服务的最小单位是语句,即一个线程可以对应多个活跃的连接。通过线程池,可以将server端的服务线程数控制在一定的范围,减少了系统资源的竞争和线程上下切换带来的消耗,同时也避免出现高连接数导致的高并发问题。

线程池存在的问题:
1. 调度死锁问题:
假设,A,B两个事务被分配到不同的group中执行,A事务已经开始,并且持有锁,但由于A所在的group比较繁忙,导致A执行一条语句后,不能立即获得调度执行;而B事务依赖A事务释放锁资源,虽然B事务可以被调度起来,但由于无法获得锁资源,导致仍然需要等待,这就是所谓的调度死锁。
image.png
解决方法:
创建优先队列,将已经开启持有锁的连接 或者 已经开启事务的连接 发起的请求放入优先队列,让线程早点解放。工作线程应该首先从优先队列获取任务执行。


1.2 sql 层

功能:解析器,授权,优化器,查询执行,查询告诉缓存,查询日志记录,跨存储引擎功能。
处理数据流程,下图:
image.png

1.2.1 接口:

接受用户的 SQL 命令,并且返回用户需要查询的结果,比如 select from 就是调用 接口。

1.2.2 解析器:

SQL 命令传递到解析器的时候,会被解析器验证和解析(进行语义和语法的分析,分解数据结构),生成 sql 解析树。
第一步,词法分析,一条 SQL 语句有多个字符串组成,首先要提取关键字,比如 select,提出查询的表,提出字段名,提出查询条件等等。做完这些操作后,就会进入第二步。
第二步,语法分析,主要就是判断你输入的 sql 是否正确,是否符合 MySQL 的语法。
完成这 2 步之后,MySQL 就准备开始执行了,但是如何执行,怎么执行是最好的结果呢?这个时候就需要优化器上场了。

1.2.3 查询优化器:

SQL 语句在查询之前会使用查询优化器对查询进行优化,根据客户端请求的 query 语句,和数据库中的一些统计信息,在一系列算法的基础上进行分析,得到最优策略,即执行计划。

1.2.4 执行器:

开始执行的时候,要先判断以下对这个表有没有执行查询的权限。如果没有,就会返回没有权限的错误。
如果有权限,就打开表继续执行。打开表的时候,执行器就会根据表的引擎定义,去使用相关的接口。
image.png
最后将结果集返回给客户端,至此语句执行完成。


1.3 存储引擎层:

存储引擎,也称为表类型,真正的负责了MySQL中数据的存储和提取,储存引擎层由多种存储引擎共同组成。它们负责存储和获取所有存储在MySQL中的数据。就像Linux众多的文件系统 一样。每个存储引擎都有自己的优点和缺陷。服务器是通过存储引擎API来与它们交互的。存储引擎不能解析SQL,互相之间也不能通信。
MySQL的存储引擎是插件式的,也就是说,用户可以随时切换MySQL的存储引擎:针对表或针对库都可(通过SQL语句命令)。

1.3.1 流程

  1. 1. 根据上层获取数据的方法(执行计划),将数据提取出来
  2. 2.重新交给 SQL
  3. 3.MYSQL数据库的核心,关系到数据库性能
  4. 4.存储引擎基于表,而非数据库

1.3.2 常见引擎

存储引擎 特点
Innodb 事务安全,但对比myIsam,写效率差一些
myIsam 支持事务,但是和Innodb的事务支持不同
Memory 数据存储在内存之中

面试经常会问 Innodb 和 MyISAM 的区别,看这里

1.4 面试常见问题:

MySQL 的执行过程
锁机制
存储引擎的区别
事务的隔离级别
几种可能出现的数据库问题


总结:
image.png

连接过程 运行过程 执行过程