赞
踩
思考:一条mysql的执行语句,经过了哪些流程
1、连接层
mysql服务端,暴露了一个3306端口,客户端用什么协议和他连接?
mysql支持多种协议,一般我们都是使用TCP (mysql-connector-java-x.x.xx.jar)
mysql-connector-java-x.x.xx.jar: 看了下代码,是解析url的 ip port 协议,建立了socket连接
连接方式:可以支持同步和异步
同步通信一般依赖于被调用方,会被阻塞,等待被调用方返回结果
异步和同步相反,异步可以减少阻塞的时间,但是并不能减少sql执行的时间。存在一个问题,并发情 况下,异步会创建大量的连接。可以使用线程池。但是对于异步结果的返回还是不可控。一般我们使用同步的方式
长连接还是短连接:都支持,但是在连接池中一般使用长连接。
show global variables like 'wait_timeout'; -- 非交互式超时时间,如 JDBC 程序 默认8小时
show global variables like 'interactive_timeout'; -- 交互式超时时间,如数据库工具 默认8小时
show variables like 'max_connections'; 最大连接数 默认151
通信方式:单工 半双工(mysql是半双工,客户端和服务端可以交互,但是不能同时发送) 全双工
其他:除了建立连接外,还有验证鉴权等功能
2、缓存
mysql 5.x 支持缓存的。结构是key-value,key是查询语句,value是查询结果。当key命中时,可以直接返回,不调用后续分析优化执行过程。但是当表中数据有任意修改时,缓存就失效了意义不大,缓存默认是关闭的,8.x废弃缓存,可以交给缓存框架或者ORM框架处理,这部分可以看mybatis的缓存模块涉及。
3、解析器(分析器)
我们输入一条sql,通信问题ok了,缓存不管,后面应该怎么处理呢?是解析。
mysql对于词法的判断,其实是会将一个完整的sql,打散成一个个单词,从哪开始,到哪结束
语法解析,将所有的词,组装到一个解析树内,实现解析校验
sql语句解析完成了,又如何知道我们的表和字段不存在的呢?
对于表和字段等操作,mysql提供了解析器,来实现检查表名列名,别名等语法没办法解析的数据,封装成一个新的解析树。
4、优化器
对于一个sql,mysql其实是有很多种执行方法的,但是具体最后选择了哪一种执行方法,还是由查询优化器来决定的。
执行优化器也还是有自己的判断标准的,mysql中使用的是cost(基于开销的优化器),哪个开销小,选哪个。
优化器可以做哪些,简单举个例子:
1、两张表关联查询,以哪张表为基表
select * from a left join b on a.id = 10 and b.id = 20
查询方案有两种:
先查询a表 id= 10 的数据,再一个一个关联b,判断b.id=20
先查询b表 id=20 ............... 关联a,判断a.id=10
2、同时可以使用多个索引,使用哪个索引。
备注:优化器其实也是代码,还是得优先提高sql的质量。
优化器优化后,还是将解析树变化成一个查询执行计划。
查询计划的工具: EXPLAIN select name from user where id=1;
备注: EXPLAIN 也不一定是最终执行的方式
5、执行器
优化器提供了具体的执行计划,调用存储引擎api,查询数据
未命中索引:一行一行拿数据,匹配所有
命中索引:类似,调用api拿命中索引的第一行数据,再next next
6、存储引擎
插件的形式,实现规范即可,innodb myisam memory等,默认innodb
mysql每个表都可以指定不同的存储引擎,并且可以修改 show table status where name = ‘user_innodb’;
查看数据的存储位置。就在如下目录中:
innodb有frm和ibd两个文件 frm存储表结构信息 ibd存储索引和数据信息(聚集索引和非聚集索引)
myisam 有frm MYD MYI三个文件 frm:存储表结构信息 MYD: myisam data MYI: myisam index
对比一下Innodb和myisam:
myisam是5.5之前的默认的存储引擎 innodb是5.5之后的
innodb默认支持事物(undo.log redo.log 这个后续再介绍),支持行级别的锁,写不阻塞读MVCC 一般数据一致性要求高,使用
myisam只支持表级别锁 (限制了读写的能力,一般也只是用读多写少的场景), insert和select的速度更快
上面的例子是查询语句,可以再看下更新语句
大致逻辑和查询其实是一致的
连接器-》分析器-》优化器-》执行器-》存储引擎
执行器执行器后面的逻辑如下:
1、根据优化器的执行计划去innodb获取数据,
2、存储引擎 先找内存,内存没有就读磁盘加载到内存,返回给执行器
3、执行器修改新的值到行,并调用存储引擎。
4、innodb 先记redo log (物理数据:真实的数据)并设置状态为prepare,返回成功给执行器
5、执行器记bin log (逻辑数据:记录具体的操作 +1 、 -1这种)
6、调用innodb 设置redo log为 commit
7、执行器返回成功
下面的几张图来自《mysql 45讲》
上述提到了两个重要的文件redo log和bin log,mysql中有很多利用log的设计。
redo log innodb特有的
目的:磁盘写太慢了,利用日志顺序读写快很多。提高效率
为什么 redo log需要两阶段提交?
站在随时随地都有可能崩溃的情况来看,写bin log 和写 redo log是两个动作,当redo log写完,
崩溃了,恢复后会有该记录对应的数据。这时bin log中没有,那么备份的数据就不一致了
redo log和bin log的区别?
1、redo log是innodb特有,引擎层。bin log是server层的。
2、redo log是循环写入,满了会覆盖。bin log是追加写
3、redo log记录的是物理日志,作用于崩溃恢复处理。而bin log记录的是逻辑日志,用于备份的复制等场景(回放sql记录)。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。