欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

重识MySQL -《MySQL是怎样运行的》

程序员文章站 2022-03-21 15:37:25
重识MySQLMySQL的客户端/服务器架构MySQL的安装启动MySQL服务器程序启动MySQL客户端程序客户端与服务器连接的过程TCP/IP命名管道和共享内存UNIX域套接字服务端处理客户端请求连接管理解析与优化查询缓存语法解析查询优化存储引擎设置表的存储引擎  最近看了小孩子4919写的《MySQL是怎样运行的》,重新认识了MySQL,下面做一个总结。佩服作者有勇气辞职在家去写作,干自己喜欢的事情。之前掘金就买了作者的小册子,献上微薄之力支持。MySQL的客户端/服务器架构  我们使用的微信Ap...


  最近看了小孩子4919写的《MySQL是怎样运行的》,重新认识了MySQL,下面做一个总结。佩服作者有勇气辞职在家去写作,干自己喜欢的事情。之前掘金就买了作者的小册子,献上微薄之力支持。

MySQL的客户端/服务器架构

  我们使用的微信App就是由客户端和服务器组成的。聊天的时候,客户端将用户发送的消息包装后发送给微信服务器,然后微信服务器根据收到的包装好的信息将消息发送给接收者。
  MYSQL的运行过程类似,它的服务端程序也可以连接多个客户端,客户端需要通过用户名密码登录服务器以后才能向服务器发送请求。服务器程序根据客户端发送的CRUD请求直接与要存储的数据打交道,对数据做出相应的处理并将结果返回给客户端。

MySQL的安装

  以mac为例,安装好MySQL以后在安装目录下的bin目录中存放着许多可执行文件,执行这些可执行文件可以通过使用这些文件的相对/绝对路径来执行。例如当前在安装目录(/usr/local/mysql),要执行bin目录下的mysqld的可执行文件。

#使用相对路径执行
./bin/mysqld
#使用绝对路径
/usr/local/mysql/bin/mysqld

启动MySQL服务器程序

  Mac中用来启动MySQL服务器程序的可执行文件很多,且大部分都位于MySQL安装目录的bin目录下。

  1. mysqld
      mysqld可执行文件就表示MySQL服务器程序,运行它就可以直接启动一个MySQL服务器进程,但并不常用。
  2. mysqld_safe
      mysqld_safe是一个启动脚本,他会间接调用mysqld并持续关注服务器的运行状态。当服务器进程出现错误时,它还可以帮助重启服务器程序,并且可以将出错信息和其他诊断信息输出到错误日志中。
  3. mysql_server
      mysql_server也是一个启动脚本,它间接地调用mysqld_safe。mysql_server其实是一个链接文件,它对应的实际文件是…/support-files/mysql.server。安装MySQL时如果没有自动安装这个脚本则需要手动安装。
#启动服务器程序
mysql_server start
#关闭正在运行的服务器程序
mysql_server stop
  1. mysqld_multi
      其实一台计算机可以运行多个服务器实例,mysqld_multi可执行文件可以启动或停止多个可执行文件,也能报告他们的运行状态。

启动MySQL客户端程序

  在成功启动服务器程序后,就可以启动客户端程序来连接到这个服务器了。通过mysql这个可执行程序我们可以与服务器程序进行交互。

mysql -h主机名 -u用户名 -p密码

各参数之间无先后顺序:
  -h:等同于--host= 主机名,表示服务器程序所在计算机的IP或者域名,如果服务器程序运行在本机则可以省略,也可使用localhost或127.0.0.1代替。
  -u:等同于--user= 用户名,表示用户名。
  -p:等同于--password= 密码,表示密码。

连接成功后我们可以通过在mysql>提示符后面输入以下任一命令退出登录:

  • quit
  • exit
  • \q

注意事项:

1、如果客户端在登录时通过一行显示输入密码就被同一台机器的其他用户通过ps之类的命令看到,所以并不安全,可以直接-p回车然后再输入密码。
2、显式输入密码时,-p和密码之间不能用空白字符,否则可能会导致服务器将密码当作数据库名称来对待。
3、Mac中省略-u的话会将登录操作系统的用户名当作MySQL的用户名去处理。

客户端与服务器连接的过程

  运行中的服务器程序和客户端程序本质上都是计算机中的一个进程,所以客户端程序向服务器程序发送请求并得到响应的过程本质上是一个进程间通信的过程。MySQL支持下面几种通信方式。

TCP/IP

  MySQL采用TCP作为服务器和客户端之间的网络通信协议。在网络环境下,每台计算机都有唯一的IP地址,如果某个进程需要采用TCP协议进行网络通信,就可以向操作系统申请一个端口号(范围:0~65535)。其他进程就可以通过IP+端口的方式与这个进程建立连接了。
  MySQL服务器启动时默认申请3306端口,如果3306端口刚好被占用或者我们想自定义该服务器进程监听的端口号,可以通过在启动服务器程序的命令行中添加-P参数来明确指定端口号。

mysqld -P3307

#也可以在通过命令启动客户端程序时通过使用-P参数指定要连接的端口号
mysqld -h127.0.0.1 -uroot -P3307 -p

命名管道和共享内存

  命名管道和共享内存是Windows操作系统中的两种进程间通信方式。使用他们需要在启动服务器程序和客户端程序时添加一些参数。

  • 使用命名管道进行进程间通信:需要在启动服务器程序的命令中加上--enable-named-pipe参数,在启动客户端程序的命令中加上--pipe或者--protocol=pipe参数。
  • 使用共享内存进行进程间通信:要求服务器进程和客户端进程必须位于同一台Windows主机,需要在启动服务器程序的命令中加上--shared-memory参数,在成功启动服务器后,共享内存便成为本地客户端程序的默认连接方式。也可以在启动客户端程序的命令中加上--protocol=memory参数来显式指定使用共享内存进行通行。

