Skip to content

polardb support design

jimin edited this page Dec 21, 2023 · 1 revision

Seata AT事务模式适配 PolarDB 数据库 - 方案设计

项目链接:https://www.gitlink.org.cn/glcc/2023/subjects/detail/649

PolarDB生态

PolarDB是由阿里自主研发的云原生数据库,以其高弹性、优越性能、海量存储能力以及安全可靠性而著称。官方文档表示,其在兼容性上可以完全100%支持MySQL和PostgreSQL生态,同时具有高度兼容Oracle语法的特性。

PolarDB涵盖三种引擎类型:PolarDB MySQL版(支持MySQL5.7及以上版本)、PolarDB PostgreSQL版(子版本:支持PG14及以上版本、以及高度兼容Oracle版)和PolarDB的分布式版。

引擎 数据库生态 产品架构 输出形态 应用场景
PolarDB-MySQL版 MySQL Share Storage,计算存储分离 公共云、专有云企业版 MySQL生态下的云原生数据库
PolarDB -PostgreSQL版 PostgreSQL版
Oracle版(高度兼容
Share Storage,计算存储分离 公共云、专有云企业版、DBStack PostgreSQL生态下的云原生数据库
PolarDB-X MySQL Share Nothing,分布式 公共云、专有云企业版、DBStack MySQL生态下的大规模数据、超高并发应用

AT模式支持方案

1. JDBC适配

以下是各版本PolarDB与其相应JDBC的匹配关系:

JDBC PoalrDB版本 备注
com.mysql.cj.jdbc.Driver、com.mysql.jdbc.Driver MySQL版 已测试
org.postgresql.Driver PostgreSQL版(兼容PG14) 已测试
com.aliyun.polardb.Driver (官方驱动) PostgreSQL版(兼容PG14 & 兼容Oracle)
  • 对于原生的MySQL以及PolarDB的JDBC,此前在Seata AT模式下对相应版本的PolarDB进行了测试,暂未发现驱动相关的兼容性问题。
  • 对于官方提供的驱动,com.aliyun.polardb.Driver使用了PostgreSQL 3.0协议,并在开源PostgreSQL的基础上实现了一系列兼容性特性,其中一些特性需要驱动层面的配合实现。而当前DataSourceProxy识别数据库类型的方法是基于druid对jdbcUrl的前缀进行判断,对于像PolarDB这样具备多类型数据库兼容性的云原生数据库,可能会引起误判。因此,需要对待适配的类型进行额外的判断,例如,可以考虑使用以下枚举来做出相应的兼容类型判别。经测试,POSTGRESQL 和 POLARDB 的连接方式在PG14兼容版本中可以被正确识别。
public enum PolarCompMode
{
    POSTGRESQL("postgresql", "jdbc:postgresql:", "PostgreSQL"), 
    POLARDB("polardb", "jdbc:polardb:", "POLARDB Database Compatible with Oracle"), 
    ORACLE_THIN("oracle", "jdbc:oracle:thin:", "Oracle"), 
    ORACLE("oracle", "jdbc:oracle:", "Oracle");

    private final String mode;
    private final String prefix;
    private final String productName;
}

2. 语法兼容性

一些已知的可能影响AT流程的兼容性问题:

  • 在PolarDB中,有一些字段仅为了实现兼容性而提供,始终为NULL或特定值。例如,avg_space, chain_cnt, avg_row_len, sample_size, last_analyzed, buffer_pool等字段在PolarDB中始终为NULL;global_stats始终为YES,user_stats始终为NO。(可能影响默认值、NULL的识别)
  • PolarDB PostgreSQL版(兼容Oracle)的大小写不敏感功能。由于Oracle和PolarDB PostgreSQL版(兼容Oracle)对于数据库对象名称的大小写处理方式不同,可能会出现大小写行为不一致的问题。例如,在不加双引号的情况下,Oracle将对象名转为大写存储,PolarDB PostgreSQL版(兼容Oracle)将对象名转为小写存储。(可能影响EscapeHandler的关键字替换功能)
  • 在处理空值的数据筛选时,PolarDB PostgreSQL版(兼容Oracle)需要安装LNNVL函数,这是一个插件形式的函数,需要完成安装后才能使用。
  • 已知的关键字差异。
  • ...

3. 基础模型

如下图所示,借助于Seata在sqlparser、rm-datasource等模块上的扩展性,PolarDB在AT模式适配中的主要工作主要包括以下几个部分的扩展和修改:rm-datasource模块的数据类型判别,sqlparser模块的SQL语法兼容性扩展,rm-datasource模块的执行器扩展,以及rm-datasource模块的元数据缓存Key识别和undo log生成的扩展。

img

适配PolarDB-X 2.0

1. 不同版本PolarDB-X的差异

PolarDB-X 1.0 PolarDB-X 2.0
概述 本质上是DRDS,类似于ShardingSphere Proxy模式,作为proxy层,后端由计算层实例与存储层私有定制RDS实例组成,通过挂载多个MySQL进行分库分表水平拆分,对应到MySQL的partition上。 集成式适配Oracle和PG,在源数据层做了更多的适配,通过源数据可以看到分库键、分表键,以及额外的schema等信息。
架构差异 PolarDB-X 1.0的架构中,大量功能依赖外围管控系统完成,例如:扩容,使用内部的精卫组件来进行。元数据,一个地域内会共享一个Diamond存储。主备探活、切换,依赖ADHA组件。 PolarDB-X中,核心功能全部内聚到内核:X-DB作为其DN(数据节点)。GMS(Global Meta Service)节点支持以下功能:提供分布式事务所使用的全局自增的时间戳。根据负载情况,调度数据的分布,使节点之间达到均衡。提供统一的元数据,例如INFORMATION_SCHEMA。对CN(计算节点)与DN进行管理,例如切换、上线、下线等。PolarDB-X的扩容基于分布式事务,由内核完成。
事务模型 使用的是MySQL官方提供的XA事务。XA事务可以保证写入操作的原子性。 使用自研的全局MVCC事务,在两阶段提交(2PC)的基础上,增加了对事务快照时间戳(snapshot_ts)和提交时间戳(commit_ts)的支持。

2. PolarDB-X 2.0 的MySQL生态兼容

  • MySQL协议

PolarDB-X通讯协议兼容MySQL协议,可以使用常见的驱动直接连接到PolarDB-X实例,包括JDBC Driver、ODBC Driver、Golang Driver等,并且兼容MySQL SSL、Prepare、Load等传输协议。

  • SQL兼容性

PolarDB-X兼容MySQL的各种DML、DAL、DDL语法,其中包括:

  • 兼容绝大部分MySQL函数(包括JSON函数、加密解密函数等)。
  • 兼容MySQL 8.0的视图、CTE、窗口函数、分析函数等。
  • 支持MySQL的各种数据类型,包括类型精度的支持(比如时间戳、Decimal类型)。
  • 兼容常见的MySQL字符串Charset及Collation。
  • 兼容绝大部分information_schema视图。

AT模式重构

TODO:

  • 目前在 execsql-parser 模块中存在结构设计问题,需要在后续迭代过程中遵循单一职责原则,将可以共用的最小化方法提取到各个类的基类(BaseXXX)中,以降低耦合度并增加可扩展性。
  • 特别地,对于SQL解析器(SQL Parser),尽管SQL对象的类型和结构相对稳定,但经常需要对一个SQL结构中的对象执行不同且无关的操作。为了避免这些操作对“识别器”类(Recognizer Classes)造成影响,同时也不希望在添加新操作时修改这些类,可以考虑采用访问者模式。例如,在原有实现中,各不同数据库类型的 SQLInsertRecognizer 中的 getInsertParamsValue 方法都采用分支检测 VALUES 子句的类型,这导致了不同数据库实现之间的微小差异只能通过增加或删除某些 if-else 分支来处理,这样会导致较高程度的耦合。由于不同类型对于某一类型的表达式(expr)的操作本质上是一致的,因此可以将类型识别抽象成“访问”,然后由各自的数据库类型来适配,同时将 getInsertParamsValue 的行为定义为一个模板。

参考

Clone this wiki locally