目录

  • 一、mysql的逻辑架构?
  • 二、介绍一下explain?
  • 三、mysql的并发控制?


一、mysql的逻辑架构?

mysql采用四层架构,从上到下分别是:连接层,服务层,引擎层,存储层。

首先介绍连接层,mysql的连接层和大多数基于网络的客户端/服务器工具架构的连接层类似,主要进行连接处理,授权,和认证方面的工作。

完成这些工作之后,客户端与服务器建立连接,当客户端发送一条sql查询的时候,经过连接层,查询会被发往服务层,这一层是mysql的核心,包括了对查询的解析,分析,优化,和缓存的功能,同时还负责所有跨存储引擎的功能,比如各种内置函数。

下一层是存储引擎层,mysql的一大优点就是灵活,因为它能够指定不同的存储引擎,通过不同的实现,应对不同的业务场景。从这一点其实就可以理解,在服务层一定是提供了统一的接口,然后由不同的存储引擎做不同的内部实现,在每一个存储引擎内都提供了大概十几个内置底层函数,用于执行一下类似“开始一个事务”,或者“按照某个主键提取纪录“的操作,存储引擎层并不会对sql进行解析,也不会和其他存储引擎进行通信,只是简单的响应服务层的请求。

注意:这里额外说一下mysql对客户端的认知,不止会认证用户名和密码,还会根据用户名,认证权限,也就是该用户对某个数据库的某个表是否具有操作权限。

下面放一张mysql逻辑架构的图片,图片采自《高性能mysql》

mysql 数据库链接解析 mysql数据链路_mysql

二、介绍一下explain?

explain其实是请求服务层的优化过程信息,在服务层,会对收到的sql进行解析,创建数据结构解析树,然后对其进行各种优化,比如重构查询,决定表的读取顺序,决定使用哪一个索引等等,用户可以通过关键字来影响优化器的决策,也可以通过explain来获取优化器的进行决策的各个因素,使得用户可以根据这些信息优化sql,提高性能。
对于优化器来说,是不关心存储引擎的,但是不同的存储引擎确实会影响优化查询,所以优化器会请求存储引擎提供对于某个操作的具体开销。
另外,在服务层进行sql解析之前,会先查找缓存,如果缓存命中的话,会返回缓存中的结果。

三、mysql的并发控制?

无论在什么时候,只要有多个客户端同时修改同一行数据,就会尝试并发控制的问题,mysql支持多个客户端,当然也提供了强大的并发控制的能力。
对于并发控制,最简单的做法就是加锁,当一个事务想要修改某个表的数据的时候,我们可以直接对整个表加锁,后面的数据想要获取表的数据,就必须先等待,这样的做法,在安全性上得到保障,但是性能太差,如果实现并发,所以在mysql中实现的是以两种不同类型的锁组成的锁系统来进行并发控制,也就是使用了读写锁或者叫共享锁和排他锁。
其中读锁是可以共享的,也就是当其他事务加了读锁之后,另一个事务同样可以加读锁,但是写锁是排他的,也就是一个写锁会阻塞其他的读锁和写锁。这样做可以实现多个读进程并发进行,提高了效率,但是,每一次都要锁住整个表,性能还是不高,想象一下有几万行数据的表,有一个数据只是想修改其中一行,却阻塞了其他几十个想要读取其它行数据的读进程,这样效率还是太低。
所以mysql引入了行锁,降低了锁的粒度,只锁住进程要修改的数据行,其他数据行同样可以被其他事务读或者写。这样做提高了效率,还保证了安全。
但是,会出现一个新的问题,比如,当一个事务想要修改一行数据的时候,会对这行数据进行加锁,这时候来了另一个事务,它想直接把这个表给删除了,这当然不行,因为此时有其他事务正在使用这张表。所以,它就需要逐行的检查,该行是不是被加了锁,如果所有数据行都没有被加锁,说明没有其他事务在使用这张表,那就可以删除了。但是这个遍历数据表的过程效率非常低,当遇到几十万行的数据表的时候,就麻烦了。
仔细想想这个过程,其实这个删除表的事务并不需要知道有多少个事务正在使用这张表,或者这张表里的具体数据,它只需要知道此时此刻,有没有事务在修改这个表,就可以了,可以就是有或者没有的判断,所以,在mysql中,为了避免遍历带来的开销,在加行锁的同时,会对表加意向锁,用来表示此时有事务在访问该表。意向锁是共享的,不管是读锁还是写锁,都是共享的,因为它只为了表示一种状态而已。
这样,当我想要删除一张数据表的时候,我只需要检查,该表有没有被加上意向锁即可。
注意:那如何查看存储引擎的加锁信息呢?可以使用

show engine innodeb status

进行查看。