【优质技术文章推荐】TiDB for PostgreSQL—牛刀小试

【是否原创】是
【首发渠道】TiDB 社区
【首发渠道链接】
【目录】
一、诞生背景
二、开发目的
三、开发进度
四、预期功能
五、结语
【正文】

  作为数据库领域国际顶级开源项目,TiDB 以其分布式高可用、高度弹性扩缩容、高性能并行集群处理能力等特性获得越来越多客户的使用,其中不仅仅有互联网、游戏领域的企业,还有金融、大型企业等。因为 TiDB 高度兼容 MySQL 协议,使这些企业原本基于 MySQL 数据库构建的上层业务系统能够以较低的代价快速迁移到TiDB上。TiDB for PostgreSQL 是我们基于 TiDB 源码修改的一款满足 PostgreSQL 协议的数据库。我们的理念就是为了让基于 PostgreSQL 的系统能够在不修改本身业务代码的前提下,快速的迁移到分布式数据库上。

一、 诞生背景

  2020年的疫情对中国整个社会都产生了巨大的影响,尤其是在疫情的暴风眼城市–武汉,而神州数码武汉云基地就在这座城市。当时我们参与的疫情相关的项目中,有些历史业务系统基于PostgreSQL搭建的,在数据量和并发量激增的情况下,增加了数据库运维的难度,于是我们开始着手向可扩展、高可用的分布式数据库迁移。

  PostgreSQL依靠加利福尼亚大学的支持,拥有许多数据库前沿实验性功能,其学术性之强、功能面之广使其收到许多企业和工程师的青睐。PostgreSQL的协议更接近大型企业常用的Oracle数据库,因此在企业中的应用广泛。它的多表关联、多列关联的语法特性是许多应用系统正常运行所必须依赖的。当我们迁移到TiDB遇到种种问题时,我们萌生了一个想法——基于TiDB源码修改以兼容PostgreSQL协议。

  神州数码在2017年开始接触TiDB,不仅在企业内部宣传分布式数据库的概念以及前景,而且更加注重TiDB的实施与实践,想让更多公司的内部系统用上TiDB,享受分布式数据库带来的便利。TiDB 拥有分布式处理和存储数据特性、无限扩容和高并发并行处理等一系列优点。在实践过程中,TiDB确实没有让我们失望,尤其是在高可用上,虽然发生过因为硬件导致的单一节点故障问题,但是整个集群从未下线,业务未受影响。另外TiDB也是中国数据库领域开源的先锋, 我们不断学习TiDB、TiKV、PD的源码,甚至用Golang对TiKV进行部分功能模拟重写,虽然只模拟了 1% 的主要功能,但我们对 TiDB 的优缺点有了更为深刻和细致的理解。

  针对 TiDB目前只支持MySQL协议这个问题,在2021年1月,我们开始进行深入的调研工作,对比了MySQL 与 PostgreSQL 两种数据库协议的差异。在参考二者官方文档的同时,也进行频繁的抓包来分析二者通信报文的区别。在这个过程中,我们总结经验,将二者协议上的区别组织成文章分享到知乎等平台,感兴趣的小伙伴可以通过链接( https://zhuanlan.zhihu.com/p/366275680 ) 查看这篇文章。

  MySQL 与 PostgreSQL 都是市面上非常流行的数据库产品。根据数据库排行网站 DB-Engines(https://db-engines.com/en/ranking) 最新数据库流行程度排行榜(如下图),我们可以看到,在开源数据库领域,PostgreSQL 流行程度紧跟在 MySQL 身后。
image

  随着信息时代信息量爆炸式增长,数据库逐渐成为限制系统性能的最大瓶颈。对于数据库扩容的解决方案,常规的都是分库分表。PostgreSQL 对于分库分表也有插件可以支持,但是存在诸多问题,例如自行维护主库和各个从库之间的数据同步、备份与容灾具有较高的运维技术门槛以及较大的成本支出等等,这些也是分布式数据库想要解决的问题。目前TiDB支持MySQL协议,在PG协议上我们暂时还没找到解决方案。而在我们公司内部许多历史系统,都是以PostgreSQL作为数据库来运行。如今想要用分布式数据库进行优化,虽然市面上有一些基于PostgreSQL的分布式数据库,例如YugabyteDB或是 CockroachDB,但经过实际测试,这些数据库很难完全兼容基于PostgreSQL的业务系统。针对基于PostgreSQL数据库的系统迁移到分布式数据库的难题,我们想到在TiDB源码的基础上进行重构,使其兼容PostgreSQL,为一些想要迁移到分布式数据库的系统提供便捷,增加TiDB的覆盖范围,所以有了 TiDB for PostgreSQL 的尝试。

  为了更深入的了解TiDB for PostgreSQL的工作,我们特意拜访了武汉大学PostgreSQL数据库专家——彭煜玮教授,多次共同讨论TiDB支持PostgreSQL协议的改造方案及可行性,这里也感谢彭老师给我们提供的建议。在他的帮助下,我们从PostgreSQL和TiDB两个数据库中同时下手,正式开始了TiDB for PostgreSQL的研发。

二、 开发目的

  重构 TiDB 源码,使其兼容原本并不支持的 PostgreSQL 协议,让基于 PostgreSQL 的系统也能顺利迁移到分布式数据库上,这是我们一直在努力尝试的事情。在数据库方面,老系统迁移往往会遇到这样一些问题,比如不同数据库语法和功能上有较大区别,而老业务系统刚好使用了该语法特性;再比如 PostgreSQL 的 Inherit 语法、Returning句式等都是MySQL所不支持的。而 TiDB 高度兼容MySQL协议,因此一些基于 PostgreSQL 数据库构建的业务系统在迁移到 TiDB 的时候将可能遇到语法或者是功能不兼容的问题。此时如果必须上TiDB ,那么将不得不面临庞大的代码修改量以及功能测试的工作量。这些工作需要耗费大量的资源,过程缓慢且需要考虑的细节繁多,不利于客户迁移到 TiDB 上。而开发 TiDB for PostgreSQL 就是为了弥补TiDB在 PostgreSQL 系统领域的空白,通过兼容PostgreSQL协议,实现其特有语法和功能,满足业务系统的需求,减轻系统迁移的代价。

  对于神州数码内部系统的技术规划,在未来我们希望通过云原生的理念,基于容器技术去构建上层应用服务,下层基于一个可以支持各种SQL协议的分布式数据库。在这个统一的分布式数据库平台上,结合低代码开发平台,整个架构应该可以解决80%的企业业务系统需求,给各业务部门提供统一的数据库PaaS平台和应用系统SaaS平台。

三、 开发进度

  TiDB for PostgreSQL 基于 TiDB 源码改造以兼容 PostgreSQL 主要有两个方面的工作。

  一方面,我们在 TiDB 中实现了基本的 PostgreSQL 通信协议。 常见的PostgreSQL客户端能够连接到 TiDB for PostgreSQL。例如psql、PgAdmin、还有Navicat,都可以连接到TiDB for PostgreSQL。这个过程中除了实现基本通信协议外,还需要兼容部分系统表和系统函数。

  Psql 连接:
image
Navicat 连接:
image

   另外一方面,兼容 PostgreSQL 特有语法。 PostgreSQL 是一个学术性非常强的开源数据库,其许多功能和语法都是 MySQL 等数据库没有的,因此这一方面的工作就十分庞大且艰巨。要在 TiDB 源码基础上实现新的语法支持要修改的模块甚多,涉及的数据库底层理论知识深度非一般人所想。就以目前我们团队对 RETURNING 子句的实现来说,其修改的模块就包括 Parser SQL解析模块、计划构建、计划优化、执行计划等模块。这一方面的工作我们暂时没有太大进展,需要在开源之后通过社区的力量来完成。

  下图是TiDB for PostgreSQL执行RETURNING句式的示例:
image

  早期在内部系统从PostgreSQL迁移到TiDB上来时,第一个方案是业务系统改造,进行了初步成本和工时预估,整个系统的迁移需要修改的PostgreSQL特性超过11种,SQL语句接近600多条,修改的同时还需要不断测试,保证系统的正常运行,整个过程的成本和耗时都是非常高的。并且这仅仅只是一个系统,那么每一个系统在迁移时可能都需要进行重复的劳动,于是我们想要一个更好的方案,那就是TiDB for PostgreSQL。

  进行改造时,为验证改造TiDB的可行性和实现难度,我们选择现在使用较多且语法更为简单的Sysbench。跑通Sysbench中PostgreSQL协议测试就成为了我们的首要目标。Sysbench在脚本中主要使用扩展查询协议,由于PostgreSQL与MySQL协议有较大的区别,在具体实现上需要增加额外的通信步骤。MySQL的预处理查询报文分两个阶段。第一个是Parse 阶段,负责解析SQL,构造计划。第二个是Execute阶段,负责执行计划,数据写回。PostgreSQL与其功能类似的叫做扩展查询,这个过程中可能存在五次报文通信, Parse(解析SQL)、Bind(绑定参数)、Description(参数描述)、Execute(执行)、Sync(同步)。

  我们花费一段时间对TiDB进行改造后成功实现了TiDB for PostgreSQL的扩展查询功能。于是部署集群,分别对相同硬件资源部署的TiDB for MySQL和TiDB for PostgreSQL进行Sysbench性能测试。Sysbench所有自带测试脚本都能够在其上面跑通。下图是部分脚本的性能对比测试结果。蓝色柱体代表TiDB for PostgreSQL,绿色代表TiDB for MySQL。(此测试仅用于对比同样环境下两者的性能差距,并不代表两者的最优性能)

image

  横坐标代表延时情况,可以发现在多数情况下,比如删除、点查这些脚本测试时,二者性能相差不大。而少部分测试,比如插入、索引更新这些还存在一定的性能差距,这也是在意料之中的情况。大部分脚本测试性能差距不大,这说明不同的协议造成的性能影响较小。部分差距较大的情况可能是修改后的逻辑存在瑕疵导致性能消耗较大,也有可能是偶然的实验误差。这些问题都可以在后续的开发测试中进行修复和完善。

  此外,PostgreSQL还有许多地方是需要我们去实现的,例如PostgreSQL系统库、系统表、Schema结构、各种语法特性支持、部署运维的生态工具等等,每一个都是非常困难的。

  目前,我们内部正在整理相关文档并开源,准备与大家分享更详细的内容。

四、 预期功能

  目前我们修改了接近5000行TiDB源码,基本实现了以下功能:

  • 基本协议(普通查询和扩展查询)
  • 部分错误信息的兼容
  • 用户登录认证(MD5加密)
  • 部分系统表和系统函数

  但这仅仅只是TiDB for PostgreSQL中的一小部分,我们仍然有以下的功能需要努力去实现:

  • PostgreSQL 关键字和语法
  • PostgreSQL 数据库结构
  • PostgreSQL 系统表和系统函数
  • PostgreSQL 权限管理
  • 部署运维相关的工具

五、 结语

  我们在实现 TiDB for PostgreSQL 的部分预期功能后,基本验证了方向的可行性,但是未来还有很多的工作要做,即使现在有各式各样开源的分布式数据库,但是我们仍然认为TiDB for PostgreSQL是一个非常好的想法。所以在实现基本协议,完成Sysbench测试后,我们也非常希望能有社区的力量一起验证目前的测试结果,一起讨论这个项目方向的技术和需求。拥抱开源,是我们一直在坚持的工作。从2020年底我们就开始融入TiDB生态社区,并为社区提供源源不断的支持。不仅在Github上为TiDB贡献代码,而且在asktug等平台解答相关难题,输出我们对TiDB研发和实施的能力。

  在未来的一个月,我们会不断召集对此感兴趣的同伴们加入进来参加讨论和验证,希望这个方向未来也能成为TIDB的一部分。下面是我们的邮箱以及github链接,感兴趣的同学可以与我们联系,交流自己的想法和建议。

12赞

:call_me_hand::call_me_hand::call_me_hand:

1赞

这个很霸气了 :+1:

2赞

分布式数据库未来可期

2赞

哈哈,感觉还可以用cockroachdb的sql层+tikv来试试

这很开源,so hack

1赞

哇喔,这样是不是可以使用pg的地理位置搜索等特性了?比如查询附近的人

哈哈,这个功能可没有

一起来玩:grin:

是个好思路