mysql in优化_MySQL 探秘: 1 整体架构

新开坑,计划做一系列专辑。由于 MySQL 源码太庞大,不可能面面俱到,先从丁奇《MySQL 实战 45 讲》[1] 案例开始入手,case by case 来做分享。同时强烈推荐丁奇的课,真的是受益匪浅,感谢感谢~~

最新版本己经是 MySQL 8.0 了,和我当初使用 5.5 差距非常大,增加很多实用功能也做了很多优化。对于我个人来讲,很陌生,也是重新学习的过程。

案例

本次分享一个 SQL 是如何执行的,先看这个案例,如果访问不存在的字段,那么报错是在 MySQL 哪个层呢?

select a,b from mytest.test where k =1;

另外刚毕业时面试百度,问我 mvcc 是在哪一层的,直接就蒙逼了:(

整体架构

ac251595b089e47e581a98a996557972.png

mysql arch

提到 MySQL 架构这个图是必看的,为了支持不同的存储引擎,分为两层:Server 层和存储引擎层。做过 DBA 的都知道,redo, undo log 这些是事务相关的,都属于引擎层,具体就是 innodb 的,而 binlog 是所有引擎通用的,所以在 Server 层。目前 MySQL 大部分公司只会用过 innodb, 并且也是默认引擎。

8747b7b1a3adafa4191b754d3d3a7c58.png

tidb arch

同时我们也可以看下最近几年新兴的 TiDB[2] , 整体分层结构并无太大区别,但是因为底层引擎是分布式的 TiKV[3], 所以生成执行计划与执行器执行还是有很大区别的,并且执行时还要考滤 rpc 超时等等。

Server

Server 层具体包括连接器,查询缓存,分析器,优化器与执行器。具体看一下每个模块的作用,后面会用 debug 方式查看

1. 连接器

负责处理新建连接,用户名密码认证,接收发送请求等功能。在 thread_handling 默认是 one-thread-per-connection 一个新建连接会新启动一个线程。

root@myali:~/mysql# ps -T -p 10477 | wc -l
28
root@myali:~/mysql# bin/mysql -uroot -h127.0.0.1
mysql> show full processlist;
+----+------+-----------------+------+---------+------+----------+-----------------------+
| Id | User | Host            | db   | Command | Time | State    | Info                  |
+----+------+-----------------+------+---------+------+----------+-----------------------+
|  2 | root | localhost:58506 | NULL | Query   |    0 | starting | show full processlist |
+----+------+-----------------+------+---------+------+----------+-----------------------+
1 row in set (0.00 sec)

mysql> exit
Bye
root@myali:~/mysql# ps -T -p 10477 | wc -l
29

可以看到线程个数随之变化,当然 MySQL 这么做肯定低效,所以开启线程池或是线程复用 thread_cache_size, 为了测试我把这个参数关掉了。

以前在 ganji 的时候,业务 php 经常会有连接失败的情况,是个不错的分析 case 啊:(

2. 查询缓存

很古老的东西了,最新版本也己废弃,原因在于效率太低,Query_cache 属于表级别的,任何更新都会使之失效。

3. 分析器

以前在 ganji 做 SQL 自动上线[4] 时就用到了这块技术,使用 lex&yacc 技术将一条 sql 解析成 ast 抽象语法树,然后对之进行 sql 审核后再上线。基本大公司的上线平台也是同样套路。

至于 MySQL 这块也差不多,将 sql 识别成 MySQL 认可的语法,然后交给下一层去执行。据说 TiDB 的 sql parser 实现效率最高,很多 go 的库也都在使用,以后有机会我也试用下。

4. 优化器

经过 parser 后的 SQL,就知道要获取什么样的数据了,但是我们知道 SQL 是一种声明式语言,不会指导数据库如何去获取数据,那么在执行器执行前,就要经过优化器去分析一波,选择哪个索引合适。这一块 MySQL 和 TiDB 区别还是很大的,以后有机会再细看。

5. 执行器

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

这一层会对用户是否有查询权限进行校验,如果没有返回报错。有的话调用 Innodb 引擎层接口获取数据,循环获取满足条件的行数据。

案例

回到文章开头的案例,如果字段不存在肯定报错,这个属于哪层呢?

cmake . -DCMAKE_INSTALL_PREFIX=/root/my-mysql8 \
-DMYSQL_DATADIR=/root/my-mysql8/data \
-DWITH_BOOST=/root/my-mysql8/boost/boost_1_70_0 \
-DSYSCONFDIR=/etc \
-DEFAULT_CHARSET=utf8mb4 \
-DDEFAULT_COLLATION=utf8mb4_general_ci \
-DENABLED_LOCAL_INFILE=1 \
-DWITH_DEBUG=1 \
-DSYSCONFDIR=/root/my-mysql8/etc \
-DEXTRA_CHARSETS=all

先编译 MySQL,记住一定要加 WITH_DEBUG 选项

nohup sh mysql.server start --debug  &

然后启动并打开调式模式。

bin/mysql -uroot -h127.0.0.1 -e "select * from mytest.test where a=1"

trace 文件在 /tmp/mysqld.trace, 我们直接截取 sql 执行的报错部分展示出来

T@3: | | | | >handle_query
T@3: | | | | | THD::enter_stage: 'init' /root/mysql-5.7.23/sql/sql_select.cc:121
T@3: | | | | | >PROFILING::status_change
T@3: | | | | | <:status_change>T@3: | | | | | >SELECT_LEX::prepare
T@3: | | | | | | opt: (null): starting struct
T@3: | | | | | | opt: join_preparation: starting struct
T@3: | | | | | | opt: select#: 1
T@3: | | | | | | >SELECT_LEX::setup_conds
T@3: | | | | | | | info: thd->mark_used_columns: 1
T@3: | | | | | | | >find_field_in_table_ref
T@3: | | | | | | | | enter: table: 'test'  field name: 'k'  item name: 'k'  ref 0x7fd620007aa8
T@3: | | | | | | | | >find_field_in_table
T@3: | | | | | | | | | enter: table: 'test', field name: 'k'
T@3: | | | | | | | | T@3: | | | | | | | T@3: | | | | | | | >find_field_in_table_ref
T@3: | | | | | | | | enter: table: 'test'  field name: 'k'  item name: 'k'  ref 0x7fd620007aa8
T@3: | | | | | | | | >find_field_in_table
T@3: | | | | | | | | | enter: table: 'test', field name: 'k'
T@3: | | | | | | | | T@3: | | | | | | | T@3: | | | | | | | >check_grant_column
T@3: | | | | | | | | enter: table: test  want_privilege: 1
T@3: | | | | | | | T@3: | | | | | | | >my_error
T@3: | | | | | | | | my: nr: 1054  MyFlags: 0  errno: 2
T@3: | | | | | | | | >my_message_sql
T@3: | | | | | | | | | error: error: 1054  message: 'Unknown column 'k' in 'where clause''
T@3: | | | | | | | | | >mysql_audit_acquire_plugins
T@3: | | | | | | | | | 

可以看到字段不存在的报错是在 mysql_parse 之后,在 prepare 函数里做的检查,这一块属于 optimize 优化器层前的预处理

另外非常有意思的是,字段不存在的报错竟然是在检查权限 check_grant_column 函数中。感兴趣的可以自行 debug 看下 trace 文件,可以帮助快速定位源码与流程。

select 完整流程

通过 trace 文件追踪了 mysql 源码,大致清楚了整体流程。比较关键的数据结构是 THD, 每个连接一个实例。这个结构光定义就 3300 行代码,还不包括方法实现... 囧:(

  1. login_connection 处理新连接,Global_THD_manager::add_thd 生成 THD,acl_authenticate 用户认证
  2. dispatch_command 分发命令
  3. mysql_parse 分析器,主要就是词法解析 lex_start 和语法解析 parse_sql
  4. check_access 检查 DB 权限,open_tables_for_query 打开 table
  5. handle_query 主要就是 prepareoptimize
  6. exec 调用引擎接口获取数据,然后 sending_data 给客户端
  7. Global_THD_manager::remove_thd 连接退出
大致 select sql 完整流程就是这些,不包括事务,不包括 innodb 层处理。

小结

这次分享参考了《MySQL 实战 45 讲》[1] 第一节,评论的内容也更精彩,推荐大家围观。以后面还会分享更多关于 MySQL 的内容,如果感兴趣,可以关注并转发(:

参考资料

[1]

《MySQL 实战 45 讲》: https://time.geekbang.org/column/intro/139,

[2]

tidb 源码分析: https://pingcap.com/blog-cn/tidb-source-code-reading-2/,

[3]

tikv 是什么: https://pingcap.com/blog-cn/#TiKV,

[4]

sql 自动上线: https://myslide.cn/slides/9070,

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/297622.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

清华姚班/智班2020级新生来了!中国奥数新晋“一姐”在列,湖南、湖北人数最多...

全世界只有3.14 % 的人关注了爆炸吧知识乾明 金磊 发自 凹非寺量子位 报道 | 公众号 QbitAI清华姚班/智班&#xff0c;又双叒叕纳一批英才。根据教育部公示的保送生拟录取名单的信息&#xff0c;清华大学姚班/智班2020年已拟定录取31名应届生&#xff0c;他们都是来自各省的顶级…

成长 | 《大厂晋升指南》学习总结(下)

【学习总结】| Edison Zhou上一篇总结了面评技巧和学习方法部分&#xff0c;本篇总结做事方法和转向提升部分。温馨提示&#xff1a;文中的贴图均来自极客时间《大厂晋升指南》课程。1做事方法概要关于做事能力&#xff0c;有三条业界达成共识的判断标准&#xff0c;分别是闭环…

在SD/MMC卡中可读写的FAT文件系统

2019独角兽企业重金招聘Python工程师标准>>> FAT文件系统 关于eLua中FAT文件系统的实现是使用了来自Elm Chan的一个很好的FatFS文件包。它可以在读写模式中处理FAT12,FAT16和FAT32文件系统。而且它打包了很多功能通过封装的形式。跟ROM文件系统一样它也与C库集成在一…

hql取满足条件最新一条记录_MySql 之一条查询sql的执行过程

每当我把一条查询sql语句写完了&#xff0c;并且执行完得到想要的结果。这时我就在想为什么我写这样的一条sql语句&#xff0c;就能给我查询出我想要的结果&#xff0c;为什么我写了update就能更新一条语句&#xff1f;它们的执行过程是什么样的&#xff1f;它们的原理是什么&a…

高糊马赛克秒变高清,表情帝:这还是我吗?

全世界有3.14 % 的人已经关注了爆炸吧知识来源&#xff1a;机器之心参与&#xff1a;魔王、杜伟有了这个工具&#xff0c;我们终于能够看到马赛克下的那张脸了。给出一张高糊人脸照片&#xff0c;你能用它做什么&#xff1f;杜克大学近期的一项研究可以将高糊人脸照片转换成清晰…

diy计算机组装注意事项,自己组装电脑要注意什么?DIY老司机教你装机注意事项...

相比品牌机&#xff0c;组装电脑的优势在于个性化的DIY硬件定制&#xff0c;让玩家可以自由选择适合自己的配置&#xff0c;可以说可玩度非常高。如今&#xff0c;电脑硬件设计已经十分人性化&#xff0c;网上还有很多直播教程&#xff0c;用视频的方式直观地教大家装机&#x…

Dapr + .NET Core实战(三)状态管理

状态管理解决了什么分布式应用程序中的状态可能很有挑战性。例如&#xff1a;应用程序可能需要不同类型的数据存储。访问和更新数据可能需要不同的一致性级别。多个用户可以同时更新数据&#xff0c;这需要解决冲突。服务必须重试 与数据存储交互 时发生的任何短期暂时性错误。…

Building JavaScript Games for Phones Tablets and Desktop(3)-创造一个游戏世界

2019独角兽企业重金招聘Python工程师标准>>> 创造一个游戏世界 这章教会你如何通过内存中储存的信息创造一个游戏世界。介绍了基本类型和变量并且这些变量是如何储存和改变信息的。接下来&#xff0c;你会看到如何用对象储存更复杂的信息&#xff0c;里面包含成员变…

我女朋友让我删前任,我明明删了她还是要分手...

1 人家都已经删了你还有什么不满意&#xff1f;&#xff1f;&#xff1f;▼2 高跟鞋翻车现场▼3 渣男总能渣出新花样▼4 现在的小朋友懂得也太多了吧&#xff01;▼5 耍帅不可怕&#xff0c;谁失败谁尴尬▼6 朋友&#xff0c;你清醒一点&#xff01;那个小手是鼠标&#…

你知道哪些开源基金会?

从 RMS 创立 FSF 发起自由软件运动&#xff0c;再到 OSI 成立并明确开源软件定义&#xff0c;这种崇尚开放协作的软件开发模式迅速席卷全球。除 FSF 与 OSI 外&#xff0c;还陆续诞生了许多致力于推广和发展开源的基金会。开源基金会对于开源软件和开源社区的组织、发展、协同创…

bpmn如何查看代码 idea_提高程序员效率的IDEA插件推荐(五大神器)

1. SequenceDiagramSequenceDiagram 可以根据代码调用链路自动生成时序图&#xff0c;超级赞&#xff0c;超级推荐&#xff01;这对研究源码&#xff0c;梳理工作中的业务代码有极大的帮助&#xff0c;堪称神器。安装完成后&#xff0c;在某个类的某个函数中&#xff0c;右键 -…

一张纸还能上天能救命?理工男宁愿放弃NASA百万年薪,也要回家折纸?!

全世界有3.14 % 的人已经关注了爆炸吧知识一张纸能做什么&#xff1f;小时候&#xff0c;它可能默默记录着你天马行空的想象力&#xff1a;而到了艺术家手中&#xff0c;它们就会变幻成各种各样精妙绝伦的艺术品&#xff1a;可当一双文艺的手&#xff0c;遇上一颗聪明无比的“理…

【干货】单日10亿GMV的.NET5电商平台,是如何设计的?

自京东和唯品会转了Java&#xff0c;.NET就一直缺乏高并发电商案例&#xff0c;.NET5能做高并发电商吗&#xff1f;必须的&#xff0c;别停留在.NET Framework的旧印象了&#xff01;这里为大家分享一家上市公司的项目案例&#xff0c;纯.NET5电商平台&#xff0c;轻松承接双11…

通过 Lotus Domino Java 代理消费 Web 服务

Web 服务是一种允许两台或更多的计算机在网络中交互的系统设计。这种服务的主要优点是&#xff0c;它是在多台不同操作系统的计算机和应用服务器之间发送对象的标准解决方法。例如&#xff0c;我们的公司使用 Web 服务从一台运行 Microsoft .NET Framework 的计算机向基于 IBM …

goahead如何使用cgi服务_QQ如何设置使用代理服务器?

很多人可能会问了&#xff0c;QQ上可以设置代理服务器吗?答案是可以的。今天就为大家详细介绍一下&#xff0c;如何在QQ上设置代理服务器的。1、双击QQ图标&#xff0c;打开QQ登录界面&#xff0c;我们就可以看到界面右上角有一个“设置”按钮。QQ如何设置使用代理服务器12、点…

android listview添加数据_Android面经分享,失业两个月,五一节前拿到offer

秦子帅明确目标&#xff0c;每天进步一点点.....作者 | 天天有道地址 | juejin.im/post/5eb01866f265da7b9c24562c基本介绍今天介绍一位朋友的经历&#xff1a;从3月初开始复习&#xff0c;准备面试题。复习的资料主要为《Android开发艺术探索》和jsonchao的博客&#xff0c;…

Dapr + .NET 实战(四)发布和订阅

什么是发布-订阅发布订阅是一种众所周知并被广泛使用的消息传送模式&#xff0c;常用在微服务架构的服务间通信&#xff0c;高并发削峰等情况。但是不同的消息中间件之间存在细微的差异&#xff0c;项目使用不同的产品需要实现不同的实现类&#xff0c;虽然是明智的决策&#x…

这些数学趣图,数学老师看了后会怎么想?

全世界有3.14 % 的人已经关注了爆炸吧知识这个扣分不?我的人生98%的时间都是无比正确的数学与我不能言语的关系最深情的告白限速是......当我完成数学作业后....维生素C的来历高数课堂恩..... 来拜师了啊, 好好学习. 为师给你命名: 阿尔法狗.这个是驻点, 这是最值, 这些机器学…

COM 组件设计与应用(六)

一、前言  1、与 《COM 组件设计与应用(五)》的内容基本一致。但本回讲解的是在 vc.net 2003 下的使用方法&#xff0c;即使你不再使用vc6.0&#xff0c;也请和上一回的内容&#xff0c;参照比对。   2、这第一个组件&#xff0c;除了所有 COM 组件必须的 IUnknown 接口外&…

python 柱状图 间距_专题第18篇:Python 绘图入门

我的施工之路1我的施工计划2数字专题3字符串专题4列表专题5流程控制专题6编程风格专题7函数使用8面向对象编程(上篇)9面向对象编程(下篇)10十大数据结构11包和模块使用总结12Python正则专题总结13设计模式14Python时间模块总结15 Python 装饰器16 Python 迭代器17 Python 生成器…