mysql 读写引擎_揭秘MySQL存储引擎spider

转自:兴趣部落​buluo.qq.com

导读: Spider是为MySQL/MariaDB开发的一个特殊引擎,具有内嵌分片功能。现在它已经被集成到MariaDB10.0及以上版本中,作为MariaDB的一个新的主要性。Spider的主要功能是将数据分散到多个后端节点,它的作用类似于一个代理。

1. 表链接

Spider的表链接的技术参考ISO/IEC 9075-9:2008 SQL/MED标准。利用spider的这个特性,你可以像操作本地MariaDB实例的表一样来操作远程MariaDB实例上的表,也可以像操作本地MariaDB实例的表一样来操作分布在多个MariaDB实例上的表。当创建一个spider存储引擎的表时,该表指向远程服务器上对应的一张表或者多个实例上的表,就像UNIX/Linux中的软链接一样。远程服务器上的表可以是任何存储引擎的表。

在执行CREATE TABLE命令创建spider引擎的表时,需要添加COMMENT或CONNECTION语法来指定远程服务器的地址等信息。例如,在远程服务器(该服务器是数据节点,假设IP为192.168.0.1)上创建了如下一张表:

spider节点创建一张表指向该表:

spider节点,表字段定义可以忽略。Spider第一次访问表的时候,如果发现没有表字段定义,会从后端节点拉取相关元数据,然后缓存在本地。

Spider的系统表spider_tables记录了各个数据分片的位置信息,类似于编程语言中指针作用。该系统表可以便利spider跨节点的join操作:访问数据所在的机器,然后把数据拉取到本地进行join操作;如果进行join操作字段不是分片字段,那么需要广播SQL语句将数据拉取到spider节点进行join操作。Spider_tables类似图1所示。

图1. Spider表链接

2.事务

Spider分别针对单机事务与XA事务实现了相应的操作事务的方法。图2列出了部分实现的方法。

图2. Spider部分实现的事务接口

Spider参照分布式事务DTP/XA模型实现了分布式XA事务(见图3)。在这个模型中,存在RM(Resource Manager,资源管理器)、TM(Transaction Manager, 事务管理器)以及AP(Application, 应用程序)三种角色。AP通过RM API来操作和管理资源,通过TM接口开启/终止/结束事务。RM与TM之间需要实现XA接口。XA接口定义了两阶段提交的必要步骤,以及RM与TM之间需要进行的交互。Spider扮演的是TM角色,而后端的数据节点扮演的是RM的角色。

图3. 分布式DTP/XA模型

为了使用分布式XA事务,业界定义的XA命令如下:

Spider会在系统表spider_xa中记录XA事务的状态,同时在另外一张系统表 spider_xa_members 中记录参与该XA事务的节点,以便进行操作。在spider中,XA事务分别有四种状态,如图4所示,对应于NOT YET, PREPAED, ROLLBACK 以及 COMMITTED。 Spider在开始PREPARE阶段之际会在系统表 spider_xa中标记该XA事务的状态为NOT YET。在所有数据节点都接收到PREPARE消息以后, 该 XA事务的状态进入到PREPARED阶段。假如在PREPARE阶段,某一个数据节点发生故障,那么spider会回滚该事务。相应地,事务的状态变成ROLLBACK。最后,如果所有参与事务的节点都返回PREPARE OK,该事务进入提交阶段。图5给出了对应上述命令的每一个步骤,spider向后端节点发送的消息。

图4. Spider XA事务状态转换

图5. 执行XA事务,Spider与后端节点的交互

从图5可以看到spider向后端节点发送XA START命令的时候会设置会话级别的事务特性,同时将XA事务ID发送到后端节点。因为XA事务ID由三部分组成,spider会 将这三个部分的解析出来,然后拼接成对应的字符串发送到后端节点。为了节省网络开销,Spider将XA END与XA PREPARE命令合并起来一起发送。也就是在这个 阶段初始,spider在系统表里面记录事务的状态。如果所有的RM都返回OK,那么spider进入PREPARED 状态,准备提交事务。否则,事务进入到回滚状态。

3.插拨式引擎

