PostgreSQL 分区和分片

2 minute read

分区

分区表并不是每天都要用到的,但在某些情况下,尤其是当你有一个预计会不断增长的大容量表时,分区表就显得尤为重要。

在 PostgreSQL 下拥有 Hot Table 隐患时进行删除操作是很灾难性的,一个长期运行的查询将会遍历每一条数据,标记为 dead 后执行操作,在这过程中不会释放任何空间。但有了分区,删除就变成了简单的 DROP TABLE。 它可以立即执行,成本可以忽略不计(分区还有其他好处)。当然,代价是需要重点维护。

分区操作

– 列出所有已存在的表

– 决定应创建哪些新分区(如果有的话)并创建它们,提前三天将未来的分区调出来,为操作提供一些缓冲,以防出错。

1CREATE TABLE widget_20221005 PARTITION OF widget
2  FOR VALUES FROM ('2022-10-05') TO ('2022-10-06');
1ALTER TABLE widget DETACH partition widget_20221005;
1DROP TABLE widget_20221005;

INSERT 和 UPDATE 都发生在父表上,因此分区完全从正常的应用程序逻辑中抽象出来。这样我们就完成了一次简单的分区操作。

分片

一种将 Postgres 数据库表分割成更小表的技术,通常用于在组成数据库实例集群的多个节点上横向分发数据,更多部署在多节点集群。

使用 Citus 分片操作

1create extension citus;
1SELECT create_distributed_table('table', 'shard_column', shard_count := 256);
1SELECT * FROM citus_add_node('worker_node_address', '192.168.0.2');
1rebalance:
2SELECT rebalance_table_shards();

除了简单方便外,使用 Citus 分片的好处还有性能:由于分片本质上也是散列分区的一种形式,因此分区的一些性能优势也适用于分片。 特别是,autovacuum 会在集群中的所有 Citus 分片上并行运行。