2.0解析系列 | OceanBase 2.0——第一款支持“存储过程”的原生分布式数据库

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: OB君:本文是 “OceanBase 2.0 技术解析系列” 的第八篇文章,今天我们来说说2.0版本最标志性、最不得不提的新特性——存储过程。在为数不多的原生分布式数据库中,OceanBase 2.0是第一款支持存储过程功能的产品。

OB君:本文是 “OceanBase 2.0 技术解析系列” 的第八篇文章,今天我们来说说2.0版本最标志性、最不得不提的新特性——存储过程。在为数不多的原生分布式数据库中,OceanBase 2.0是第一款支持存储过程功能的产品。本文将为你深入剖析2.0中存储过程的功能特性和实现机制。更多精彩欢迎关注OceanBase公众号持续订阅本系列内容!

引言

PL/SQL(存储过程)是一种程序语言,叫做过程化SQL语言(Procedural Language/SQL),从Ada语言发展而来。PL/SQL是关系数据库对SQL语句的扩展,在普通SQL语句的基础上增加了编程语言的特点,把数据操作和查询语句组织在PL/SQL的过程化代码中,通过逻辑判断、循环等操作实现复杂的功能。

使用PL/SQL可以编写具有很多高级功能的程序,能够把业务逻辑封装在数据库内部,提供更好的抽象和安全性,同时减少了网络的交互,并且调用更快,从而提升整体性能。

目前无论是商业数据库还是开源产品几乎都在一定程度上支持类似PL的功能,但是采用的规范标准不尽相同。使用最广泛的是Oracle的PL/SQL,最早在1989年发布,语法基于Ada语言。

除此之外还有SQL Server的T-SQL,PostgreSQL的PL/pgSQL等。SQL标准中的SQL/PSM(SQL/Persistent Stored Modules)定义了存储过程中使用的PL,但是Oracle的PL/SQL已经成为了事实上的规范。MySQL采用的是SQL/PSM标准,但是并非100%兼容。OceanBase 2.0当前的PL以兼容MySQL为主体,MySQL没有的功能参照Oracle实现。

MySQL和PostgreSQL的PL都采用解释执行方式,从实现角度来说,解释执行比编译执行更容易实现,也更易于控制。但是理所当然的,解释执行比编译执行性能相对较差。

Oracle 9.x之前的PL也是解释执行(Interpreted Compilation)的,从9.x开始,Oracle提供了编译执行(Native Compilation),SQL/PL首先被翻译为C语言代码,然后调用C编译器编译为机器码,编译后的程序存在动态链接库中,运行时执行器直接装载调用动态链接库中编译好的函数。

根据Oracle自己的说明,编译后的程序比解释执行性能提升1.05到2.4倍。具体提升的程度取决于程序的特性。因为SQL语句本身还是解释执行的,所以如果PL的主体是程序控制逻辑,那么提升效果会很明显,而如果PL的主体是SQL语句,那么PL的性能提升不会显著。另外Oracle的PL调试功能只支持解释执行方式。

编译执行是一个趋势,目前除了PL之外,很多数据库也纷纷在尝试把SQL引擎改写为编译执行,包括MemSQL、HANA、PostgreSQL等。OceanBase PL采用编译执行的方式,使用LLVM生成native code,并直接把机器码装载到程序段执行,无需依赖外部C编译器和生成动态链接库。

无论解释执行还是编译执行,当前的商业数据库都只支持单机,OceanBase在分布式环境下在关系数据库里支持了完整的PL/SQL功能,这在业界尚属首次。

价值和意义

1. 降低RT

PL对于业务最直接的价值就是降低业务的RT。假如某个业务逻辑里面一条完整的执行链路平均有200条SQL,也就是应用需要和数据库交互200次。在同机房的情况下网络开销大约需要0.5ms,如果把200次交互省掉,那么就可以节约100ms的RT。当然,事实上因为业务有自身的逻辑,不可能全部逻辑都可以用PL/SQL来实现,所以这200次交互不可能全部省掉,但是即便省下一半,也会有大约50ms的RT提升。

2. 节省资源

