Mysql的架构可分为两层:Server层和存储引擎层。
Server层:包含连接器,缓存,分析器,优化器,执行器,包含MySQL大多数核心的功能及内置函数;
存储引擎层:主要负责数据的存储和提取,是基于插件的形式的架构,支持InnoDB,MyISAM等存储引擎;5.5.5后默认使用InnoDB作为默认的存储引擎。在创建表的时候不指定引擎,默认就是InnoDB,也可以通过engine=memory来指定使用的存储引擎。
Server层
Server层是MySQL的基础架构,包含了MySQL的大多数核心功能及一些内置的函数。
连接器
连接器负责与客户端建立连接,获取用户权限,维持和管理连接;
在经过TCP握手后,就会开始验证用户名和密码,如果密码错误直接结束客户端,如果密码正确,连接器会在权限表中查询用户的权限,此后这个链接中进行的操作都会基于简历链接时读到的权限(也就是说在一个客户端建立了链接后,即使管理员对账号权限进行了修改,也需要这个用户重新链接才会生效);
通过show processlist 命令可以查询链接的状态,其中Command列显示的就是链接的状态;如果一个客户端默认超过八个小时没有操作,连接器会将这个链接断开(这个超时时间由wait_timeout参数控制);
| Id | User | Host | db | Command | Time | State | Info |
| :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |
| 3 | root | localhost:54957 | test | Query | 0 | starting | ... |
在数据库中长链接指的是在连接成功后如果一个客户端持续有请求,则使用的是同一个连接,短连接是执行几次操作后就断开了连接,下次再操作的时候重新建立连接;因为建立连接的过程是比较复杂的,所以尽量减少频繁创建连接;
但是全部使用长连接会造成内存长得非常快,因为MySQL执行的过程中临时使用的内存是管理在连接对象中的,这些资源只有在连接器断开的时候释放;如果这些资源长期积累则会出现数据库的OOM,现象上就是MySQL异常重启;解决这个问题可以执行mysql_reset_connection来初始化连接资源,这个操作不需要权限校验,会恢复到刚创建完连接的状态;
缓存
在执行查询类语句的时候,会先到缓存中查看是否执行过这条语句,之前执行过的语句会以KV的形式存储,K是语句,V是语句的查询结果,如果查询语句命中了缓存,会直接将结果返回到客户端,如果执行的是修改,删除类的语句,则会删除这个表中所有的缓存;在MySQL8.0后删除了缓存这个模块;
在MySQL8.0之前的版本中也提供了缓存的配置,将query_cache_type 参数设置成DEMAND,这样在执行查询语句的时候都不使用缓存;
分析器
MySQL在这个阶段需要先做词法分析,来判断出这个命令是做什么的,比如输入的select就会分析出是查询语句,吧表名,查询字段名都分析出来,在识别完上面这些后接下来就要进行语法分析,分析语句是否符合SQL的语法。
优化器
经过分析器后,就知道这是个什么操作了,在开始执行前就要先经过优化处理,比如表中有多个索引,来决定使用哪个索引;以及在执行多表查询的时候,决定各个表的连接顺序;
执行器
在知道了这条语句是要做什么,以及决定了使用哪个索引及查询的先后顺序,到这里就要开始执行语句了;
在执行前会先判断当前连接用户是否有表的操作权限,如果没有则返回异常提示,如果有权限则通过引擎提供的接口执行;
比如执行的是个查询语句,并且where条件上没有索引,那么在执行的时候就会调用引擎接口取表的第一行,判断是否满足where条件,满足则将这行数据保存在结果集中,不满足则跳过这条记录,继续取下一行,以此类推,在扫描完表后将结果集返回给客户端;
如果where的字段上建立了索引,那么调用引擎的则是满足这个索引条件的第一行这个接口,循环获取
存储引擎层
MySQL的存储引擎层负责数据的存储和提取。其架构模式是插件式的,支持 InnoDB、MyISAM、Memory 等多个存储引擎。
InnoDB
MySQL5.5.5版本后的默认存储引擎,具体特点如下:
- 支持事务,在可重复读和读提交隔离级别下通过MVCC一致性视图解决了不可重复读问题,通过间隙锁解决了幻读的问题。
- 默认支持行锁,更小的锁力度支持更大的并发
- InnoDB使用B+Tree来作为索引的数据结构,查询效率高,并在基础B+Tree上进行了优化,叶子节点通过指针相连接,提高范围查询效率
- 数据与主键索引放在一起,叶子节点会冗余非叶子节点的数据,在叶子节点上存储主键对应的整行数据
MyISAM
MySQL5.1版本前默认的存储引擎,具体特点如下:
- 不支持事务,不具有ACID特性
- update时通过表锁保证数据的安全性(写操作会阻塞 读和写,读操作不会阻塞读)
- 读数据速度快,占用资源更少,并且会记录表中记录行数
- 不支持外键约束