MySQL连接发生的那些事?
MySQL连接12mysql -h$ip -u$user -p
连接器
基于TCP三次握手连接
验证用户名和密码
读取权限,后面的权限逻辑判断都基于此时读到的权限
查询缓存
首先查询缓存是针对于select语句的,当表中的数据进行更新,那么此表的查询缓存就会被清空,如果刚缓存了一个查询很大的数据,还没被使用,刚好这个表有更新操作,查询缓存就被清空了
mysql8.0没有查询缓存这一步操作
解析SQL
解析器
词法分析
目的就是构建语法树
它会根据你输入的字符串识别出关键词,如SQL语句类型、表名、字段名、where后面的条件等
语法分析
检查语法
根据前面语法分析的结果,判断SQL语句是否满足MySQL语法,比如from写成form就会报错
注意这里不会验证表名和字段是否存在,解析器不做这个处理,虽然《MySQL45讲》中说是解析器做的,但是从MySQL5.7和8.0版本的源码并没有检查表和字段是否存在
执行SQL
三个阶段:
prepare阶段,预处理阶段
optimize阶段,优化阶段
execute阶段,执行阶段
预处理器
检查SQL查询语句表中的表或者 ...
操作系统中的调度算法
调度算法链接
分区分配算法
给出每个进程的大小,分区编号、起始地址、分区大小
找到分区编号的起始地址就是进程的分配的地址,然后操作(起始地址加上进程大小,分区大小减去进程大小)
首次适应(first)
根据分区编号从小到大进行匹配,找到第一个分区大小大于等于进程大小的分区编号
最佳适应
根据分区大小从小到大进行排序,依次从小到大匹配,找到第一个分区大小大于等于进程大小的分区,注意此排序是动态排序的
循环首次适应(next)
在首次适应的基础上,根据分区编号从小到大进行匹配,下次就从当前分区的下一个进行匹配
最坏适应(worst)
根据分区大小从大到小进行排序,依次从大到小进行匹配,找到第一个分区大小大于等于进程大小的分区,注意此排序是动态排序的,如果第一个不匹配了就不找了,所以他的效率很高
页面置换算法先进先出置换(FIFO)
选择在内存驻留时间很长的页面进行中置换
一般来说直接把第一个换掉就可以了
最佳页面置换(OPT)
置换未来最长时间不访问的页面
从当前点开始,从左往右找,最后出现的值替换掉,如果有多个没找到就替换第一个
最近最久未使用(LRU)
置换最近最久未 ...
mysql中的幻读
MySql可重复读(RR)隔离级别当前读
通过间隙锁(next-key-lock)实现的
在执行select当前读语句的时候,会加上一个间隙锁,当有其他事务执行时,这个事务会被阻塞,无法执行,就保证了数据一致性问题;解决了幻读
123456789select ... lock in share modeselect ... for updateupdate ...delete ...insert into ....
快照读
通过MVCC实现的
多版本并发控制,多版本mysql维护行记录的多个版本,并发控制指不同的事务同一时间操作某一行记录时mysql控制返回多个版本行记录中的某个版本。
MVCC它有一个readview;在快照读的情况下,只会在事务开始时创建一个readview,后续的查询操作都是复用这个readview;当然这个readview它有自己的策略,它维护了几个值,活跃事务的id,最大事务的id,最小事务的id····;然后他就是用可见性算法拿当前事务的id和这些id进行一定规则的比较,来控制返回那个版本。
然后在RR级别隔离下,快照读也保证了数据一致性,很大 ...
Java中的SPI
SPI
S指Service,p指provider,I指Interface。它一般由三个组件组成:
Service
是一个公共的接口或抽象类,定义了一个抽象的功能模块
Service Provider
是Service的一个实现类
ServiceLoad
是SPI中的核心组件,它用来发现并加载Service Provider
SPI的运行流程
启动一个Application程序后,调用ServiceLoad的load()方法,得到provider,也就是接口的实现类,这时候返回给Application,这时候返回的是个接口类型的,然后就进行下一步操作了。
它不关系Service实现类是怎么实现的,只需要和Service接口进行交互即可。
SPI的三个规范
一:规范的配置文件;必须在jar包中的META-INF/services目录下,文件名称是接口的全限定名;内容是接口的实现类的全限定名,一行一个实现类的全限定名。
二:Service Provider类必须具备默认的无参构造方法;
三:保证能加载到配置文件和Service Provider类;如利用maven将jar包作为依赖 ...