mysql的体系结构分两层,Mysql Server层和存储引擎层。
1、连接器
连接器负责跟客户端建立连接、获取权限、维持和管理连接。
客户端和服务端完成TCP三次握手后,连接器就要开始认证客户端身份,即客户端提供的用户名密码,如果用户名或密码不对,客户端就会收到一个”Access denied for user”的错误,然后客户端程序结束执行。如果用户名密码认证通过,连接器会到权限表里面查出当前用户拥有的权限。
连接完成后 如果客户端超过 wait_timeout(默认值是 8 小时)配置时间没有发起请求,连接器就会自动将它断开。
长链接
长连接是指连接成功后,如果客户端持续有请求,则一直使用同一个连接。
短连接则是指每次执行完很少的几次查询就断开连接,下次查询再重新建立一个。
建立连接的过程通常是比较复杂的,所以建议在使用中要尽量减少建立连接的动作,也就是尽量使用长连接。
长连接问题:
全部使用长连接后,有些时候 MySQL 占用内存涨得特别快。这是因为 MySQL 在执行过程中临时使用的内存是管理在连接对象里面的。这些资源会在连接断开的时候才释放。所以如果长连接累积下来,可能导致内存占用太大,被系统强行杀掉(OOM),从现象看就是 MySQL 异常重启了。
解决方案:
1、定期断开长连接。使用一段时间,或者程序里面判断执行过一个占用内存的大查询后,断开连接,之后要查询再重连。
2、如果用的是 MySQL 5.7 或更新版本,可以在每次执行一个比较大的操作后,通过执行 mysql_reset_connection 来重新初始化连接资源。这个过程不需要重连和重新做权限验证,但是会将连接恢复到刚刚创建完时的状态。
2、查询缓存
MySQL 5.6之前的版本查询缓存功能是默认开启的,5.6之后是默认关闭的,MySQL 8.0 版本直接将查询缓存的整块功能删掉
当mysql接收到查询请求时,会先查询缓存,如果开启了查询缓存功能,之前的查询语句和结果会以 key-value 对的形式,被直接缓存在内存中,key 是查询的语句,value 是查询的结果。如果查询请求命中缓存就直接将对应的结果返回给客户端,如果缓存未命中则继续执行之后的阶段执行完成后查询结果会被放到缓存中。
建议不要使用查询缓存,查询缓存的失效非常频繁,只要有对一个表的更新,这个表上所有的查询缓存都会被清空。
所以除非是静态数据,如系统配置表这种基本不更新的表
MySQL 也提供了针对某个表启用查询缓存功能的方式,将参数 query_cache_type 设置成 DEMAND,这样对于默认的 SQL 语句都不使用查询缓存。而对于确定要使用查询缓存的语句,可以用 SQL_CACHE 显式指定,像下面这个语句一样
select SQL_CACHE * from T where ID=10;
3、分析器
mysql会分析请求的sql语句,是否符合MySQL的语法,如果语句不正确,会收到“You have an error in your SQL syntax”的错误提醒
4、优化器
优化器是在表里面有多个索引的时候,决定使用哪个索引,或者在一个语句有多表关联的时候,决定各个表的连接顺序
5、执行器
MySQL 通过分析器知道了要做什么,通过优化器知道了该怎么做,于是就进入了执行器阶段,开始执行语句。开始执行的时候,要先判断一下对这个表 T 有没有执行查询的权限,如果没有,就会返回没有权限的错误,如果有权限,就打开表继续执行。打开表的时候,执行器就会根据表的引擎定义,去使用这个引擎提供的接口。
6、存储引擎
MySQL支持多种存储引擎,每种引擎有着一些自己独特的功能,用户在使用的时候,可以根据自己的业务场景来使用不同的存储引擎。
| 存储引擎 | 特点 |
|---|---|
| InnoDB | 支持事务,行锁,支持MVCC多版本控制,并发性高 |
| MyISAM | 不支持事务,表锁,mysql8.0后被废弃,并发很低,资源利用率也很低 |
| Memory | 内存存放,数据安全性不高,读取速度快 |
| TokuDB | 支持事务,支持压缩,高速写入功能,在线online DDL,不产生索引碎片 |
| MariaDB columnstore | 列式存储引擎,高压缩功能 |
| Blackhole | 不存储数据,数据写入时只写binlog |
MySQL最常用的存储引擎为:MyISAM和InnoDB,InnoDB和MyISAM对比
| 区别 | InnoDB | MyISAM |
|---|---|---|
| 事务的支持 | 支持事务 | 不支持 |
| 锁粒度 | 行锁 | 表锁 |
| 并发性 | 高并发 | 低并发 |
| 构成机构和缓存机制 | 数据和索引文件都存储在.Ibd文件里,并且缓存在内存里 | 数据文件扩展名.MYD 索引文件扩展名.MYI 只缓存索引文件,不缓存数据文件 |
| select count(*) | 需要扫描全表,统计所有行数 | 计数器中取出保存的行数 |
