为什么处理单个 POSTGRES 分区会影响父分区 table?

Why does working on an individual POSTGRES partition effect the parent table?

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

我的 table 的定义类似于 -

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 插入父级 table tableA(不是特定分区),loadedTime 总是指当前时间,所以数据总是被加载到今天的分区。

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

更新 - 当前使用 postgres 10.5。如果我尝试 DETACH、VACUUM 和 ATTACH 来自父 table 的旧分区,我会遇到类似的问题。分离分区后我可以访问父级,但是 DETACH 和 ATTACH 需要一段时间,并且在 detach/attach 步骤期间在父级超时时插入。

对于 Postgres 10.5,父 table 上的 INSERT 在确定给定行应插入到哪个分区之前锁定所有分区。如果您已锁定其中一个较旧的分区以更改其 table space,则 INSERT 必须等待获得对该分区的锁定,这可能解释了为什么它会超时. Postgres 11 具有相同的行为,但 Postgres 12(目前处于测试阶段)修复了此问题,因此父 table 上的 INSERT 不会阻止对旧分区的操作,反之亦然,即,如果 INSERT 仅针对最新的分区。

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

为避免父table被长时间锁定以进行此验证检查,您可以在table上添加检查约束以匹配所需的分区约束在[=之前39=] ATTACH 命令。有了检查约束,Postgres 可以跳过昂贵的 ATTACH 验证步骤,因为分区约束已经有效,因为检查约束有效。