减少网络交互除了减少RT,另一个直接的效果是减少了网络的数据传输和网络开销。假如某个互联网业务的网络开销平均是30%,也就是说30%的CPU都花在了网络的收发和解析上。如果说几十个ms的RT对整个链路来说比例不那么显著的话,30%的CPU资源节省缩省下的机器可是以亿计的真金白银,而把这些机器资源换算成系统处理能力也将是惊人的。

3. 提高吞吐率

事实上利用PL/SQL带来的网络开销的节省只是表面,更深层次的是,因为每个事务的RT缩短,每个事务在数据库内核所抢占临界区的时间缩短,使得系统的CPU利用率获得大幅提升,整个吞吐量也随之提高。这种提升不止在数据库内核存在,对业务的应用逻辑同样有帮助。CPU利用率的提升所获得价值同样也是亿级规模的。

4. 提升稳定性和可靠性

当前的互联网分布式业务多是单元化部署,应用和数据库部署在同机房,并且在大多数情况下都是机房内访问,一旦发生故障导致某个数据库的数据不可访问,OceanBase会自动切换访问其他副本,与此同时应用也必须随之切走,否则同机房的数据库访问将变成跨机房甚至跨城访问,网络开销也将由原来的每次0.5ms变成2ms,甚至达到7ms~30ms。对于单次来说这不算什么,但是在几百条SQL的加成下就可观了。

巨大的网络延迟会对整个业务系统造成严重影响,甚至拖垮整个系统。而利用了PL/SQL之后,这些问题都将不复存在,业务将不再和数据库强绑定,计算和计算的分离成为可能,整个系统的可靠性获得提升。

同时,OceanBase的设计对于网络要求相对比较高,集群内部通信以及内部流程逻辑也都可以利用PL/SQL实现,这不仅提升能够内部通信的效率,同时也使得数据库内核的核心代码充分简化,减少出错路径,提升稳定性。

并且部分业务逻辑改为PL后,业务的代码将会减少,业务开发流程也会相对简化,同时提供更好的抽象和安全性。

实现机制

1. 框架结构

图1给出了OceanBase PL Engine工作的调用关系图。PL引擎(PL Engine)和SQL引擎(SQL Engine)可以互相交互,SQL可以直接访问PL引擎,比如在一个SQL语句中使用了用户自定义函数。PL引擎可以通过SPI接口访问SQL引擎,比如在PL里进行表达式计算和执行SQL语句。

2_0_8_1

图1:PL Engine工作调用关系

2.PL Engine

PL Engine由六个模块组成:Parser、Resolver、Code Generator、Compiler、Executor和PL Cache,其中Parser、Resolver、Code Generator和Compiler构成了一个完整的PL编译流程。如图2所示。

  • Parser
    语法解析器,用于分析PL语法生成语法树(ParseTree)。PL引擎和SQL引擎各自实现了单独的Parser,但是两个Parser尽量不做冗余的工作。一个查询串进入Observer首先进入PL Parser解析,如果发现是SQL语句则交由SQL引擎解析。
  • Resolver
    Resolver用于进行语义分析,例如检查变量作用域、静态SQL中数据对象的Schema等,并为每一条PL语句生成对应的AST结构以及全局的FunctionAST结构。FunctionAST存储了PL定义的基本信息和生成的全局符号表、全局标签表、全局异常表等信息。每一条语句的AST里面则记录了指向这些全局表的逻辑信息。
  • Code Generator
    对于解释执行来说,AST已经足够。但是对于编译执行,需要对AST进行进一步的翻译,这一步是使用LLVM提供的接口,把AST树翻译成IR中间码的过程。IR码可以输出,以核对检验翻译过程是否正确。
  • Compiler
    通过JIT把IR码生成机器码的过程,输出为PLFunction结构。
  • Executor
    PL的执行器,根据编译出的PLFunction,和输入参数构造执行环境,调用函数指针,得到函数结果。
  • PL Cache
    PL Cache存在的目的是为了避免每一次都重新编译PL,提升PL的执行效率。所以对于匿名块(Anonymous Block)没有Cache的必要。

PL Cache是一个hash表,通过Key(Procedure或Function的ID)查找到Value(PLFunction),并通过访问Schema检查PLFunction的有效性,如果失效则趁机删除。