MySQL最强大的功能之一以及区别于其他关系型数据库系统的一个主要的特色是不同的表能够采用不同的存储引擎。每一个存储引擎都有其优缺点,用户能够根据自己的需要定制MySQL的存储引擎。存储引擎能够控制在哪里以及如何存放、获取数据。它代表了下面物理层提供的抽象逻辑接口,也是数据库执行实际I/O操作的地方。这是一个组件体系结构。在这个结构中,handler类定义了存储引擎提供的接口和功能。因为所有的存储引擎从基类handler继承而来,所以它们能够提供相同的功能。总的来说,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保证事务提交的原子性。

4.读写流程

为了更清楚地了解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层代码进行分析。

图7. 查询计划树示例

4.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对于上述两种表访问方法的实现机制。

图8-1.索引扫描实现

图8-2. 全表扫描

4.2 INSERT操作

MySQL的handler类对于INSERT操作提供的接口函数的名字是write_row。存储引擎想要支持INSERT操作就必须实现write_row方法。Spider对于write_row方法的实现是简单地根据查询解析的信息拼接一条INSERT语句,发往后端节点处理。如果是批量插入操作则需要与MySQL Server层配合,将INSERT语句批量发到后端节点。图9结合一条批量插入的INSERT语句给出MySQL中INSERT操作的具体实现。mysql_insert调用write_row执行具体的插入操作(第8行)。这是存储引擎必须实现的方法。对应于spider,spider根据查询涉及到的列(field)拼成一条INSERT语句(如果是分片数据库,VALUSE中的列必须包含分区键,分区键是自增列的情况除外)。图8中的QUERY将用户ID(ID)和用户名(Name)插入到user表,其中ID是分区键。mysql_insert根据VALUES包含的元组数目,判断是否需要进行批量插入操作。该例子的QUERY的VALUES包含4条元组,所有需要进行批量插入操作。MySQL循环调用write_row方法触发spider生成INSERT语句。Spider的write_row方法实现中会根据分区键将INSERT语句进行分组(第5行~第9行)。图8给出的实例只有两个数据分片,所以SQL语句被分成两组。处理完VALUES以后,spider的INSERT语句也拼接完成。ha_end_bulk_insert方法通知spider完成VALUES处理。此时,spider将INSERT发送到后端节点进行处理(第11行)。

图9. spider中INSERT操作的实现

4.3 DELETE实现

Spider想要支持DELETE操作必须实现MySQL handler类提供的ha_delete_row方法。与INSERT操作不同,DELETE操作需要生成一条SELECT语句将查询涉及的分区键拉到spider节点。这是因为MySQL Server层的“once-a-tuple”的查询执行模型(实际上基本所有的关系数据库系统都采用该模型)会驱动spider逐个拼接DELETE语句,然后发往后端节点。这时候,spider需要知道对应的DELETE语句该往哪个后端节点发送。为了减少网络开销,spider提供了批量发送DELETE语句的功能。

图10给出了spider中delete的实现。MySQL server层首先确定表的访问方法:采用索引扫描或者全部扫描(第5行)。DELETE方法需要执行一次查找操作,调用get_next方法(info.read_record)获取一条元组(第10行)。Spider需要判断是否第一次调用get_next方法。如果是的话,则需要生成SELECT语句,将数据节点的数据拉到本地。否则,spider直接从本地返回数据给上层调用者。接下来,server层调用ha_delete_row方法将数据删除。这是存储引擎需要具体实现的方法。由于Spider本身并不存储数据的缘故,其实现delete操作的主要思想是利用从后端节点拉取过来的数据(分区键,过滤条件等),拼接成一条DELETE语句。然后,发送该请求到数据节点。Spider为了优化网络开销,提供了批量发送DELETE语句的选项。

UPDATE操作的实现类似DELETE,都需要spider生成SELECT语句从后端节点拉取数据。只不过,UPDATE在更新区分键的时候,可能需要多一次DELETE操作(删除原来分区的数据,将新的数据插入到不同的分区)。

图10. DELETE实现

5.总结

Spider的最大亮点是为MySQL的使用者提供分库分表的中间件解决方案,同时在SQL语法上兼容MySQL。这得益于spider作为MySQL的插拔式引擎而存在。 Spider 是一个proxy,其本身并没有存储数据,因此上层的读写表请求需要转换成SQL语句,重新路由到后端的数据节点。相比其它的中间件解决方案,spider的查询解析次数都是两次,并没有过多开销。此外,spider还针对聚集、排序等操作提供了MAP REDUCE的解决方案。总而言之,从兼容性、性能上衡量,spider是MySQL分库分表的一个不错的选项。

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

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

