文章目录
- 通信协议
- 通信类型:同步|异步
- 连接方式:长连接|短连接
- 通信协议
- Socket
- TCP/IP
- 其他方式
- 通信方式
- 单工方式
- 半双工方式
- 全双工方式
- 查询缓存
- 概述
- 缓存开启开关
- 语法解析和预处理
- 词法解析
- 1.概述
- 语法解析
- 1.概述
- 预处理器
- 1.概述
- 查询优化与查询执行计划
- 查询优化器[query optimizer ]概念
- 查看最后一条SQL的直销开销时间
- 优化器应用方面
- 1.当我们对多张表进行关联查询的时候,以哪个表的数据作为基准表
- 2.有多个索引可以使用的时候,选择哪个索引。
- 优化器开启
- 开启成功
- 存储引擎
- 官网介绍
- 概念--如何通俗的了解存储引擎是啥?
- 类型
- InnoDB
- 概述
- 特点
- MyISAM
- 特点
- 备注
- MySQL查询执行流程
- 整体模块
- 执行流程
- MySQL更新执行流程
- Buffer Pool概述
- 简单场景理解buffer pool
- MySQL 内存存储结构与磁盘存储结构
- 普及常识:非唯一索引[普通索引]与唯一索引
- Mysql InnoDB 内存存储结构
- 概述
- Buffer Pool [缓冲池]
- 查看buffer pool的相关参数
- 缓冲池存储策略 -LRU(最少使用策略)
- Change Buffer [变更缓存]
- Adaptive Hash Index
- Log Buffer
- show variables like 'innodb_log%'; innodb_log相关的参数
- 为啥我们要先写日志,再写磁盘?
- 写入日志与写入磁盘的频率问题?
- Mysql InnoDB 磁盘存储结构
- 1.系统表空间[共享表空间]-System Tablespace
- 1.1.数据字典(InnoDB Data Dictionary)
- 1.2.双写缓存(Doublewrite Buffer) 【InnoDB 的一大特性】
- 1.3.变更缓存(Change Buffer)
- 1.4.Undo Logs
- 2.独占表空间[File-Per-Table Tablespace]
- 案例说明
- 1.创建表
- 2.服务器文件说明
- 3.通用表空间[General Tablespace]
- 创建General Tablespace语法
- 创建表时指定tablespace
- 删除表空间需要先删除里面的所有表:
- 4.临时表空间[temporary tablespaces]
- 5.Undo Tablespace[回滚日志空间]-Redo Log
- 6.Redo Log
通信协议
通信类型:同步|异步
连接方式:长连接|短连接
通信协议
Socket
localhost:kubeadm-centos gaoxinfu$ mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 7
Server version: 5.7.27 MySQL Community Server (GPL)
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show global status like 'Thread%';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Threads_cached | 0 |
| Threads_connected | 2 |
| Threads_created | 2 |
| Threads_running | 1 |
+-------------------+-------+
4 rows in set (0.01 sec)
mysql> SHOW PROCESSLIST;
+----+------+-----------+------+---------+------+----------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+------+-----------+------+---------+------+----------+------------------+
| 5 | root | localhost | NULL | Sleep | 163 | | NULL |
| 7 | root | localhost | NULL | Query | 0 | starting | SHOW PROCESSLIST |
+----+------+-----------+------+---------+------+----------+------------------+
2 rows in set (0.00 sec)
mysql>
mysql> exit
Bye
localhost:kubeadm-centos gaoxinfu$ pwd
/Users/gaoxinfu/docker/kubeadm-centos
localhost:kubeadm-centos gaoxinfu$ mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 23
Server version: 5.7.27 MySQL Community Server (GPL)
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
1.这里的命令没有指定ip,所以只是本地的一个交互,会去当前服务器上去找物理文件
/var/lib/mysql/mysql.sock
TCP/IP
1.TCP/IP的区别就是会通过-h指定参数,连接服务器
2.我们的编程语言的连接模块都是用TCP协议连接到MySQL服务器的,
比如mysql-connector-java-x.x.xx.jar驱动包。
其他方式
1.略
通信方式
单工方式
1.两台机器在通信的过程中,传输是单向传输,如电视的遥控器
半双工方式
1.两台机器在通信的过程中,传输是双向的,彼此双方都可以给发送信息给对方;
但是在发送的过程中,同一时间只能一方进行发送;
2.生活中例子:对讲机,mysql
全双工方式
1.两台机器在通信的过程中,不受时间的限制,双方都可以彼此进行传输;
2.如打电话;
查询缓存
概述
1.MySQL内部自带了一个缓存的模块;
这个缓存模块会把数据会以k-v的形式放到内存里面,可以加快数据的读取速度,
也可以减少服务器的处理时间和压力;
https://dev.mysql.com/doc/refman/5.7/en/query-cache-configuration.html
缓存开启开关
show variables like 'query_cach%'
1.mysql的缓存开关默认是关闭的,官方不推荐使用;
不推荐使用的原因有两点
1.原因1:要求,SQL语句必须一模一样,多个空格,字母大小写不一样都认为不同的SQL,应用场景有限;
2.元音2:表里的任何一条数据发生变化的时候,这张表所有缓存会失效;
1.数据库层面的缓存,我们一般都交给ORM框架如MyBatis或者Redis去处理
语法解析和预处理
词法解析
1.概述
1.所谓词法解析,就是我们在执行任何一个SQL的时候,都会把这条SQL拆分为一个个的单词,然后进行解析处理;
2.例如:SELECT * FROM user_innodb where id =1;
会解析为select,*,FROM,user_innidb,where,id,=,1 这8个单词;
语法解析
1.概述
1.第二步就是语法分析,语法分析会对SQL做一些语法检查,比如单引号有没有闭合,然后根据MySQL定义的语法规则,根据SQL语句生成一个数据结构。这个数据结构我们把它叫做解析树(select_lex)。
2.如上面的SELECT * FROM user_innodb where id =1;解析为8个单词之后
语法解析就会去校验这8个单词是否符合语法规则;
预处理器
1.概述
1.在我们进行了词法解析和语法解析之后,会有一个预处理器;
2.你可以理解为我们prepared statement组装
样例流程
1.预处理:创建 SQL 语句模板并发送到数据库。预留的值使用参数 "?" 标记 。例如:
INSERT INTO user_innidb (id, name, gender,phone) VALUES(?, ?, ?,?,?)
2.数据库解析,编译,对SQL语句模板执行查询优化,并存储结果不输出。 可以认为是一种验证;
3.执行:最后,将应用绑定的值传递给参数("?" 标记),数据库执行语句。应用可以多次执行语句,如果参数的值不一样。 (这一步不属于预处理的过程)
查询优化与查询执行计划
查询优化器[query optimizer ]概念
1.所谓的优化器实际上就是我们在写一个查询SQL的过程中,实际上根据条件,可能会有不同的执行方式,但是返回的查询结果是一致的,
但是如何判断那一条的执行效率最高呢?
这就是查询优化器模块要做的;
目前查询优化器主要是根据执行的开销时间去判断的;那一中执行方式开销最小,我们认为是最优的;
2.如下图,我们一条SQL可能会有两种不同的执行计划(Execution Plan),根据不同的开销,选择开销最小的执行计划
查看最后一条SQL的直销开销时间
1.主要用于比较不同的执行计划那个开销更小
select * from user_innodb u where u.name='吴短';
show status like 'Last_query_cost';
优化器应用方面
1.当我们对多张表进行关联查询的时候,以哪个表的数据作为基准表
2.有多个索引可以使用的时候,选择哪个索引。
备注
1.优化器不是万能的,垃圾SQL,永远是垃圾,再怎么优化,都不能从根本上提高性能;
优化器开启
1.注意开启这开关是会消耗性能的,因为它要把优化分析的结果写到表里面,所以不要轻易开启,或者查看完之后关闭它(改成off)
2.SHOW VARIABLES LIKE 'optimizer_trace';
set optimizer_trace='enabled=on';
**SHOW VARIABLES LIKE ‘optimizer_trace’; **
开启成功
存储引擎
官网介绍
https://dev.mysql.com/doc/refman/5.7/en/storage-engines.html
概念–如何通俗的了解存储引擎是啥?
1.首先,我们要记住,存储引擎是针对表table的;
2.我们在关系型数据库(如mysql,oracle等等)中,存储表中的时候,涉及到数据的存储,这个时候,不同的存储数据的结构方式,
对于你后期的CURD操作效率以及事务等不一样的;
对本地数据库表的存储引擎定义,在服务器上有下面的文件
任何一个存储引擎都有一个frm 文件,这个是表结构定义文件
不同的存储引擎存放数据的方式不一样,产生的文件也不一样,innodb 是 1
show variables like 'datadir';
服务器上查看表的定义文件,注意以root权限登录
sh-3.2# pwd
/Users/gaoxinfu
sh-3.2# cd /usr/local/mysql/data/
sh-3.2# ls -la
total 246312
drwxr-x--- 17 _mysql _mysql 544 1 16 06:35 .
drwxr-xr-x 13 root wheel 416 9 13 21:29 ..
-rw-r----- 1 _mysql _mysql 57831 9 16 09:27 MacBook-Pro.local.err
-rw-r----- 1 _mysql _mysql 4 9 13 21:53 MacBook-Pro.local.pid
-rw-r----- 1 _mysql _mysql 56 9 13 21:29 auto.cnf
drwxr-x--- 11 _mysql _mysql 352 10 10 14:05 gp@002dmybatis
drwxr-x--- 14 _mysql _mysql 448 12 28 20:05 gp@002dmysql
-rw-r----- 1 _mysql _mysql 6822 1 15 18:43 ib_buffer_pool
-rw-r----- 1 _mysql _mysql 50331648 1 16 06:35 ib_logfile0
-rw-r----- 1 _mysql _mysql 50331648 1 16 06:35 ib_logfile1
-rw-r----- 1 _mysql _mysql 12582912 1 16 06:35 ibdata1
-rw-r----- 1 _mysql _mysql 12582912 1 16 07:03 ibtmp1
drwxr-x--- 77 _mysql _mysql 2464 9 13 21:29 mysql
-rw-r----- 1 _mysql _mysql 150712 1 16 06:35 mysqld.local.err
-rw-r----- 1 _mysql _mysql 5 1 16 06:35 mysqld.local.pid
drwxr-x--- 90 _mysql _mysql 2880 9 13 21:29 performance_schema
drwxr-x--- 108 _mysql _mysql 3456 9 13 21:29 sys
sh-3.2# cd gp@
@::1 @gaoxinfu.online @localhost
@broadcasthost @kubernetes.docker.internal
sh-3.2# cd gp@002dmysql
sh-3.2# pwd
/usr/local/mysql/data/gp@002dmysql
sh-3.2# ls -la
total 114856
drwxr-x--- 14 _mysql _mysql 448 12 28 20:05 .
drwxr-x--- 17 _mysql _mysql 544 1 16 06:35 ..
-rw-r----- 1 _mysql _mysql 61 12 28 19:58 db.opt
-rw-r----- 1 _mysql _mysql 8740 12 28 20:05 user_archive.ARZ
-rw-r----- 1 _mysql _mysql 8652 12 28 20:05 user_archive.frm
-rw-r----- 1 _mysql _mysql 35 1 15 18:43 user_csv.CSM
-rw-r----- 1 _mysql _mysql 0 12 28 20:05 user_csv.CSV
-rw-r----- 1 _mysql _mysql 8652 12 28 20:05 user_csv.frm
-rw-r----- 1 _mysql _mysql 8652 12 28 20:05 user_innodb.frm
-rw-r----- 1 _mysql _mysql 58720256 1 15 14:00 user_innodb.ibd
-rw-r----- 1 _mysql _mysql 8652 12 28 20:05 user_memory.frm
-rw-r----- 1 _mysql _mysql 0 12 28 20:05 user_myisam.MYD
-rw-r----- 1 _mysql _mysql 1024 12 28 20:05 user_myisam.MYI
-rw-r----- 1 _mysql _mysql 8652 12 28 20:05 user_myisam.frm
sh-3.2# vi user_innodb.frm
sh-3.2#
类型
1.我们这里只介绍两种存储引擎的类型,一种是InnoDB,一种是MyISAM;
InnoDB
概述
1.mysql 5.5版本之后,默认采用InnoDB
特点
1.支持事务,支持外键,因此数据的完整性、一致性更高。
2.支持行级别的锁和表级别的锁。支持读写并发,写不阻塞读(MVCC)(这个是行级锁带来的好处)。
3.特殊的索引存放方式,可以减少IO,提升查询效率。
适合:经常更新的表,存在并发读写或者有事务处理的业务系统。
MyISAM
特点
1.支持表级别的锁(插入和更新会锁表)。不支持事务。拥有较高的插入(insert)和查询(select)速度。
存储了表的行数(count 速度更快)。
适合:只读之类的数据分析的项目。
备注
(怎么快速向数据库插入 100
MySQL查询执行流程
整体模块
执行流程
MySQL更新执行流程
1.更新流程和查询流程有什么不同呢?
基本流程也是一致的,也就是说,它也要经过解析器、优化器的处理,最后交给执行器。
区别就在于拿到符合条件的数据之后的操作
Buffer Pool概述
1.首先,我们需要理解的是InnoDB数据库的存储引擎会将我们所有的数据存储到数据库所在的服务器磁盘上;
2.InnoDB操作数据有一个最小的逻辑单位叫做页(索引页和数据页),我们对数据做操作的时候,如果直接操作磁盘显然效率是及其低下的;
因为磁盘的读写速度太慢了;这个时候MySQL的存储引擎使用了一种缓冲池的技术,将会把磁盘的的数据读取到的页(索引页和数据页)放
到一块内存的区域里面,以此来提供数据的读写速度,这个内存区域就是Buffer Pool;
简单场景理解buffer pool
1.客户端在对数据库进行操作的过程中,会先去缓冲池(buffer pool)里面去判断是否有当前操作的页(数据页和索引页),
如果有,那么直接对缓存中的数据进行修改,然后后面会有一个线程(Thread)去定时的同步缓存中的变更数据到磁盘中;
如果没有,那么磁盘中的数据会先将数据同步到缓存(buffer pool)中,然后我们再直接操作缓存中的数据;
2.当然,这里大家注意下,一般缓存中的数据其实是可以存储很多的;有可能80%都会存储在缓存当中;
3.关于InnoDB的缓存结构和磁盘结构,可以看下面的介绍
MySQL 内存存储结构与磁盘存储结构
https://dev.mysql.com/doc/refman/5.7/en/innodb-architecture.html
普及常识:非唯一索引[普通索引]与唯一索引
1.通俗的理解:我们知道我们数据库中的字段,有的字段的值是可以重复,有的字段的值是不可以重复的,
如:表user,字段name加了索引name_index,这个name字段是可以重复的,所以是普通索引
字段id_no加了索引id_name_index,这个id_no字段是不可以重复的,所以是唯一索引
Mysql InnoDB 内存存储结构
概述
1.MySQL的内存存储结构主要是指的Buffer Pool(缓冲池);
Buffer Pool分为三部分:Buffer Pool,Change Buffer,Adaptive Hash Index,以及这个(redo)log buufer;
https://dev.mysql.com/doc/refman/5.7/en/innodb-in-memory-structures.html
Buffer Pool [缓冲池]
查看buffer pool的相关参数
SHOW VARIABLES like '%innodb_buffer_pool%';
1,buffer pool 默认大小128M,可以调整
缓冲池存储策略 -LRU(最少使用策略)
1.由于缓冲池(Buffer Pool)中内存空间是固定的,所以这里就涉及到一个问题,一旦内存满了怎么办?
Buffer Pool目前使用的是LRU(最少使用策略),对于很少使用的页会删除;
Change Buffer [变更缓存]
1.我们在进行数据库的更新操作(insert,delete,update)的时候,通过去操作缓存中的数据,来提升其速度;
实际上就是先将修改记录在内存的缓冲池中,这部分数据就是change buffer;
2.后面会有一个线程Thread对这块变更内容进行同步到数据库所在的服务器磁盘之中;这块操作我们称之为merge
Adaptive Hash Index
Log Buffer
https://dev.mysql.com/doc/refman/5.7/en/innodb-redo-log-buffer.html
1.Log Buffer 是一块用于将数据写入磁盘日志的缓存区域;
2.Log Buffer的缓存区域的大小,可以通过参数innodb_log_buffer_size 区设置,默认是16M
3.Log Buffer的缓存数据内容会定期的写入到磁盘中的日志文件(你可以认为这里的文件记录的是一些SQL)中;
4.一旦如数据库宕机,可以再数据库启动的时候通过读取日志文件中的内容,进行数据的恢复,写入到磁盘中的数据库数据
1.这里我们写入的日志就是redo log(重做日志),
这些日志的话,都是存储在/var/lib/mysql/目录下的 ib_logfile0 和 ib_logfile1,每个 48M。
2.这个机制实际上是通过日志和磁盘配合,来保证数据尽量的不被丢失,这个技术我们称之为WAL技术(Write-Ahead Logging)
show variables like ‘innodb_log%’; innodb_log相关的参数
为啥我们要先写日志,再写磁盘?
1.磁盘的交互,效率极低,而且涉及到分布式数据库的问题;
2.日志存储时顺序存储的,执行效率比较高;
写入日志与写入磁盘的频率问题?
https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html
show variables like 'innodb_log%';
Mysql InnoDB 磁盘存储结构
https://dev.mysql.com/doc/refman/5.7/en/innodb-on-disk-structures.html
1.表空间可以看做是 InnoDB 存储引擎逻辑结构的最高层,所有的数据都存放在表空 间中。InnoDB 的表空间分为 5
1.系统表空间[共享表空间]-System Tablespace
官网
https://dev.mysql.com/doc/refman/5.7/en/innodb-system-tablespace.html
1.在默认情况下 InnoDB 存储引擎有一个共享表空间(对应文件/var/lib/mysql/ibdata1),也叫系统表空间。
见下面截图ibdata1服务器上这个文件;
2.系统表空间:包括数据字典(InnoDB Data Dictionary),双写缓存(Doublewrite Buffer),变更缓存(Change Buffer),Undo Logs
[root@izwz91h49n3mj8r232gqwez mysql]# pwd
/var/lib/mysql
[root@izwz91h49n3mj8r232gqwez mysql]# ls -la
总用量 110616
drwxr-xr-x 5 mysql mysql 4096 1月 20 12:45 .
drwxr-xr-x. 33 root root 4096 1月 20 10:36 ..
-rw-rw---- 1 mysql mysql 56 1月 20 10:38 auto.cnf
drwx------ 2 mysql mysql 4096 1月 20 12:46 gpmysql
-rw-rw---- 1 mysql mysql 12582912 1月 20 12:46 ibdata1
-rw-rw---- 1 mysql mysql 50331648 1月 20 12:46 ib_logfile0
-rw-rw---- 1 mysql mysql 50331648 1月 20 10:38 ib_logfile1
drwx------ 2 mysql mysql 4096 1月 20 10:38 mysql
srwxrwxrwx 1 mysql mysql 0 1月 20 10:38 mysql.sock
drwx------ 2 mysql mysql 4096 1月 20 10:38 performance_schema
[root@izwz91h49n3mj8r232gqwez mysql]#
1.1.数据字典(InnoDB Data Dictionary)
1.由内部系统表组成,定义表和索引的元数据(定义信息);
1.2.双写缓存(Doublewrite Buffer) 【InnoDB 的一大特性】
1.
1.3.变更缓存(Change Buffer)
1.4.Undo Logs
2.独占表空间[File-Per-Table Tablespace]
1.显然就是 让每张表独占一个表空间。这个开关通过 innodb_file_per_table 设置,默认开启。
SHOW VARIABLES LIKE 'innodb_file_per_table';
案例说明
1.创建表
1.我们创建一个数据库schema,其中数据库的名字(schema_name)为gpmysql,另外在gpmysql下面创建表user,其中创建表的语句如下:
CREATE TABLE `user` (
`id` int(11) NOT NULL,
`name` varchar(45) DEFAULT NULL,
`idno` varchar(45) DEFAULT NULL,
`sex` char(1) DEFAULT NULL,
`remark` varchar(2000) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2.服务器文件说明
1.我们创建gpmysql这个数据库成功之后,在我们的服务器上会出现下面的文件:
/var/lib/mysql下面会有gpmysql这个文件件,其中ibd 文件(user的ibd文件就是user.ibd)是我们创建的表的数据信息以及索引信息都在这里存储;
[root@izwz91h49n3mj8r232gqwez mysql]# pwd
/var/lib/mysql
[root@izwz91h49n3mj8r232gqwez mysql]# ls -la
总用量 110616
drwxr-xr-x 5 mysql mysql 4096 1月 20 12:45 .
drwxr-xr-x. 33 root root 4096 1月 20 10:36 ..
-rw-rw---- 1 mysql mysql 56 1月 20 10:38 auto.cnf
drwx------ 2 mysql mysql 4096 1月 20 12:46 gpmysql
-rw-rw---- 1 mysql mysql 12582912 1月 20 12:46 ibdata1
-rw-rw---- 1 mysql mysql 50331648 1月 20 12:46 ib_logfile0
-rw-rw---- 1 mysql mysql 50331648 1月 20 10:38 ib_logfile1
drwx------ 2 mysql mysql 4096 1月 20 10:38 mysql
srwxrwxrwx 1 mysql mysql 0 1月 20 10:38 mysql.sock
drwx------ 2 mysql mysql 4096 1月 20 10:38 performance_schema
[root@izwz91h49n3mj8r232gqwez mysql]#
[root@izwz91h49n3mj8r232gqwez mysql]# cd gpmysql
[root@izwz91h49n3mj8r232gqwez gpmysql]# ls -la
总用量 124
drwx------ 2 mysql mysql 4096 1月 20 12:46 .
drwxr-xr-x 5 mysql mysql 4096 1月 20 12:45 ..
-rw-rw---- 1 mysql mysql 61 1月 20 12:45 db.opt
-rw-rw---- 1 mysql mysql 12774 1月 20 12:46 user.frm
-rw-rw---- 1 mysql mysql 98304 1月 20 12:46 user.ibd
[root@izwz91h49n3mj8r232gqwez gpmysql]#
备注
1.但是其他类的数据,如回滚(undo)信息,插入缓冲索引页、系统事务信息,二次 写缓冲(Double write buffer)等还是存放在原来的共享表空间内。
2.这个ibd文件只保存这个表的数据和索引信息;
3.通用表空间[General Tablespace]
1.通用表空间也是一种共享的表空间,跟 ibdata1 类似。 可以创建一个通用的表空间,用来存储不同数据库的表,数据路径和文件可以自定义。
创建General Tablespace语法
create tablespace demoGTS add datafile '/var/lib/mysql/demoGTS.ibd' file_block_size=16K engine=innodb;
创建表时指定tablespace
create table person(id integer) tablespace demoGTS;
删除表空间需要先删除里面的所有表:
drop table person;
drop tablespace demoGTS;
4.临时表空间[temporary tablespaces]
1.临时表空间主要是创建临时表时存储的数据和索引等
备注创建临时表的SQL
CREATE TEMPORARY TABLE tmp_table SELECT *
5.Undo Tablespace[回滚日志空间]-Redo Log
1.Undo Tablespace 实际上也是Redo Log,主要是存储一些回滚日志一些记录,主要是提供回滚的作用
6.Redo Log