mysql基础架构
先对mysql的一些基础组件进行简单的介绍
- 1.连接器:身份认证和权限相关。
- 2.查询缓存:执行查询语句时,会先查询缓存(mysql8.0版本后移除)。
- 3.分析器:词法分析和语法分析,词法分析即对一条sql语句中的关键字进行提取,如select、insert、update、表名、字段名等等,语法分析即查看sql语句是否有语法错误。
- 4.优化器:根据mysql内部的优化算法按照最优方案执行sql。
- 5.执行器:执行语句,然后从存储引擎返回数据。
mysql主要分为server层和存储引擎层。
- server层:包含连接器、查询缓存、分析器、优化器、执行器等,所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图、函数等等,还有一个mysql通用日志binlog日志模块。
- 存储引擎层:主要负责数据的读取和存储采用可以替换的插件式架构,支持innodb、myisam、memory等存储引擎,其中innodb引擎有自带的日志模块redo log,现在最常用的存储引擎是innodb,从mysql5.5之后就是mysql的默认引擎。
说了这么多,那么sql语句到底在mysql中是怎么执行的呢?
sql语句分析分为查询语句和更新语句。
查询语句
select * from tb_student a where a.age='18' and a.name=' 张三 ';
结合上面的说明,我们来结合这条查询语句分析一下执行过程:
先查询该语句是否有权限,如果没有权限直接报错,如果有权限,在mysql8.0版本前会查询缓存,以这条sql语句为key看是否命中缓存,命中直接返回缓存,没有命中执行下一步。
通过分析器提取该sql语句中的关键字,如select、from、表名tb_student、查询的列、等等,然后判断这个sql语句是否有错误,比如关键字是否拼写错误,没有错误执行下一步。
接下来就是优化器确定执行方案,上面sql语句有两种执行方案,a先查询年龄为18,然后查询name为张三的数据,b先查询name为张三,然后查询age为18的数据,优化器会根据内部的优化算法进行选择执行效率最高的一个方案,确定执行计划后开始执行语句。
进行权限校验,没有权限直接返回错误信息,如果有权限就会调用数据库引擎接口,返回引擎的执行结果。
更新语句
update tb_student a set a.age='19' where a.name=' 张三 ';
执行更新语句不同的是要进行日志记录了,这时候就要引进日志模块了,mysql自带的日志是binlog日志,所有存储引擎都可以使用,innodb引擎有redo log日志,我们就以innodb引擎来分析一下这条更新语句的执行过程:
先查询出张三这一条数据,不会走查询缓存,因为更新语句会导致与该表相关的查询缓存失效。
拿到数据后将age改为19,然后调用引擎api接口,写入这一行数据,innodb引擎把数据保存在内存,同时记录redo log,此时redo log状态为prepare,并告诉执行器,执行完成,随时可以提交。
执行器接收通知后,记录binlog,并提交reod log。
肯定有人疑惑,这里为什么要用两个日志记录,不能用一个日志记录吗?
主要原因如下:
功能不同:
redo log
:是innodb特有的日志,用于保证事务的持久性。在数据库发生崩溃时,通过redo log可以将未持久化到磁盘的数据页恢复到内存,从而实现事务的持久化。binlog
:是mysql server层的日志,主要用于记录数据库所有的变更操作,用于数据恢复、主从复制等。
恢复需求不同:
redo log
:在数据库崩溃时,能让数据库恢复到崩溃前的一致状态,确保已提交的事务不会丢失。binlog
:binlog日志主要进行从某个位置或某个时间点恢复到另一个位置和时间点的恢复。
总结
只用redo log或binlog无法同时满足以上的功能和恢复需求,所以要同时使用redo log和binlog。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论