相关文章

python中的与或非_「Python基础」 While 循环语句

Python 编程中 while 语句用于循环执行程序,即在某条件下,循环执行某段程序,以处理需要重复处理的相同任务。其基本形式为:while 判断条件:执行语句……执行语句可以是单个语句或语句块。判断条件可以是任何表达式&…

lamp mysql大小限制_LAMP 调优之:MySQL 服务器调优

关于 MySQL 调优有 3 种方法可以加快 MySQL 服务器的运行速度,效率从低到高依次为:替换有问题的硬件。对 MySQL 进程的设置进行调优。对查询进行优化。替换有问题的硬件通常是我们的第一考虑,主要原因是数据库会占用大量资源。不过这种解决方…

go定时器 每天重复_Go语言学习基础-定时器、计时器

Timer计时器如果希望在将来的某个时间点执行Go代码,或者在某个时间间隔重复执行Go代码,使用Go内置的timer和ticker功能。先看定时器timer,然后再看计时器ticker。定时器代表未来的单个事件。告诉定时器需要等待多长时间,它返回一个…

html类名定义规则_HTML入门笔记1

HTML 是谁发明的?Tim Berners-LeeHTML起手式&#xff1a;HTML起手式 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0&q…

mysql主从虚拟机_虚拟机centos7Mysql实现主从配置

环境搭建在虚拟机上和创建两个一模一样的centos7系统&#xff0c;并安装相同版本的mysql(可以先创建一个再克隆)在master上操作登录mysqlmysql -u root -p使用mysqluse mysql;创建用户CREATE USER lystbc1% IDENTIFIED BY Lys135426tbc;给用户授权GRANT REPLICATION SLAVE ON *…

怎样检测mysql5.5安装成功_64位wiN7系统中装配MySQL5.5.17(测试安装成功哦!)

64位wiN7系统中安装mysql5.5.17(测试安装成功哦&#xff01;&#xff01;~~)下载地址&#xff1a;[url] http://www.mysql.com/downloads/mysql/[/url]下载的话需要登录,你只需按照要求注册一个账号,然后下载即可.我下载的是mysql-5.5.17-winx64.msi版本.安装步骤:Step 1. Mysq…

xcode 创建模拟器_Xcode编译WebKit

下载WebKit源码1)进入https://webkit.org/2)点击页面的 Get Started 进入新页面&#xff0c;如下图所示3)点击 Getting the code 进入新页面&#xff0c;如下图所示4)在源码下载页面&#xff0c;有多种下载方式&#xff0c;包括直接下载代码zip包&#xff0c;通过SVN下载&#…

mysql iscsi_iscsi共享存储的简单配置和应用

1、环境介绍SCSI(Small Computer System Interface)是块数据传输协议&#xff0c;在存储行业广泛应用&#xff0c;是存储设备最基本的标准协议。从根本上说&#xff0c;iSCSI协议是一种利用IP网络来传输潜伏时间短的SCSI数据块的方法&#xff0c;ISCSI使用以太网协议传送SCSI命…

request mysql 接口_TP5接口开发

开启debug调试模式(正式上线建议关闭)config.php// 应用调试模式app_debug > true,设置输出类型index.phpnamespace app\index\controller;class Index{public function index(){$data [name > steven, age > 24];return json([code > 0, msg > 操作成功, data…

django和mysql写注册_Django电商项目---完成注册页面和用户登录

完成基本的创建项目、用户注册、登录、注销功能创建Django项目,创建df_user的App创建静态文件夹static(跟manage.py保持在同一级别下)复制静态文件(css images js)到static路径下修改settings.py文件修改templates路径修改数据库新添加静态文件加载路径Pycharm连接mysql数据库…

命令行进入指定目录_VIM学习笔记 操作目录(Manipulate Directory)

在目录间移动使用以下命令&#xff0c;可以显示当前所在的目录&#xff1a;:pwd使用以下命令&#xff0c;在Linux下可以进入HOME目录&#xff0c;而在Windows下则显示当前所在目录&#xff1a;:cd使用以下命令&#xff0c;可以进入指定的目录&#xff1a;:cd D:tepm使用以下命令…

