起因
上学的时候研究数据库的时候大多数是以PG为模板的,最近因为一些原因重新捡起了数据库相关的知识。既然工业界用mysql比较多,而网上对于mysql源码解析的文章虽然不少,但大多数都是浅尝辄止,所以我在这里也尝试着整理一下在阅读源码过程中的思路,也当做个笔记。
思路
其实mysql源码解析最好的资料就在官方文档里,只是很多人没有发现。
MySQL Internals Manual不过上述的文档似乎还停留在5.7以前的版本,只是做个参考。
源码布局
mysql的源码大概有400M,并且2014年以后就已经放到github上维护了,我们的分析工作以8.0版本为准。
首先看一下mysql的源码关键的目录布局以及说明:
名称 | 分类 | 说明 |
---|---|---|
cmake |
编译 |
编译脚本存放处,mysql编译所有的cmake控制脚本都存放在这里,源码相关的散落在各自目录里 |
client | 客户端 | 客户端相关的代码,包括密码管理,安全保障(ssl),链接管理等,8.0之后似乎也要负责dump已经日志传输的工作 |
components | 工具类 | 一些工具类合集,包括密码验证、日志、备份等 |
extra | 三方库 | zlib、rapidjson、protobuf等 |
include | 头文件 | 对外暴露的头文件集合,阅读源码的话建议从这里开始看 |
libbinlogevents | binlog | binlog的事件合集 |
libbinlogstandalone | binlog | 似乎是把上面的libbinlogevents的部分文件编成.a库,暂时不明白为啥要分开 |
libmysql | 接口 | mysql的接口定义集合,包括初始化、CURD接口、版本帮助信息等 |
libservices | 插件 | 用于开发mysql插件用的相关服务,做法类似于向mysql服务中插入自定义回调 |
mysql-test | 测试 | mysql的应用层测试套件集合 |
mysys | 定义 | mysql自定义的算法、数据结构、锁等等,均为跨平台,通常以my_为前缀 |
plugin | 插件 | mysql自带的插件合集,包括fulltext、rewriter等等,均可以热启动 |
router | 集群 | mysql集群的路由功能,用于管理集群的负载分配 |
share | 定义 | 一些通用的文件,编码定义等 |
scripts | 脚本 | 一些常用的脚本,方便管理mysql |
sql-common | sql | 服务端和客户端都需要用得到sql相关的通用代码 |
sql | sql | sql解析核心模块,包括语法分析,生成语法树,查询计划生成,执行等等 |
storage | 存储 | 存储引擎目录,包括innodb、myisam都在这里 |
strings | 定义 | 字符串处理接口定义,跨平台 |
unittest | 测试 | 单元测试集合,可以只关注gtest部分 |
vio | 网络 | 网络虚拟IO接口,统一不同协议的IO交互 |
解释
mysql源码布局中最复杂的就是「sql」和「storage」两个文件夹,这也不难理解,毕竟数据库高度抽象后最主要的就是两大块,即解析与存储。
除了并行处理机制不同之外,PG与mysql最大的区别就在于mysql将解析与存储分离的更加彻底,这也是我感觉mysql能够流行起来的一个重要的原因之一,因为这种设计催生了众多不同目的的存储引擎,很多有能力的大厂甚至能够自行重写一遍存储引擎来适应自己的业务。
后续的安排,我会在简单地介绍一条sql的生命周期之后,重点介绍这两块的代码架构,有些复杂的部分我会单独拎出来讲。
这里我也推荐一下一个朋友的博客,上面有很多关于mysql源码的文章,都是散装的,且写的比较深,不太适合入门。
传送门:Yangming's Blog
本篇只是引子,没什么实质性内容,后续有时间会尽快更新。