Mysql 是怎样运行的:从根上理解Mysql 读后个人总结
初识 MySQL
通信介绍
MySQL 也是典型的 C / S 模型,分为客户端及服务端,服务端一般部署在远端服务器中,也可以部署至本地,然后客户端跟服务端通信则可以使用依赖网络的 TCP 长连接或 Unix-like 的系统下可以使用 Socket文件的形式通信
连接阶段
客户端跟服务器端通信,MySQL 服务器会维护为每个客户端请求建立一个线程专门处理请求
连接可以通过 SSL 保证传输安全性,实际情况一般都是通过 SSL 访问跳板机再通过内网地址访问到 MySQL 服务器
MySQL 服务器也会通过用户名,密码,主机信息来做认证,判断是否提供对应权限的服务
查询缓存阶段
MySQL 服务器为提供查询效率,所以加入了全局缓存,当缓存命中时可以直接返回结果。但是实际两个请求只要有任何字符上的不一样,都会导致缓存不能命中,同时对于读写相差不多或写多读少的表,每次写操作都会导致缓存失效造成不必要的开销,所以在 MySQL 5.7+ 版本中该功能以及被废弃,MySQL 8.0+ 版本中被移除
语法解析阶段
如果缓存没有命中,MySQL 服务接下去就会开始解析 SQL 语句,如果有语法错误则直接返回至客户端,没有问题则会将 SQL 语句转换为 MySQL 内部的数据结构(解析树)
查询优化
语法解析之后,MySQL 服务器已经知道客户端想如何去获取数据,接下来服务器会对语句的执行进行优化,例如外连接转换为内连接,表达式简化,子查询转换为连接之类的,这部分优化不会对查询结果有影响,类似于数学上的因式分解,但是执行效率更高。完成优化后,生成的结果就是执行计划,这时根据执行计划就可以知道该从哪个表,使用哪个索引,查询哪些数据等所有的具体操作。
我们可以使用 EXPLAIN
语句查询某个 SQL 的执行计划,然后对 SQL 进行优化
存储引擎
当拥有执行计划后,MySQL 服务接下去就要真正的去持久化的区域,将数据取出来交给客户端,这里为了能支持各种各样的持久化策略,MySQL 对下层的所有控制都依赖于统一的存储引擎 API,然后不同的存储引擎提供各自的具体实现
不同的存储引擎,目标场景不同,实现方式与特性也不同,可以根据实际场景进行选择,场景的存储引擎如下:
存储引擎 | 描述 |
---|---|
ARCHIVE | 用于数据存档 (行插入后不能再被修改) |
CSV | 在存储数据时,以逗号分隔各个数据项 |
InnoDB | 具备外键功能的事务存储引擎 |
MERGE | 用来管理多个 MyISAM 表构成的表集合 |
NDB | MySQL 集群专用存储引擎 |
BLACKHOLE | 丢弃写操作,读操作会返回空内容 |
FEDERATED | 用来远程访问表 |
MEMORY | 置于内存的表 |
MyISAM | 主要的非事务处理存储引擎 |
数据库可以配置一个默认的存储引擎,而每个表还可以单独指定一个不同的存储引擎,例如:
-- 创建表时指定一个存储引擎
CREATE TABLE engine_demo_table(
i int
) ENGINE = MyISAM;
-- 修改一个表的存储引擎
ALTER TABLE engine_demo_table ENGINE = InnoDB;
MySQL 调控
MySQL 服务器正常运行,会有非常多的配置参数,并且这些参数是支持根据实际场景进行修改的,主要有 **启动选项 ** 和 配置文件 的方式
启动选项
常规在命令行下使用一个命令,为了让这个命令根据用户不同的需求产生不能的行为,都会传递一个这个命令支持的选项参数,然后命令解析到这个参数后,就会按固定的行为来工作
比如 ls
表示将当前目录下的文件信息都展示出来,而 ls -l
通过传递一个 -l 的选项,表示修改展示的内容及方式,这种类似的操作就是传递启动选项,MySQL 服务器在启动时也支持大量的启动选项
启动选项一般包含长形式和短形式,比如 MySQL 服务器配置监听主机名的选项,长形式就是 –host,而短形式就是 -h,他们的作用是相同的,相当于短地址数量有限,所有只有一些常用的选项有短形式
mysqld -h 127.0.0.1 -P 3306
# 等同于
mysqld --host 127.0.0.1 --port 3306
注意:选项名区分大小写,所以 -p 与 -P 完全不一样,而短形式指定选项时,可以跟空格,也可以不跟(-p有些特殊,-p和密码值之间是不能用空格的),所以 -P 3306
和 -P3306
是一样的
配置文件
启动选项仅针对单次启动生效,也就是不会将配置进行持久化,而配置文件是持久化到本地的,所以不需要每次启动时都输入,所以非常方便
Unix like 操作系统下,默认 MySQL 服务器会从以下路径来寻找配置文件:
路径 | 备注 |
---|---|
/etc/my.cnf | |
/etc/mysql/my.cnf | |
SYSCONFDIR/my.cnf | |
$MYSQL_HOME/my.cnf | 特定于服务器的选项 |
defaults-extra-file | 命令行指定的额外配置文件路径 |
~/.my.cnf | 用户特定选项 |
~/.mylogin.cnf | 用户特定的登录路径选项(仅限客户端) |
说明:
1、 SYSCONFDIR 表示在使用 CMake 构建时使用 SYSCONFDIR 选项指定的目录,通常情况下,默认配置是编译安装目录下的 etc 目录
2、 MYSQL_HOME 是自定义的环境变量,可配可不配,仅代表可以自定义放置配置文件的路径
3、 ~ 表示跟当前登录用户相关,也就是根据用户不同的配置方式,放置到每个用户自己的目录下
4、 defaults-extra-file 表示在启动 MySQL 服务是,指定的编译文件的目录,例如:
`mysqld --defaults-extra-file=/tmp/my.cnf` 这样启动,则会访问 /tmp/my.cnf 这个路径下的配置文件
配置文件的内容
配置文件的启动选项被分为若干个组,每个组有个组名,用中括号包裹
[server]
option1 # option1,该选项不需要选项值
option2 = value2 # option2,该选项需要选项值
[mysqld]
(具体的启动选项)
[mysqld_safe]
(具体的启动选项)
[client]
(具体的启动选项)
[mysql]
(具体的启动选项)
[mysqladmin]
(具体的启动选项)
对应到启动选项中,配置的这两个选项的使用方式应该类似于:
mysqld --option1 --option2=value2
其次是分组的适用范围:
1、 server 分组表示所有 MySQL 服务器程序都会读取使用
2、 client 分组表示所有 MySQL 客户端程序都会读取使用
3、 mysqld
命令启动 MySQL 服务器程序会读取 [mysqld],[server]
4、 mysqld_safe
命令启动 MySQL 服务器程序会读取 [mysqld],[server],[mysqld_safe]
5、 mysql.server
命令启动 MySQL 服务器程序会读取 [mysqld],[server],[mysql.server]
6、 mysql
命令启动客户端程序会读取 [mysql],[client]
7、 mysqladmin
命令启动客户端程序会读取 [mysqladmin],[client]
8、 mysqldump
命令启动客户端程序会读取 [mysqldump ],[client]
注意:同一个配置文件中,多个组都修改了同一个选项,并且这几个组都能被读取,则按从上到下的顺序进行读取,也就是最后一个配置会覆盖之前的配置项
系统变量
除了监听的端口ip等参数以外,MySQL 服务还有大量的系统变量,能影响 MySQL 服务程序的行为,跟之前的区别在于,这些系统变量除了配置文件和启动选项能修改外,还支持通过 SQL 动态的更改
例如 default_storage_engine
表示 MySQL 服务默认的储存引擎,max-connections
表示 MySQL 服务默认的储存引擎,通过启动选项的方式配置如下:
mysqld --default_storage_engine=MyISAM --max-connections=1000
通过配置文件的方式配置参考如下:
[server]
default-storage-engine=MyISAM
max-connections=1000
而通过 SQL 语句配置参考如下:
-- 用法: SET [GLOBAL|SESSION] 系统变量名 = 值;
SET GLOBAL default_storage_engine = MyISAM;
SET max-connections = 1000;
变量作用范围
与一般编程语言相似,MySQL 的系统系统变量也有作用范围的说法,不过不是全局和局部,而是全局跟用户,如果是 GLOBAL 下修改了这个参数,则对所有 MySQL 用户而言,都以最新的参数进行工作,而在 SESSION 下修改了这个参数,则仅对当前的 MySQL 用户生效
另外,不是所有的系统变量都有两种作用范围的,比如 max-connections
只具有 GLOBAL 的作用范围,而 insert_id
只具有 SESSION 的作用范围,像 version
这种变量更为特殊,属于只读的系统变量,不可更改
系统变量跟启动选项的区别
启动选项是程序启动时传递的参数,而系统变量是程序在运行时,控制程序行为的变量,关系如下:
- 大部分的系统变量都可以通过启动选项的方式进行配置
- 部分系统变量是程序自动生成,不可通过启动选项的方式进行配置,例如:
auto_increment_offset
- 部分启动选项也不是系统变量,例如:
defaults-file
状态变量
为了更好的了解 MySQL 服务的运行状况,服务提供了大量的关于运行状态的变量,称为状态变量。例如:Threads_connected
表示当前已经连接的数量
状态变量用于显示服务器的状态信息,他们的值只能由 MySQL 服务程序自己维护,而不能手动配置