我在 PostgreSQL 14 中有一个简单的分区表,如下所示:
create table entity
(
dataset_id integer not null references dataset (id),
...
) partition by list (dataset_id);
create table entity_1
(
like entity including constraints including defaults,
constraint entity_1_pkey primary key (entity_id),
);
alter table entity attach partition entity_1 for values in (1);
创建一个分区的原因是先“分离”一个分区,然后在单独的语句中附加它是为了避免在父表上获得排他锁entity
(分割。这是Laurenz Albe在https://stackoverflow.com/a/67016755/1536933中建议的解决方案,它非常适合创建分区。
不幸的是,我在删除分区时遇到了同样的问题:只要客户端正在从任何分区读取数据,我就无法删除任何其他分区:不仅被drop table entity_1
阻塞,甚至alter table entity detach partition entity_1 concurrently
被阻塞!我看不到pg_locks
“同时分离”语句的任何相关锁定(没有granted=false
),但 pgAdmin 仪表板显示Wait event: Lock: virtualxid
和Blocking PIDs: (pid of the reading process)
从其他分区读取数据时如何删除分区?当然这应该是可能的?
ALTER TABLE ... DETACH PARTITION CONCURRENTLY
是您拥有的最佳工具。是的,它会等到所有读取表的事务都完成后,但这应该不是问题,因为并发读取在任何时候都不会被阻塞。只需等到读取事务完成(所有事务必须在某一天结束),你就很好了。请注意,您无需等到表上没有活动事务:您只需等到您开始时活动的
ALTER TABLE
所有事务都完成。