MySQL专栏(一)-->数据库架构要牢记

213 阅读6分钟

“这是我参与更文挑战的第25天,活动详情查看: 更文挑战

欢迎关注公众号:卢卡多多

目光所致:

MySQL的专栏第一篇来了,

废话少说,直接开整:

mysql的基本架构层

MySQL 可以分为 Server 层和存储引擎层两部分。

不同的存储引擎--->共用server层; 连接器到执行器

其中存储引擎负责对数据的存储和提取;

现在最常用的存储引擎是 InnoDB,它从 MySQL 5.5.5 版本开始成为了默认存储引擎。

server层的构成:(特别干货)

  • 连接器: 建立连接,开启认证,确定权限

  • 查询缓存: 查询是否命中缓存语句

  • 分析器: 语法,词法,语句合法性校验

  • 优化器: 语句执行的过程方案,效率的制定

  • 执行器:执行器的一个过程,执行语句

简单来说, 语句通过校验合法,确定执行顺序,然后执行,

连接器:

本质上:与客户端建立连接

- 获取权限

-  管理连接

mysql -hip -Pport -u$user -p

上述是命令行,但是生产服务器就不能这么写了,会泄露你的密码;

一般的本地使用mysql时调用的命令:

mysql -uroot -pxxx 中的mysql是

指客户端工具,是用来与服务端建立连接的

Tcp建立连接之后,验证客户端用户名密码,开启认证身份

如果用户名或密码不对,你就会收到一个"Access denied for user"的错误,然后客户端程序结束执行。

如果正确就会读取权限,在权限表中获取到,修改权限不会影响当前的链接, 重启可以使用新的权限

连接成功后:

SHOW PROCESSLIST     //查看这个链接 ,其中command显示sleep就代表 这个是一个空闲链接

客户端长时间没操作,连接器会在参数wait_timeout,8小时之后断开, 默认是8小时

如果在连接被断开之后,客户端再次发送请求的话,就会收到一个错误提醒: Lost connection to MySQL server during query。这时候如果你要继续,就需要重连,然后再执行请求了。

建立连接过程比较复杂,--通常多数使用长连接-->避免连接动作

但是全部使用长连接后,你可能会发现,有些时候 MySQL 占用内存涨得特别快,这是因为 MySQL 在执行过程中临时使用的内存是管理在连接对象里面的。这些资源会在连接断开的时候才释放。所以如果长连接累积下来,可能导致内存占用太大,被系统强行杀掉(OOM),从现象看就是 MySQL 异常重启了。

MySQL连接过程中时常OOM,怎么办?

怎么解决这个问题呢?你可以考虑以下两种方案。

  • 定期断开长连接。使用一段时间,或者程序里面判断执行过一个占用内存的大查询后,断开连接,之后要查询再重连。

  • 如果你用的是 MySQL 5.7 或更新版本,可以在每次执行一个比较大的操作后,通过执行 mysql_reset_connection 来重新初始化连接资源。这个过程不需要重连和重新做权限验证,但是会将连接恢复到刚刚创建完时的状态。

查询缓存

当前连接器建立后,  可以执行select的查询语句了,

先不会直接执行,会去缓存中查询根据key_value的形式, key是语句本身,value是执行后的结果,

如果说当前的key已经执行过,那就会找到value直接返回, 如果没有再执行查询语句select

注意事项

1.缓存需要语句完全相等,包括参数。

2.表更新后就会失效 因此,只有在表更新频率不高,查询语句完全一致的情况下,可以手动开启缓存,其他一律关闭。

注意:mysql8之后,取消了缓存功能

所以我们一般不使用缓存,因为缓存的弊大于利

mysql> select SQL_CACHE * from T where ID=10;   // SQL_CACHE显示指定用缓存,但是MySQL8.0之后去删除这个功能了

分析器(语句识别)

如果说当前缓存没有,或者没有命中缓存,就开始直接执行SQL语句了;

语法识别,将参数和关键字逐一识别

优化器

经过分析器的语法分析,代表这个SQL已经是通过标准,可以执行

优化器是在表里面有多个索引的时候,决定使用哪个索引;或者在一个语句有多表关联(join)的时候,决定各个表的连接顺序。比如你执行下面这样的语句,这个语句是执行两个表的 join:

也就是优化,链表查询时,哪种效率更快

类似于火车要去目的地的路线选择,

执行器

MySQL 通过分析器知道了你要做什么,通过优化器知道了该怎么做,于是就进入了执行器阶段,开始执行语句。

通过对分析器分析好的语法,优化器优化好的执行方案--来执行具体的语句;

执行器会首先看当前语句操作的表,是否有权限, precheck如果有就

根据当前的存储引擎提供的接口,对语句进行执行,

mysql> select * from T where ID=10;

ERROR 1142 (42000): SELECT command denied to user 'b'@'localhost' for table 'T'

举个例子

比如我们这个例子中的表 T 中,ID 字段没有索引,那么执行器的执行流程是这样的:

  • 调用 InnoDB 引擎接口取这个表的第一行,判断 ID 值是不是 10,如果不是则跳过,如果是则将这行存在结果集中;

  • 调用引擎接口取“下一行”,重复相同的判断逻辑,直到取到这个表的最后一行。

  • 执行器将上述遍历过程中所有满足条件的行组成的记录集作为结果集返回给客户端。至此,这个语句就执行完成了

卢卡问答

我给你留一个问题吧,如果表 T 中没有字段 k,而你执行了这个语句 select * from T where k=1, 那肯定是会报“不存在这个列”的错误: “Unknown column ‘k’ in ‘where clause’”。你觉得这个错误是在我们上面提到的哪个阶段报出来的呢?

答案

分析器会分析你当前要做的,语法,词法分析, 如果当前这个词都没有----我的答案是分析器;

因为分析器是表示, 当前语句的组成部分,--是否合法包括关键字

优化器----在全部参数合法,语法没问题的情况下,是否可以执行,有哪几种执行方案,

执行器才是具体根据存储引擎的接口去执行

卢卡寄语:

最近在刷丁奇的MySQL,对数据库的印象更加深刻了,所以我想做个专栏输出自己的笔记,其中对于Mysql的架构已经有了明确的认识了,因为对于数据库,我们首先要了解架构组成,才能更好的执行,解决问题。

我是卢卡,一个努力寻找生活答案的人,欢迎关注公众号,卢卡多多,晚安了