PolarDB-X 分区建列类型变更

本文涉及的产品
云原生数据库 PolarDB 分布式版,标准版 2核8GB
简介: 作为一款分布式数据库,变更表的列类型,无论变更的是否是分区键,都需要保证各个分片以及元数据的一致性,因此对于非分区键的列类型变更也不只是简简单单的下推执行就可以的,后续会有一篇文章做详细的阐述,本文主要阐述的是如何对分区键的列类型做变更。

作者:无沐

背景

纵观数据库领域数十年来的发展,关系型数据库脱颖而出的一个重要原因是,它支持用户灵活地定义和修改“数据模型”。

PolarDB-X 作为一款云原生关系型数据库,同样支持通过各种 DDL 语句对数据模型进行修改,以满足用户业务的不断发展,例如:可以使用 ALTER TABLE 语句对表进行添加列,删除列,修改列类型等操作。然而,PolarDB-X 作为一款分布式数据库,其一张逻辑表通常通过某种分区方式将数据划分成多个分片(又称为物理表),并且这些分片分布在不同的数据节点中[1][2],这使得 DDL 语句的实现会更加复杂。

本文以列类型变更为例,简单介绍在 PolarDB-X 中如何执行 ALTER TABLE 语句。首先,列类型变更分为两种:一种是变更分区键列类型,另一种是变更非分区键列类型。对于非分区键的列类型变更,可以直接将逻辑 DDL 拆分成多个物理 DDL,直接下推到对应分片上执行;对于分区键的列类型变更,则相对复杂,在修改列类型的同时,还需要对数据进行重分布,因为分区键列类型修改会影响到分片的路由,如果只是简单的下推执行,会导致使用分区键进行查询时,查询不到数据。

实际上,作为一款分布式数据库,变更表的列类型,无论变更的是否是分区键,都需要保证各个分片以及元数据的一致性,因此对于非分区键的列类型变更也不只是简简单单的下推执行就可以的,后续会有一篇文章做详细的阐述,本文主要阐述的是如何对分区键的列类型做变更。

传统实现

传统分布式数据库中间件采用分库分表的方式对表进行拆分,通常是不允许对拆分键列类型进行变更,如果想要做变更,一般需要重新建一张表,并且停写之后重新导入数据。

如果想要变更的时候不停写,则需要在导入存量数据的同时,自行维护一套双写的逻辑,这种操作方式不仅复杂,而且很难校验最后数据的正确性,导致很容易出现数据不一致的问题。

实现

前文中介绍了PolarDB-X拆分规则变更的实现原理[3],该变更过程同样需要对数据进行重分。

作为数据重分布的经典案例,拆分规则变更过程需经历建新表、双写、导入存量数据、数据校验、流量切换等步骤,整个流程已经非常成熟。很容易想到的是,变更分区键列类型可以基于该流程修改来完成,下面介绍该功能的详细实现。

数据重分布过程中的增量数据双写、存量数据同步以及如何进行流量切换在文章中已经详细描述了,这里不再赘述,强烈建议没有看过的同学,再看一下这篇文章以及 Online Schema Change 这篇论文[4]。

需要补充的一点是,我们还做了基于 TSO 快照[5]的物理数据校验功能,以保证变更前后数据的正确性。 回到本文主题,分区建列类型变更具体与拆分规则变更有以下几点不同,下面详细阐述。

  • 创建新表
  • 对于全局二级索引(GSI)处理
  • 数据校验

创建新表

对于拆分规则变更而言,该功能只会修改分区规则,并不会修改列定义,因此新建表的表结构与原表完全一致,列定义不会做修改。而分区键列类型变更需要修改分区键的列定义,因此新建表的表结构与原表不完全一致,除了分区键的列定义以外其他定义是一样的。

因为新表的列定义与原表的列定义不一致,所以原有的增量数据双写以及存量数据同步流程都存在类型隐式转换,那需不需要对这两个过程做修改呢?答案是不需要的,这是因为对于分区键而言,在 CN(计算节点)上兼容了 DN(数据节点)的类型隐式转换,能够保证使用隐式转换前的数据和隐式转换后的数据都可以路由到同一个分片中,不需要担心路由问题。

