-
Notifications
You must be signed in to change notification settings - Fork 8.8k
polardb support design
jimin edited this page Dec 21, 2023
·
1 revision
项目链接:https://www.gitlink.org.cn/glcc/2023/subjects/detail/649
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生态下的大规模数据、超高并发应用 |
以下是各版本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;
}
一些已知的可能影响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函数,这是一个插件形式的函数,需要完成安装后才能使用。
- 已知的关键字差异。
- ...
如下图所示,借助于Seata在sqlparser、rm-datasource等模块上的扩展性,PolarDB在AT模式适配中的主要工作主要包括以下几个部分的扩展和修改:rm-datasource模块的数据类型判别,sqlparser模块的SQL语法兼容性扩展,rm-datasource模块的执行器扩展,以及rm-datasource模块的元数据缓存Key识别和undo log生成的扩展。
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)的支持。 |
- 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视图。
TODO:
- 目前在 exec 和 sql-parser 模块中存在结构设计问题,需要在后续迭代过程中遵循单一职责原则,将可以共用的最小化方法提取到各个类的基类(BaseXXX)中,以降低耦合度并增加可扩展性。
- 特别地,对于SQL解析器(SQL Parser),尽管SQL对象的类型和结构相对稳定,但经常需要对一个SQL结构中的对象执行不同且无关的操作。为了避免这些操作对“识别器”类(Recognizer Classes)造成影响,同时也不希望在添加新操作时修改这些类,可以考虑采用访问者模式。例如,在原有实现中,各不同数据库类型的 SQLInsertRecognizer 中的
getInsertParamsValue
方法都采用分支检测 VALUES 子句的类型,这导致了不同数据库实现之间的微小差异只能通过增加或删除某些 if-else 分支来处理,这样会导致较高程度的耦合。由于不同类型对于某一类型的表达式(expr)的操作本质上是一致的,因此可以将类型识别抽象成“访问”,然后由各自的数据库类型来适配,同时将getInsertParamsValue
的行为定义为一个模板。