Moh*_*eem 7 postgresql datatypes alter-table postgresql-performance
我们有一个非常大的POSTGRES表,包含超过80 亿行,并且以非常高的速度增长(每天 3000 万行)。
我们的表是按日期分区的。每个分区包含6 个月的数据,除了第一个分区包含近18 个月的数据。
Postgres 版本:PostgreSQL 12.11
数据库规格: db.r6g.16xlarge (vCPU:64,内存:512,EBSBandwidth(Mbps):19000)
表架构:
create table table_1
(
id bigint default nextval('table_1_id_seq'::regclass) not null,
user_id integer not null,
amount numeric(18, 2) not null,
date timestamp not null,
column_1 varchar not null,
column_2 varchar,
.
.
primary key (id, date)
) partition by RANGE (date);
Run Code Online (Sandbox Code Playgroud)
该表还包含多个索引(包括部分索引)
create index index_1
on table_1 (column_1);
create index index_2
on table_1 (date, column_2, column_3);
create index index_3
on table_1 (column_4);
create index index_4
on table_1 (user_id, column_3);
create index index_5
on table_1 (user_id asc, date desc)
where (column_3 = ANY (ARRAY [1, 2, 3, 6, 7, 8, 10]));
create index index_6
on table_1 (user_id, column_2, column_3, column_5);
Run Code Online (Sandbox Code Playgroud)
最初,我们创建了数据类型为 numeric(18, 2) 的amount列。现在我们需要支持高达 6 的更高精度。因此我们需要将类型更改为numeric(22, 6)。
现在运行如下所示的Alter 命令需要花费大量时间(数小时):
注意:我们在表上运行此命令,没有删除任何索引
ALTER TABLE table_1 ALTER COLUMN amount type numeric(22, 6);
Run Code Online (Sandbox Code Playgroud)
我们正在探索的几种不同策略:
更新运行时删除所有索引、触发器和外键,并在最后重新创建它们。
创建新表:
A。创建一个具有完全相同配置的新分区表,
b. 将数据从旧表迁移到新表。
C。在新表上创建所有索引。
d. 删除旧表。
注意:我们的主要目标是最大限度地减少停机时间。如果 更大的数据库实例可以提供帮助,我们也愿意对此进行探索。
我们想探索是否有其他策略来完成这项任务,或者在我们当前的策略中,我们可以采取哪些额外或不同的措施来最大限度地减少停机时间。
我要做的如下:
VACUUM ANALYZE
在更新一定数量的行后执行 a 操作。ALTER TABLE
操作来将同一事务中的两列重命名(新的为amount
,旧的为其他)。这通常是一个非常快的操作。预先检查应用程序是否可以在所有读取路径上很好地处理数据类型更改。根据我的经验,这是您必须以尽可能短的停机时间进行计划的方式。更改的总时间将比简单的数据类型更改要长得多。另一方面,如果出现一些问题,您可以恢复到旧列直到最后。显然,事先在测试环境中测试该过程。
注1:正如评论中提到的,您有可能无法在交换新列的同时更改应用程序代码。在这种情况下,您将需要ALTER TABLE
在事务中使用三个语句:
amount -> amount_old
amount_new -> amount
amount_old -> amount_new (looks confusing first, but the application will be happy)
Run Code Online (Sandbox Code Playgroud)
然后更改应用程序代码以使用更高的精度amount
和 的原始精度amount_new
。
注意2:如果您碰巧使用较旧的Postgres版本(最多10个),请添加新列而不使用默认值,否则整个表将被重写。在更高版本中,这种情况仅在不稳定的默认值下发生- 检查您的用例是否与这两种情况匹配。
归档时间: |
|
查看次数: |
1780 次 |
最近记录: |