另外,熟悉 MySQL 的同学可能知道在 MySQL 中,ALTER TABLE MODIFY COLUMN 的转换和DML的隐式转换逻辑存在差异,这样可能会导致通过 BINLOG 同步的下游与上游数据不一致,这个问题会在数据校验章节进行解答。

全局二级索引处理

文章中介绍了 PolarDB-X 的全局二级索引[6],全局二级索引为了方便回表查询,默认包含了主表的主键以及分区键作为 Cover 列。

为了保证 GSI 和主表数据的一致性,在变更主表分区键列类型时,所有 GSI 的对应 Cover 列的类型也需要同时做变更,因此变更主表的分区键列类型其实会将GSI表的数据也进行重分布。

如果主表的分区键和 GSI 的分区键不一致,且对 GSI 的分区键列类型做变更,为了保证数据的一致性,还是需要走相同流程。

数据校验

为了保证变更的正确性,在创建新表、开启增量数据双写以及存量数据同步都完成之后,需要穿插一个数据校验步骤,数据校验通过之后,才是流量切换以及原表优雅下线过程。

这里先简单介绍一下数据校验的逻辑,首先我们在DN端实现了一种顺序无关的哈希算法并将其封装称为 UDF,在 CN 开始进行校验时,首先利用 TSO 事务获取到源表和目标表的一致性快照,然后分别对源表和目标表对应的 DN 端每个分片进行全表的 hashcheck计算(并行),并将结果拉取到 CN节点汇总,计算出源表的 checksum 和目标表的 checksum,最后进行比较即可。

同构表(分片间并行):

a1.png

异构表(分片间并行):

a2.jpg

对于分区键列类型变更而言,源表和目标表在列定义上不完全一致,直接进行校验肯定会导致校验失败。例如,源表分区键列类型是 VARCHAR,存在一条数据是'123abc',现将分区键列类型修改为 INT,那么目标表分区键对应的数据则转换成了 123,123和'123abc'的 hashcheck值自然是不一样的,因此校验会失败。为了解决上述问题,在创建新表后,为源表添加了一个仅用于数据校验虚拟列(对外不可见),并且该虚拟列是在分区键列的基础上调用列类型转换函数。例如,在上面的例子中,对源表添加一个虚拟列,那么该虚拟列的值即为'123abc'调用转换函数后的结果123,结果与目标表一致。利用添加虚拟列的方式,即可完成数据校验,并且该虚拟列调用的列类型转换函数与 MySQL 中 ALTER TABLE MODIFY COLUMN 转换的处理逻辑一致,因此还可以校验出 DML 隐式转换与 ALTER TABLE MODIFY COLUMN 转换不一致的情况。


查看DDL执行计划


分区键列类型变更并不是一定需要数据重分布,例如对于字符串列类型来说,如果只是想变长,并不修改字符串的 CHARSET 和 COLLATE,那么其实是不需要进行数据重分布的,执行过程与非分区键列类型变更相似。另外,用户可能刚好修改的是 GSI 的分区键列类型,不是主表的分区键,这样仍然会产生数据重分布。可以看到列类型变更其实存在好几种场景,为了便于用户快速区分列类型变更具体是走的什么流程,我们提供了类似 explian 的操作给 DDL语句来使用,下面以sysbench 表举几个例子进行说明。


建表语句:

a3.jpg

例1,修改非分区键列类型:

a4.jpg

例2,修改分区键列类型,并且需要数据重分布:
其中 CREATE TABLE 为创建新表,DROP TABLE 则为完成校验之后删除旧表,ALTER TABLE 为添加虚拟列用于数据校验。

a5.jpg

例3,修改分区键列类型,无需数据重分布:
首先将分区键id列修改为 varchar(30),该过程需要数据重分布,然后再将其类型修改为 varchar(60),explain 结果如下,可以看到无需数据重分布(不需要建表删表)。

20230718135306.jpg

总结


