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



我有一个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。如果我试图从父表中分离,真空并附上一个旧分区,我也有类似的问题。我可以在分开分区后访问父母,但是分离和附件需要一段时间,然后在分离/附加步骤中插入父及时间。

使用Postgres 10.5,父表上的INSERT锁定所有分区,然后再确定应插入给定行的分区。如果您锁定了一个旧分区之一以更改其表空间,则INSERT必须等待才能锁定该分区,这可能解释了为什么它会定时。Postgres 11具有相同的行为,但是Postgres 12(目前在beta中(修复了此操作,以使父表上的INSERT不会阻止旧分区上的操作,反之亦然,也就是说,如果INSERT仅针对最新的目标分区。

ATTACHDETACH命令锁定父表。因此,如果您将INSERT与连接或分离分区同时进入父表中,则前者可能会被阻止,直到后者结束为止。ATTACH可能需要一段时间,因为它必须扫描附加的分区以检查是否不包含任何违反分区约束的行。同样,Postgres 12有改进的问题,使得ATTACH不会阻止并发INSERT S(和SELECT/UPDATE/DELETE(。

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

最新更新