PL Cache是PL Engine的内部机制,PL Engine对外提供统一的通过ID执行Procedure或Function的接口,外部不必关心PL的缓存机制,只需通过PL Engine对象执行PL即可。

2_0_8_2

图2:PL Engine模块组成

PL Engine根据ID在PL Cache查找是否有编译好的PLFunction,如果有则进一步检查Version是否可用。如果PL Cache中没有可用的PLFunction,则调用编译流程进行编译,编译后的结果缓存在PL Cache,并交给Executor执行。

最终编译出的结果是一段二进制代码的内存地址,Executor将这段内存地址转成一个函数指针,并传入执行参数和执行环境运行得到结果。

3.编译执行

编译执行比解释执行的优势毋庸赘言,OceanBase 也是采用把存储过程编译为机器码的方式进行执行,但是和Oracle实现不同的是,OceanBase采用JIT技术,无需依赖外部C编译器和生成动态链接库。采用这一技术方案,有如下优点:

  1. 无需研究体系结构相关的复杂的机器码生成,就可以获得编译执行的效果;生成LLVM IR比生成汇编简单很多,且自然拥有了考虑跨平台能力;
  2. LLVM提供的成熟的优化模块都是基于LLVM IR的,clang等项目中对优化器的改进都可以直接被我们受益;
  3. 用JIT技术在Observer内直接控制生成编译后的代码,比Oracle采用的在数据库外部编译器编译结合动态链接库装载的方式在可控性,性能,可维护性各方面都有优势;
  4. PL的编译执行可以和SQL表达式及部分physical operator甚至是整个查询计划采用编译执行相结合,获取整体性能的提升。

图3给出了PL 编译的工作流程。Parser、Resolver和Code Generator三个模块完成了编译器的前端(Frontend)工作,实现从PL文本到中间码(LLVM IR)的转换过程。Compiler模块完成了Pass和后端(Backend)的工作,把中间码经过Pass流程优化,并生成实际的机器码。

2_0_8_3

图3:PL编译工作流程

这种架构下,对于实现PL/SQL语言来说,大量的工作是实现一个前端,即Parser、Resolver和Code Generator三个模块,而对于Compiler可以调用LLVM提供的接口实现。

兼容性

各大数据库支持的PL都各有不同。目前最广泛使用的Oracle PL/SQL语言最早在1989年发布,语法基于Ada语言。PostgreSQL的PL/pgSQL,SQL Server的T-SQL等语言都各不相同。SQL标准中的SQL/PSM (SQL/Persistent Stored Modules)定义了存储过程中使用的PL,但遗憾的是主流数据库厂商并没有全心支持。

像PL/pgSQL一样,MySQL采用了SQL/PSM标准,但是并非100%兼容。OceanBase 提供MySQL和Oracle两种兼容模式,PL/SQL也同样既可以使用Mysql的用法,也可以选择Oracle兼容模式,基于Mysql或者Oracle的PL的代码可以一行不改的迁移到OceanBase运行。

分布式

OceanBase天然的分布式特性决定PL的执行也是分布式的,PL的解析、编译和执行都在某一个Observer上完成,当PL里涉及到SQL交互时,会通过SPI调用SQL Engine,由SQL Engine执行SQL语句,如果该SQL语句是一个分布式的,那么自然而然会进行分布式执行。

OceanBase选择存储过程里访问的第一张表的数据所在的节点编译和执行PL,这是为了尽量使得PL对数据的访问都是LOCAL的。如果无法确定所访问数据所在的节点,则随机选取一个节点。

当分布式执行的SQL调用了PL函数时,PL函数可能会在多个Observer上编译执行,每个Observer上保证在相同的环境参数下进行编译,从而编译出的PL具有相同的行为。

调试

调试是编程语言的基本需求,所以事实上Mysql这样不支持调试的PL/SQL是不具备大规模应用的基础的。