灵活的对表列类型变更是分布式数据库的重要特性。PolarDB-X 支持了分区键列类型变更的同时,保证了数据的强一致、高可用、对业务透明、去除了分布式带来的限制并且使用起来非常方便。本文在 PolarDB-X 拆分规则变更的基础上,简单阐述了实现分区键列类型变更过程中使用到的各项技术点,PolarDB-X 之所以能够支持该功能,使用到了很多诸如 TSO 事务之类的特性,这也是分布式数据库区别于分布式数据库中间件的重要特性之一。


参考文献


[1] PolarDB-X 数据分布解读(一)
[2] PolarDB-X 数据分布解读(二) :Hash vs Range
[3] PolarDB-X 拆分规则变更
[4] Online, Asynchronous Schema Change in F1
[5] PolarDB-X 分布式事务的实现(一)
[6] PolarDB-X 全局二级索引


本文来源:PolarDB-X知乎号

相关实践学习
跟我学:如何一键安装部署 PolarDB-X
《PolarDB-X 动手实践》系列第一期,体验如何一键安装部署 PolarDB-X。
相关文章
|
6月前
|
关系型数据库 Go PostgreSQL
golang pgx自定义PostgreSQL类型
golang的pgx驱动提供了大约70种PostgreSQL类型支持,但还是有一些类型没有涵盖,本文介绍如何自己编写代码支持特殊的类型。
87 3
|
4天前
|
分布式计算 DataWorks 关系型数据库
DataWorks产品使用合集之在使用 DataWorks 数据集成同步 PostgreSQL 数据库中的 Geometry 类型数据如何解决
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
28 0
|
4天前
|
分布式计算 关系型数据库 大数据
MaxCompute产品使用合集之怎么才可以将 PostgreSQL 中的 geometry 空间类型字段同步到 MaxCompute 或另一个 PostgreSQL 数据库
MaxCompute作为一款全面的大数据处理平台,广泛应用于各类大数据分析、数据挖掘、BI及机器学习场景。掌握其核心功能、熟练操作流程、遵循最佳实践,可以帮助用户高效、安全地管理和利用海量数据。以下是一个关于MaxCompute产品使用的合集,涵盖了其核心功能、应用场景、操作流程以及最佳实践等内容。
|
4天前
|
关系型数据库 MySQL 分布式数据库
PolarDB产品使用合集之PolarDB MySQL标准版中带有分区功能吗
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
|
4天前
|
JSON 关系型数据库 分布式数据库
PolarDB常见问题之PolarDB8.0.1使用冷热混合分区失败如何解决
PolarDB是阿里云推出的下一代关系型数据库,具有高性能、高可用性和弹性伸缩能力,适用于大规模数据处理场景。本汇总囊括了PolarDB使用中用户可能遭遇的一系列常见问题及解答,旨在为数据库管理员和开发者提供全面的问题指导,确保数据库平稳运行和优化使用体验。
|
4天前
|
关系型数据库 Serverless 分布式数据库
PolarDB的Serverless能力与同类型产品的对比
【2月更文挑战第21天】PolarDB的Serverless能力与同类型产品的对比
21 2
|
7月前
|
关系型数据库 数据管理 Go
《PostgreSQL数据分区:原理与实战》
《PostgreSQL数据分区:原理与实战》
128 0
|
5月前
|
关系型数据库 Serverless 分布式数据库
PolarDB的Serverless能力与同类型产品的对比
PolarDB的Serverless能力与同类型产品的对比
125 4
|
7月前
|
JSON Java 关系型数据库
Spring Boot 学习研究笔记(十三) Spring Data JPA与PostgreSQL的jsonb类型集成
Spring Boot 学习研究笔记(十三) Spring Data JPA与PostgreSQL的jsonb类型集成
101 0
|
10月前
|
SQL 存储 分布式数据库
实践教程之PolarDB-X分区管理
PolarDB-X 为了方便用户体验,提供了免费的实验环境,您可以在实验环境里体验 PolarDB-X 的安装部署和各种内核特性。除了免费的实验,PolarDB-X 也提供免费的视频课程,手把手教你玩转 PolarDB-X 分布式数据库。本期实验将指导您如何进行PolarDB-X分区管理。

热门文章

最新文章

相关产品

  • 云原生分布式数据库 PolarDB-X
  • http://www.vxiaotou.com