我有一个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操作。
答案 0 :(得分:0)
对于Postgres 10.5,父表上的INSERT
会锁定所有分区,然后再确定应将给定行插入哪个分区。如果您已锁定一个较旧的分区来更改其表空间,则INSERT
必须等待对该分区进行锁定,这可能解释了为什么它超时了。 Postgres 11具有相同的行为,但Postgres 12(目前处于测试版)已解决此问题,因此父表上的INSERT
不会阻止对较旧分区的操作,反之亦然,也就是说,如果{ {1}}仅针对最新的分区。
INSERT
和ATTACH
命令锁定父表。因此,如果您在附加或分离分区的同时DETACH
进入父表,则前者可能会被阻塞,直到后者完成。 INSERT
可能需要一段时间,因为它必须扫描要附加的分区,以检查它是否不包含违反分区约束的任何行。再次,Postgres 12进行了改进,使得ATTACH
不会阻止并发的ATTACH
(和INSERT
/ SELECT
/ UPDATE
)。
为避免父表长时间锁定以进行此验证检查,可以在运行DELETE
命令之前在要附加的表上添加与所需分区约束匹配的检查约束。使用检查约束后,Postgres可以跳过昂贵的ATTACH
验证步骤,因为分区约束由于检查约束有效而已经有效。