业界实现PL的调试功能都只在解释执行模式支持,Oracle的编译执行模式不支持调试。OceanBase只有一种编译执行模式,支持在编译模式进行调试,并且是在分布式的环境下进行调试。目前支持的调试功能包括设置断点(b)、查看断点(info b)、查看变量(p)、查看堆栈(bt)、单步运行(s)、进入函数(s)、继续(c)等等,通讯方式采用类似Oracle的方式,建立一个数据库连接来调试另一个连接,调试指令用文本指令,不发明新的通讯协议,并通过包的形式对外提供接口。

分布式调试是分布式环境下实现PL/SQL的难点,当PL分布式执行时,用户的调试线程连到其中一个节点,该节点需要再和其他分布式执行节点建立调试连接并传输指令和数据。

Mysql没有包(Package),OceanBase提供和Oracle完全兼容的包机制,用户在Oracle上创建的包可以一行不改的迁移到OceanBase上创建和运行。

但是Oracle的系统包目前OceanBase还没有全部支持,这也将成为今后一段时间我们要做的工作之一。在有了PL/SQL的基础能力支持和Package的机制之后,其余的系统包可以根据需要快速实现。

总结和展望

从OceanBase诞生的第一天起,团队的目标就不是想做一个数据库只给自己用,而是要做一个通用数据库真的去推动整个社会的进步,能够让整个社会的生产力发生变化。

随着蚂蚁金服的开放赋能,OceanBase也开始服务外部客户,金融行业的很多客户以前都有很大一部分业务是使用Oracle开发,并且大量使用了PL/SQL,这种现状在非金融行业中更为普遍,而这也成为了Oracle绑在客户身上最重要的一条锁链。OceanBase要为客户提供比Oracle更可靠、更高性价比的服务,PL/SQL是必须迈过去的一道门槛。这道门槛很难迈,而一旦迈过去,就会形成OceanBase的重要优势。

另一方面,虽然互联网公司目前的现状是普遍都不使用PL/SQL进行业务开发,但是难掩其对业务的巨大价值,PL不仅能够降低RT,提高资源利用率,提升系统吞吐率、稳定性和可靠性,同时也是服务用户,尤其是传统行业客户的重要基础。在这一方面蚂蚁金服走在互联网行业前列,已经开始在内部尝试利用PL/SQL的优势来解决业务的问题。

OceanBase提供了同时兼容Mysql和Oracle两种模式的PL/SQL,并利用LLVM实现其编译执行的内核引擎,使得PL控制逻辑本身性能能够达到Oracle相当的水平。而且OceanBase是业界第一个真正意义上支持分布式PL的商业产品,并提供完善和兼容的调试机制。与此同时OceanBase还提供了完备的包机制。

未来除了进一步完善Oracle兼容的系统包之外,还需要继续优化PL/SQL的性能。与此同时,我们也会在更多内部业务中推广使用PL/SQL,为业务创造巨大的价值,并在提供给外部客户使用之前做好技术沉淀和产品锤炼。

加入OceanBase 2.0技术交流群

— 想了解更多OceanBase 2.0新特性?

— 想与蚂蚁金服OceanBase的一线技术专家深入交流?

扫描下方二维码联系小编,快速加入OceanBase技术交流群!

_

