我们使用机器学习技术将英文博客翻译为简体中文。您可以点击导航栏中的“中文(简体)”切换到英文版本。
在适用于 PostgreSQL 的亚马逊 RDS 和亚马逊 Aurora PostgreSQL 中使用原生命令对现有表进行分区
客户使用
对表进行分区可以在很多方面提供帮助,例如使用
在这篇文章中,我将向您展示如何使用 PostgreSQL 原生 SQL 命令将现有的非分区表转换为分区表。此方法适用于适用于 PostgreSQL 的亚马逊 RDS、Aurora PostgreSQL 和自行管理的 PostgreSQL。
概述
要对现有的大表进行分区,我们使用以下高级步骤:
- 在现有表上创建并验证检查约束。
- 重命名现有表及其相应的索引,并使用原始表的名称创建一个新的分区表。
- 将旧表附加为新创建的分区表的分区。
- 删除检查约束。
- 将数据从作为分区附加的旧表移到新表中的多个较小分区。
先决条件
在本演练中,您应该具备以下先决条件:
-
一个
亚马逊云科技 账户 。 -
适用于 PostgreSQL 的亚马逊 RDS(版本 13.8)数据库实例或 Aurora PostgreSQL(版本 13.8)集群 — 创建 RDS for PostgreSQL 数据库实例或创建 Aurora PostgreSQL 集群。 -
亚马逊 Simple Storage Servic e (Amazon S3) 存储桶。 - 了解 PostgreSQL 分区以及相应的 SQL 命令和 PostgreSQL 锁。
完成以下步骤以准备您的环境。对于这种情况,我创建了一个非分区的示例表
car_dat
a。现在,让我们使用本地命令将此表转换为同名的分区表。
-
连接到 RDS for PostgreSQL 数据库实例 或连接到在先决条件步骤中 创建的 Aurora PostgreSQL 集群 。 - 使用以下命令创建非分区表和索引:
在现有表上创建检查约束
定义一个检查约束,当分区作为分区附加到新表时,该分区边界应与旧表的分区边界相匹配。必须在用作新表分区键的列上定义检查约束。检查约束的目的是确保在将旧表作为分区附加时,避免进行表扫描,这是验证分区边界所必需的。
因为我们使用
date_of_purch
ase 作为分区键,所以我们会确定它的最小值和最大值以相应地定义检查约束。在这篇文章中,我们得到以下输出:
使用以下代码使用在
date_of_purchase 的输出中找到的日期
范围创建检查约束:
我们使用 NOT VALID 选项来避免为约束验证而进行昂贵的表扫描。因为我们已经有了分区键的最小值和最大值,所以不需要任何额外的强制器来执行检查约束。
验证现有表的检查约束
使用 NOT VALID 运算符创建约束
条件后,运行 VALID
ATE CONSTRAINT 语句,以便在将表附加为分区时接受该约束。
此命令获得
共享更新专属
锁(你可以在 PostgreSQL 文档中找到更多细节——
在运行
V
ALIDATE CONSTRAINT 命令时,您仍然可以使用 UPDATE、INSERT、DELETE 和 SELECT 语句运行常规工作负载,如以下示例所示。
重命名现有表和索引并创建新的分区表
第一步是,重命名现有表及其相应的索引,使用可以接受新数据的分区创建同名的新分区表,并根据需要创建索引。此外,您还可以在分区列上添加索引。而且,您在单个事务中执行所有这些操作,因为这些步骤之间存在相互依赖性。
在此操作期间,该表在整个事务时间内都不可访问,因为 ALTER TABLE 会使用访问专属锁,这会导致一些停机。请参阅以下 SQL 语句:
将旧表作为分区附加到新表中
将重命名的表
此操作在主表
car_data_old 附加 为 car_dat
a 的分区。
car_data 上使用共享更新独占锁,在所连接的表 (car_
data_old
) 上使用访问独占锁,从而使其不可用于读取 和写入。参见以下代码:
如果没有检查约束,此步骤可能需要更长的时间,因为它会扫描整个 c
ar_data_old
表以验证分区边界。
删除检查约束
因为你不需要它,所以删除你创建的检查约束:
将数据从大分区移动到较小的分区
因为我们将一个大表作为单个分区附加到新表中,所以应该将其分成较小的分区。您可以按照自己的节奏逐步将数据从这个大分区移动到较小的分区。这应该在表上没有业务活动或更少的业务活动时运行,这样数据移动、高 I/O 和锁定对活动查询的影响就会降低。您必须使用事务分步完成此过程,如以下步骤所述,以及相应的 SQL 代码:
- 开始交易。
- 分离步骤中附加的旧表分区将 旧表作为分区 附加到新表 中 。
- 为将从上面分离的旧表中移出的数据创建一个新分区。例如,为值介于 2022-06-01 到 2022-07-01 之间的记录创建分区。
- 使用 INSERT INTO SELECT 语句从旧表中填充上面在步骤 3 中创建的分区。
- 删除已从旧表移至新分区的记录。
- 添加检查约束条件以避免在再次连接分区时进行表扫描。
- 验证在上一步中创建的 CHECK 约束。
- 将旧表及其余记录作为分区附加到新表中。
- 删除该约束,因为它不再需要了。
- 完成交易。
分离分区
car_data_old 后 ,表 c ar_data
将仅包含来自先前定义
的新分区(从 2022-07-01 到 2022-08-01)的数据。请注意,再次附加旧表时,分区边界已更改。这是因为一些数据已移至新的分区
car_data_p
202206。此外,每次运行此步骤时都必须定义检查约束条件并对其进行验证,因为这样可以避免每次定义新的分区边界时进行表扫描。继续执行此步骤,直到包含旧表的整个分区被划分为较小的分区。
清理
完成实施此解决方案的所有步骤后,
结论
在这篇文章中,我向您展示了如何使用 PostgreSQL 原生命令将现有的非分区表迁移到停机时间最少的分区表。表可能不可用,因为在重命名和分区过程中运行 ALTER 命令时会被锁定。当我们定义检查约束时,通过跳过将表作为分区附加时所需的昂贵表扫描,可以大大减少分区期间的停机时间。确保使用前面提到的在事务中运行的命令,否则您将无法达到预期的结果。
最后,我鼓励你自己测试这个过程,完成后清理资源。如果您有任何问题或建议,请将其留在评论部分。
作者简介
*前述特定亚马逊云科技生成式人工智能相关的服务仅在亚马逊云科技海外区域可用,亚马逊云科技中国仅为帮助您发展海外业务和/或了解行业前沿技术选择推荐该服务。