为什么在单个POSTGRES分区上工作会影响父表?

时间:2019-05-25 19:21:44

标签: postgresql partitioning

我有一个24/7的postgres数据库,其中已经对一些主要表进行了分区,以便在仍在加载数据的同时进行维护。不幸的是,对单个分区的更改似乎仍然会对父表产生影响。

我的表被定义为-

CREATE TABLE tableA ( loadedTime TIMESTAMP, rawData CHARACTER(150))
PARTITION BY RANGE (loadedTime)

以及各个分区-

CREATE TABLE tableA_yyyymmdd PARTITION OF tableA FOR VALUES FROM () TO ()

范围等于各天。

我有一个将记录24/7插入到父表 tableA (不是特定分区)的过程, loadedTime 始终引用当前时间,因此数据为总是加载到今天的分区中。

为什么更改某些旧分区的表空间会导致对当前分区的插入超时?我的理解是,分区几乎就像单独的表一样,我应该能够在分区上工作而不会导致父表出现问题-还是我误解了?

更新-当前使用的是postgres 10.5。如果我尝试从父表中分离,删除和附加旧分区,也会遇到类似的问题。分离分区后,我可以访问父级了,但是在分离/附加步骤中,DETACH和ATTACH花费了一段时间,并且在父级超时上进行了INSERT操作。

1 个答案:

答案 0 :(得分:0)

对于Postgres 10.5,父表上的INSERT会锁定所有分区,然后再确定应将给定行插入哪个分区。如果您已锁定一个较旧的分区来更改其表空间,则INSERT必须等待对该分区进行锁定,这可能解释了为什么它超时了。 Postgres 11具有相同的行为,但Postgres 12(目前处于测试版)已解决此问题,因此父表上的INSERT不会阻止对较旧分区的操作,反之亦然,也就是说,如果{ {1}}仅针对最新的分区。

INSERTATTACH命令锁定父表。因此,如果您在附加或分离分区的同时DETACH进入父表,则前者可能会被阻塞,直到后者完成。 INSERT可能需要一段时间,因为它必须扫描要附加的分区,以检查它是否不包含违反分区约束的任何行。再次,Postgres 12进行了改进,使得ATTACH不会阻止并发的ATTACH(和INSERT / SELECT / UPDATE)。

为避免父表长时间锁定以进行此验证检查,可以在运行DELETE命令之前在要附加的表上添加与所需分区约束匹配的检查约束。使用检查约束后,Postgres可以跳过昂贵的ATTACH验证步骤,因为分区约束由于检查约束有效而已经有效。