InnoDB执行流程

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 数据库系统能够接受 SQL 语句,并返回数据查询的结果,或者对数据库中的数据进行修改,可以说几乎每个程序员都使用过它。所以,解析一下 MySQL 编译并执行 SQL 语句的过程,一方面能帮助你加深对数据库领域的编译技术的理解。另一方面,由于 SQL 是一种最成功的 DSL(特定领域语言),所以理解了 MySQL 编译器的内部运作机制,也能加深你对所有使用数据操作类 DSL 的理解,比如文档数据库的查询语言。另外,解读 SQL与它的运行时的关系,也有助于你在自己的领域成功地使用 DSL 技术。

数据库系统能够接受 SQL 语句,并返回数据查询的结果,或者对数据库中的数据进行修改,可以说几乎每个程序员都使用过它。所以,解析一下 MySQL 编译并执行 SQL 语句的过程,一方面能帮助你加深对数据库领域的编译技术的理解。另一方面,由于 SQL 是一种最成功的 DSL(特定领域语言),所以理解了 MySQL 编译器的内部运作机制,也能加深你对所有使用数据操作类 DSL 的理解,比如文档数据库的查询语言。另外,解读 SQL与它的运行时的关系,也有助于你在自己的领域成功地使用 DSL 技术。

image-20221207225508793

一条SELECT执行流程

连接层

主要负责用户登录数据库,进行用户的身份认证,包括校验账户密码,权限等操作。如果用户账户密码已通过,连接器会到权限表中查询该用户的所有权限,之后在这个连接里的权限逻辑判断都是会依赖此时读取到的权限数据,也就是说,后续只要这个连接不断开,即时管理员修改了该用户的权限,该用户也是不受影响的。

  • 账户验证
  • 权限分配
  • 线程分配
    • 如果线程满了,则处于线程等待状态
    • 执行结果返回后,该线程不会立刻销毁,而是会将该线程保存起来(线程创建和销毁都牵扯到CPU上下文的切换,会有很大的开销)。如果有别的连接则可以复用该连接,如果长时间没有则会将该线程销毁

Server层

主要包括连接器、查询缓存、分析器、优化器、执行器等,所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图,函数等,还有一个通用的日志模块 binglog日志模块。

  • 缓存层

    • 按照查询语句作为key查找缓存(如果查到直接返回,如果未查到则进入分析器)
  • 分析器

    • 词法分析,一条SQL语句有多个字符串组成,首先要提取关键字,比如select,提出查询的表,提出字段名,提出查询条件等等。
    • 语法分析,主要就是判断你输入的sql是否正确,是否符合mysql的语法。
  • 优化器
    • 根据检索条件(索引,表连接 等等),生成执行计划
    • 选择成本最低的执行计划,调用执行器
  • 执行器
    • 执行前会校验该用户有没有权限,如果没有权限,就会返回错误信息,如果有权限,就会去调用引擎的接口,返回接口执行的结果。

小帖士:Mysql8.0为什么删除缓存层

查询语句和查询结果以键值对的形式被直接缓存在内存中。因为是对SQL语句做hash计算,所以查找缓存的时候,SQL语句必须是字节级的匹配,完全一致的SQL才能命中缓存,也意味着在缓存中SELECT * FROM testselect * from test是不一样的。
一旦涉及到缓存,我们就要考虑缓存失效的问题,如果数据表存在数据(表数据,表结构以及索引)的变更,那么这张表的查询缓存就要被清除。这时候频繁的变更必定导致更大的系统开销。此时查询缓存也就要考虑使用的实际场景有哪些了。
最重要的还有一个大招,就是MySQL查询缓存有严重的可伸缩性问题,并且很容易成为严重的瓶颈。它不能与多核计算机上在高吞吐量工作负载情况下进行扩展。关于这个具体说明,可以参考一下MySQL官方人员的博客文章:https://dev.mysql.com/blog-archive/mysql-8-0-retiring-support-for-the-query-cache

引擎层

  • 根据查询主键ID绑定的 page_id 找到对应数据页
  • 将数据页内容写入到 BufferPool
  • 根据二分查找法从 Page Directory 找到对应的数据槽
  • 在对应数据槽沿着数据的单向链表查找到对应的数据
  • 返回查询结果

一条UPDATE语句的历险记

CREATE TABLE `users` (
  `user_id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(50) COLLATE utf8mb4_general_ci NOT NULL,
  `sex` char(1) COLLATE utf8mb4_general_ci DEFAULT NULL,
  `hobby` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL,
  PRIMARY KEY (`user_id`),
  UNIQUE KEY `idx_name` (`name`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

INSERT INTO `test`.`users` (`user_id`, `name`, `sex`, `hobby`) VALUES (1, 'tom', '男', '唱歌');
INSERT INTO `test`.`users` (`user_id`, `name`, `sex`, `hobby`) VALUES (2, 'mike', '女', 'rap');
INSERT INTO `test`.`users` (`user_id`, `name`, `sex`, `hobby`) VALUES (3, 'tony', '男', '篮球');

我们根据对 users 表的 name 字段建立的唯一索引,然后执行修改语句

UPDATE `users` SET `hobby` = '跳舞' WHERE `name` = 'make';

然后我们分析一下这个事务的整体执行流程。在介绍 SELECT 的时候大体流程是相同的,所以这里我们只把重要的点找出来分析

Server层

  • 分析器

    • 根据二级索引生成对应的执行计划
    • 根据主键索引生成对应的执行计划

    很明显,如果采用二级扫描只需要回表一次就可以拿到数据。如果采用主键索引方案则需要进行全表扫描。所以第一种方案是最优方案

引擎层

  • 根据二级索引B+Tree找到主键ID,然后从主键索引的B+Tree找到数据页的 page_id
  • 将数据页写入buffer pool
  • 从数据页中找到查询的数据
  • 如果找到则判断更新的数据是否发生变化(没有变化则不更新)
  • 将要修改的数据写入到 redo-log
  • 回滚数据写入到 undo-log
  • 事务进入 prepare 状态

Server层

  • 执行器
    • 判断事务是否处于 prepare 状态
    • 将更新记录写入 bin-log
    • 将事务提交,事务变成 commit 状态

总结

本文是对InnoDB执行流程一次简单的探索,为了便于读者理解,其中存在一些不完善的地方。例如:

  • 分析器对于语句的分析报告
  • 优化器如何根据索引计划计算成本
  • 索引计划的计算成本因素是什么
  • 从InnoDB页中取数据的规则
  • 修改数据的时候如果加锁和加在哪里
  • 如果是Insert语句,隐式锁升级过程
  • 在不同隔离级别下,取出的数据为什么不相同
  • MVCC如何在不加锁的情况下保证Mysql的高效查询

是的,Mysql是一个技术栈非常丰富的软件。这里面有很多的疑问和问题,就算拿其中一个写,都需要很长的篇幅去表述。但是不怕,我们把这个庞大的mysql进行拆解,一步步去认识他。带着这些疑问,我们一起来探索Mysql新世界的大门。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
7月前
|
存储 SQL 关系型数据库
Mysql专栏 - mysql、innodb存储引擎、binlog的工作流程
Mysql专栏 - mysql、innodb存储引擎、binlog的工作流程
147 0
|
存储 SQL 缓存
Mysql专栏 - mysql、innodb存储引擎、binlog的工作流程
这次新开了一个个人的mysql专栏,专门用于总结mysql的一些细节以及相关的案例总结,同时也包括了一些mysql的底层实现,在后续的篇章则是根据《mysql技术内幕innodb存储引擎》(第二版)来深入了解mysql中用的最多的存储引擎的内部细节。
125 0