加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 电商 > 正文

MySQL存储引擎之Spider内核深度解析

发布时间:2021-01-13 21:15:56 所属栏目:电商 来源:网络整理
导读:《MySQL存储引擎之Spider内核深度解析》要点: 本文介绍了MySQL存储引擎之Spider内核深度解析,希望对您有用。如果有疑问,可以联系我们。 作者介绍 朱阅岸 ,中国人民大学博士,现供职于腾讯云数据库团队.研究方向主要为数据库系统理论与实现、新硬件平台下的

总的来说,handler类和handlerton结构在整个体系结构中扮演了中间层的角色.你所编写的存储引擎只有满足了handler的要求后,才能顺利插入到运行的MySQL服务器中.所有的网络连接、安全认证、解析和优化由MySQL服务器本身完成,与存储引擎无关.

Spider作为MySQL的一个可插拔引擎,实现了handler类定义的相应的存取方法.Spider本身并不存放数据,而是类似一个代理的功能将访问请求路由到后端的数据节点.Spider提供了两种途径访问后端节点存储的数据.如图6所示,Spider可以遵循MySQL传统的查询处理流程来访问数据,也开发了自有的一套来加速数据访问.在传统的查询处理方式下,SQL查询请求经过查询解析、查询重写、查询优化等步骤.按照生成的查询执行计划,Spider从后端节点拉取数据,交给MySQL服务器处理.Spider在这种查询处理框架之下的一个缺点是不能很好地利用后端节点可并行化特性,同时需要对SQL查询进行两次解析,带来的性能损耗问题比较严重.

在我们的测试中,性能损耗约50%左右.基于这个原因,为了加速聚集、统计等查询,Spider开发团队提供了DirectSQL方式执行查询.DirectSQL的原理类似于Map Reduce方案,将查询直接下发到后端节点,无需在MySQL服务器层进行解析(Map阶段);后端节点将结果返回给Spider,由Spider合并结果集.(Reduce阶段).这个方式很好地利用后端节点可并行处理查询的特点,消除重复解析SQL语句的行为.

图6. MySQL体系下的Spider

上面已经谈到,Spider本身并不存储数据,因此需要将数据访问请求转换成其它方式,例如Handler、Handler Socket以及SQL方式.前面两种访问方式更像是一种NoSQL的数据访问方式,允许查询绕过SQL layer层.Spider允许后端的数据节点可以是不同的数据库系统,通过2PC保证事务提交的原子性.

四、读写流程

为了更清楚地了解Spider的读写流程,我们有必要研究一下数据库系统的查询执行模型,以及MySQL的插拔式引擎如何跟这个模型对接的.

数据库系统基本都采用迭代器模型处理查询,也叫volcano查询执行引擎(发明这个词的学者大概是因为查询执行计划树看起来像一座火山,如图7).执行计划树的上层节点通过get_next方法驱动子节点获取一条元组,子节点递归调用.在叶子节点也就是基本表将数据返回.

这个模型的一个好处就是实现起来很优雅,同时数据流与控制流结合在一起方便程序的调试.这个模型的缺点是函数的大量调用使得进程/线程上下文切换频繁,程序的局部性受到损害.因此,后来针对OLAP场景,采用了向量查询执行模型来减少进程上下文的切换以及保证保证高速缓存的命中率.

再次以图7为例子,图中的SQL语句的功能是查询一个部门的平均薪资.假如在职工表EMP的员工ID字段Dno上存在索引,MySQL在Server层针对该查询语句生成的查询计划如下:顺序扫描部门表,通过索引访问职工表,然后在两表join操作之后进行投影操作.下一个阶段为分组排序操作.上层的操作算子(例如join),驱动子节点调用get_next方法(表扫描方法)获取一条元组.底层操作算子(表访问方法,handler接口定义)将数据返回.至此,我们可以总结一下MySQL体系的工作原理:查询执行计划由MySQL Server层生成,存储引擎受执行计划驱动而访问表.MySQL的handler已经定义好表的访问方法,实现了这些访问方法的存储引擎就可以作为MySQL的插件式引擎而存在.

下面我们对Spider的读写流程结合Server层代码进行分析.

Serve

图7. 查询计划树示例

1、SELECT操作

上面提到Spider的作用类似一个proxy,本身并不存储数据.因此Spider处理SELECT语句(UPDATE与DELETE类似)首先需要根据查询解析的信息生成一个SELECT语句,发送到查询涉及的后端节点,将数据从远端拉到本地,然后进行处理.函数spider_db_append_select_columns根据查询涉及的读集以及写集获取相应的字段,构造一个SQL语句从后端节点拉取数据到本地.如果涉及多个分片,spider将从不同实例获取过来的结果集存放在不同的结果集spider_db_result中.类spider_db_fetch提供了fetch_next,? current_row等方法供上层方法调用.Server层调用get_next方法驱动引擎层获取下一条数据.

对于表访问方法,MySQL实现了索引扫描(ha_index_read)与随机访问(ha_rnd_next)的方法.对于切分为多个分片的DB,索引扫描需要借助优先队列.索引扫描需要区分是否是第一次调用该方法.如果是第一次调用该方法,需要遍历所有的分片读取一条记录,然后插入到优先队列.对应到Spider,如果第一次调用访问远端实例表的方法,需要生成SELECT语句,将远端实例的数据拉到本地存放.在使用索引扫描的情况,MySQL 为每个分片保留一个key buffer以及record buffer.server 利用队列头部的m_top_entry 获得访问的分片ID.接着,调用get_next方法获取相应的元组,将返回的数据存放在record buffer,并插入到优先队列.函数最后将元组从优先队列返回.

为缓解内存等资源的压力,Spider实现全表扫描的方法是逐个分片串行扫描(为了加速,spider也提供了并行扫描数据节点的选项).图8给出了Spider对于上述两种表访问方法的实现机制.

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读