UNIX域套接字

  如果服务器进程和客户端进程运行在同一台类UNIX操作系统上,则可以使用UNIX域套接字进行进程间的通信。如果在启动客户端程序时没有指定主机名,或者指定的主机名为localhost,又或者指定了--protocol=socket的启动参数,那么服务器程序和客户端程序就可以通过UNIX域套接字进行通信了。

服务端处理客户端请求

  服务器程序在处理客户端的请求时大致分为3部分:连接管理、解析与优化、存储引擎。

连接管理

  客户端进程通过以上几种进程间通信方式与服务器进程建立连接。每当有一个客户端进程连接到服务器进程时,服务器进程都会创建一个线程专门处理与这个客户端的交互;当客户端退出连接时,服务器并不会立即将该线程销毁,而是将它缓存起来,在另一个新的客户端进行连接时,将该线程分配给新的客户端。这样就通过减少创建销毁线程而节省了开销。由于分配太多线程会严重影响系统的性能。所以我们需要限制可以同时连接到服务器的客户端数量。
  在客户端程序发起连接时,需要携带主机信息、用户名、密码等信息,服务器程序会这些信息进行认证,认证失败则拒绝连接。当客户端程序和服务端程序不运行在一台机器上时,我们可以通过采用传输层安全性(Transport Layer Security,TLS)协议对连接进行加密来保证数据传输的安全性。
  当连接建立后,与该客户端关联的服务器线程会一直等待客户端发送过来的请求。MySQL服务器接收到的请求只是一个文本信息,该文本信息还要经过各种处理。

解析与优化

查询缓存

  MySQL服务器程序会讲刚刚处理过的查询请求和结果缓存起来,如果下一次有同样的请求过来则直接从缓存中查找结果。这个查询缓存可以在不同的客户端之间共享。如果两个查询请求有任何字符上的不同(例如:空格、注释、大小写),都会导致缓存不命中。另外,如果查询请求中包含某些系统函数、用户自定义变量和函数、系统表,如mysql、information_schema、performance_schema数据库中的表,则这个请求不会被缓存。因为某些系统函数两次调用的结果可能不一样,比如函数NOW。
  MySQL的缓存系统会监控涉及的每张表,只要该表的结构或者数据被修改,则与该表有关的所有查询缓存都将变为无效并从查询缓存中删除。比如使用了INSERT、UPDATE、DELETE、TRUNCATE TABLE、ALTER TABLE、DROP TABLE或DROP DATABASE语句。
  虽然查询缓存有时可以提升系统性能,但也因维护缓存而造成了一些开销。从MySQL5.7.20开始不推荐使用查询缓存,在MySQL8.0中直接将其删除。

语法解析

  因为客户端发送过来的请求只是一段文本,如果查询缓存没有命中,则MySQL服务器程序首先要对这段文本进行分析。判断请求的语法是否正确,然后从文本中将要查询的表、各种查询条件都提取出来放到MySQL服务器内部使用的一些数据结构上。

查询优化

  语法解析后,服务器程序获得到了需要的信息,MySQL还会对语句做一些优化来提高执行效率,如外连接转化为内连接、表达式简化、自查询转化为连接等等。优化的结果就是生成了一个执行计划,表明了应该使用哪些索引执行查询,以及表之间的连接顺序是怎样等等。我们可以通过EXPLAIN语句来查看某个语句的执行计划。

存储引擎

  服务器程序完成查询优化后还没有真正地去访问真实的表中数据(查询优化期间可能访问表中少量数据)。MySQL服务器把数据的存储和提取操作都封装到了一个名为存储引擎的模块中。为了实现不同的功能,MySQL提供了各式各样的存储引擎,不同存储引擎管理的表可能有不同的存储结构,采用的存取算法也可能不同。
  MySQL服务器处理客户端请求的过程可简单划分为server层和存储引擎层,各种不同的存储引擎为server层提供统一的调用接口,其中包括了几十个不同用途的底层函数。
server层和存储引擎层的交互一般以记录为单位。server层在判断某条记录符合要求后,其实是先将其发送到一个缓冲区,待到该缓冲区满了,才向客户端发送真正的记录。该缓冲区的大小由系统变量net_buffer_length控制。
  MySQL支持很多种存储引擎,最常用的是InnoDB和MyISAM。InnoDB从MySQL5.5.5版本开始作为了MySQL的默认存储引擎,之前版本的默认存储引擎为MyISAM。

--查看当前服务器程序支持的存储引擎
SHOW ENGINES;

返回结果中的SUPPORT列表示该存储引擎是否可用,DEFAULT值代表当前服务器程序的默认存储引擎;Comment列是对存储引擎的一个描述;Transaction列表示该存储引擎是否支持事务处理;XA列代表该存储引擎是否支持分布式事务;Savepoints列代表该存储引擎是否支持事务的部分回滚。

设置表的存储引擎

我们可以为不同的表设置不同的存储引擎,也就是说,不同的表可以有不同的物理存储结构、不同的读取和写入方式。如果在创建表时没有显式指定存储引擎则使用默认存储引擎InnoDB。

CREATE TABLE engine_demo_table(
	建表语句;
)ENGINE = 存储引擎名称;

如果表已经创建好了,可以通过以下语句来修改表的存储引擎

ALTER TABLE 表名 ENGINE = 存储引擎名称;
--查看表结构
SHOW CREATE TABLE 表名;

本文地址:https://blog.csdn.net/yang_girl/article/details/109500852

相关标签: MySQL