mysql cluster双机_GitHub - sophys/mysqlha: 博客“Mysql-cluster数据库集群双机HA研究”测试代码...

mysqlha本代码是基于博客Mysql-cluster数据库集群双机HA研究所写的。测试采用的是32位环境&#xff0c;linux环境为debian&#xff0c;如果是其他系列只需修改部分指令即可。mysql-cluster版本位&#xff1a;mysql-cluster-gpl-7.2.7-linux2.6-i686.tar.gz&#xff0c;可自行去…

mysql gtid基础_MySQL 基础知识梳理学习(四)----GTID

在日常运维中&#xff0c;GTID带来的最方便的作用就是搭建和维护主从复制。GTID的主从模式代替了MySQL早期版本中利用二进制日志文件的名称和日志位置的做法&#xff0c;使用GTID使操作和维护都变得更加简洁和可高。1.GTID的优点(1)基于GTID搭建主从复制根据简单。(2)可以确保每…

k8s pod MySQL环境变量_Kubernetes 配置Pod和容器(一)定义容器环境变量

此页展示了如何给运行在Kubernetes Pod中的容器定义环境变量。开始之前必须有一个Kubernets集群&#xff0c;和一个能和集群沟通的kubectl命令行工具。如果你还没有集群&#xff0c;你可以用Minikube建立一个集群。给容器定义环境变量当你建立了一个Pod,你可以给你运行在Pod中的…

koa2 mysql 中间件_Koa2第二篇:中间件

第一篇介绍了生成器目录设计。xyzcoding&#xff1a;Koa2第一篇&#xff1a;详解生成器​zhuanlan.zhihu.com接下来学习Koa2的中间件。Koa2本身只能算一个极简的HTTP服务器&#xff0c;自身不内置中间件&#xff0c;但是提供中间件内核。中间件是Koa2的核心&#xff0c;因此需要…

mysql命令行如何建库_MySQL心得2--命令行方式建库和表

1.创建使用create database或create schema命令可以创建数据库。create database 库名create database if not exists 库名(创建库并检验创建的库是否存在&#xff0c;不存在则建&#xff0c;存在就不建了)MySQL不允许两个数据库使用相同的名字&#xff0c;使用ifnot exists从句…

python 少儿趣味编程下载_PYTHON少儿趣味编程

章认识Python11.1编程语言和Python11.1.1程序设计和编程语言11.1.2Python简介21.2Python的安装41.2.1Windows下的Python安装41.2.2MAC下的Python安装81.3个程序HelloWorld111.4开发工具IDLE121.4.1IDLE简介121.4.2用IDLE编写程序121.4.3IDLE的其他功能161.5小结18第2章变量、数…

rs485数据线接反_终于有人把RS485通讯的正确接线方式讲明白了,网友:这下好办了...

RS485是一个定义平衡数字多点系统中的驱动器和接收器的电气特性的标准,该标准由电信行业协会和电子工业联盟定义。使用该标准的数字通信网络能在远距离条件下以及电子噪声大的环境下有效传输信号。RS485使得廉价本地网络以及多支路通信链路的配置成为可能。那么RS485通讯的正确…

骑马与砍杀python代码_GitHub - yunwei1237/scottish-fold: 一个关于骑马与砍杀的剧本制作工具...

scottish-fold一个关于骑马与砍杀的剧本简单快速的制作工具前言​在很久以前的时候&#xff0c;也就是刚开始玩骑砍的时候就想着能够制作一个自己的剧本&#xff0c;用于书写自己想要的故事。当我怀着远大的梦想去这么做的时候才发现&#xff0c;原来制作剧本没有自己想象的那么…

java tomcat 监控_java程序监控tomcat实现项目宕机自动重启并发送邮件提醒

最近由于老项目频繁挂掉&#xff0c;由于项目经过多批人之手&#xff0c;短时间难以定位问题&#xff0c;所以只好写一个监控程序。 时间比较紧半天时间&#xff0c;而且水平有限大神勿喷&#xff0c;有好的方法还请赐教。 1、问题描述&#xff1a;分两种情况1.1、tomcat 彻底挂…