相关文章
|
1月前
|
存储 JSON 数据库
Elasticsearch 分布式架构解析
【9月更文第2天】Elasticsearch 是一个分布式的搜索和分析引擎,以其高可扩展性和实时性著称。它基于 Lucene 开发,但提供了更高级别的抽象,使得开发者能够轻松地构建复杂的搜索应用。本文将深入探讨 Elasticsearch 的分布式存储和检索机制,解释其背后的原理及其优势。
116 5
|
2月前
|
存储 容灾 关系型数据库
OceanBase 高可用性架构解析
【8月更文第31天】在大数据和云计算蓬勃发展的今天,数据库作为数据存储的核心组件,其稳定性和可靠性直接影响到整个系统的性能。OceanBase 是由阿里巴巴集团自主研发的一款分布式关系型数据库系统,旨在为大规模在线交易处理(OLTP)场景提供高性能、高可用性的解决方案。本文将深入探讨 OceanBase 是如何通过其独特的架构设计来确保数据的高可用性和容灾能力。
148 0
|
2天前
|
关系型数据库 数据挖掘 数据库
解析数据库联结:应用与实践中的 INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL OUTER JOIN 与 CROSS JOIN
解析数据库联结:应用与实践中的 INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL OUTER JOIN 与 CROSS JOIN
9 1
|
2月前
|
存储 SQL 安全
【数据库高手的秘密武器:深度解析SQL视图与存储过程的魅力——封装复杂逻辑,实现代码高复用性的终极指南】
【8月更文挑战第31天】本文通过具体代码示例介绍 SQL 视图与存储过程的创建及应用优势。视图作为虚拟表,可简化复杂查询并提升代码可维护性;存储过程则预编译 SQL 语句,支持复杂逻辑与事务处理,增强代码复用性和安全性。通过创建视图 `high_earners` 和存储过程 `get_employee_details` 及 `update_salary` 的实例,展示了二者在实际项目中的强大功能。
30 1
|
28天前
|
SQL 关系型数据库 MySQL
MySQL技术安装配置、数据库与表的设计、数据操作解析
MySQL,作为最流行的关系型数据库管理系统之一,在WEB应用领域中占据着举足轻重的地位。本文将从MySQL的基本概念、安装配置、数据库与表的设计、数据操作解析,并通过具体的代码示例展示如何在实际项目中应用MySQL。
68 0
|
2月前
|
C# 开发者 Windows
全面指南:WPF无障碍设计从入门到精通——让每一个用户都能无障碍地享受你的应用,从自动化属性到焦点导航的最佳实践
【8月更文挑战第31天】为了确保Windows Presentation Foundation (WPF) 应用程序对所有用户都具备无障碍性,开发者需关注无障碍设计原则。这不仅是法律要求,更是社会责任,旨在让技术更人性化,惠及包括视障、听障及行动受限等用户群体。
54 0
|
2月前
|
存储 C# 关系型数据库
“云端融合:WPF应用无缝对接Azure与AWS——从Blob存储到RDS数据库,全面解析跨平台云服务集成的最佳实践”
【8月更文挑战第31天】本文探讨了如何将Windows Presentation Foundation(WPF)应用与Microsoft Azure和Amazon Web Services(AWS)两大主流云平台无缝集成。通过具体示例代码展示了如何利用Azure Blob Storage存储非结构化数据、Azure Cosmos DB进行分布式数据库操作;同时介绍了如何借助Amazon S3实现大规模数据存储及通过Amazon RDS简化数据库管理。这不仅提升了WPF应用的可扩展性和可用性,还降低了基础设施成本。
60 0
|
2月前
|
开发者 云计算 数据库
从桌面跃升至云端的华丽转身:深入解析如何运用WinForms与Azure的强大组合,解锁传统应用向现代化分布式系统演变的秘密,实现性能与安全性的双重飞跃——你不可不知的开发新模式
【8月更文挑战第31天】在数字化转型浪潮中,传统桌面应用面临新挑战。本文探讨如何融合Windows Forms(WinForms)与Microsoft Azure,助力应用向云端转型。通过Azure的虚拟机、容器及无服务器计算,可轻松解决性能瓶颈,满足全球用户需求。文中还提供了连接Azure数据库的示例代码,并介绍了集成Azure Storage和Functions的方法。尽管存在安全性、网络延迟及成本等问题,但合理设计架构可有效应对,帮助开发者构建高效可靠的现代应用。
23 0
|
2月前
|
SQL 数据处理 数据库
|
2月前
|
Java 数据库连接 数据库
AI 时代风起云涌,Hibernate 实体映射引领数据库高效之路,最佳实践与陷阱全解析!
【8月更文挑战第31天】Hibernate 是一款强大的 Java 持久化框架,可将 Java 对象映射到关系数据库表中。本文通过代码示例详细介绍了 Hibernate 实体映射的最佳实践,包括合理使用关联映射(如 `@OneToMany` 和 `@ManyToOne`)以及正确处理继承关系(如单表继承)。此外,还探讨了常见陷阱,例如循环依赖可能导致的无限递归问题,并提供了使用 `@JsonIgnore` 等注解来避免此类问题的方法。通过遵循这些最佳实践,可以显著提升开发效率和数据库操作性能。
70 0

推荐镜像

更多