简体   繁体   English

Postgres - 如何在不持有 AccessExclusiveLock 的情况下向具有 DEFAULT 分区的表添加分区?

[英]Postgres - how to add a partition to a table that has a DEFAULT partition, without holding AccessExclusiveLock?

Specifically, this section of the postgres doc doc says I should be able to avoid a scan of the default partition:具体来说, postgres doc文档的这一部分说我应该能够避免扫描默认分区:

Before running the ATTACH PARTITION command, it is recommended to create a CHECK constraint on the table to be attached that matches the expected partition constraint, as illustrated above.在运行 ATTACH PARTITION 命令之前,建议在要附加的表上创建一个 CHECK 约束,该约束与预期的分区约束相匹配,如上所示。 That way, the system will be able to skip the scan which is otherwise needed to validate the implicit partition constraint.这样,系统将能够跳过验证隐式分区约束所需的扫描。 Without the CHECK constraint, the table will be scanned to validate the partition constraint while holding an ACCESS EXCLUSIVE lock on that partition.如果没有 CHECK 约束,将扫描表以验证分区约束,同时对该分区持有 ACCESS EXCLUSIVE 锁。 It is recommended to drop the now-redundant CHECK constraint after the ATTACH PARTITION is complete.建议在 ATTACH PARTITION 完成后删除现在冗余的 CHECK 约束。 If the table being attached is itself a partitioned table, then each of its sub-partitions will be recursively locked and scanned until either a suitable CHECK constraint is encountered or the leaf partitions are reached.如果被附加的表本身是一个分区表,那么它的每个子分区都将被递归锁定和扫描,直到遇到合适的 CHECK 约束或到达叶分区。

Similarly, if the partitioned table has a DEFAULT partition, it is recommended to create a CHECK constraint which excludes the to-be-attached partition's constraint.同样,如果分区表有一个DEFAULT分区,建议创建一个排除待附加分区约束的CHECK约束。 If this is not done then the DEFAULT partition will be scanned to verify that it contains no records which should be located in the partition being attached.如果不这样做,则将扫描 DEFAULT 分区以验证它不包含应位于所附加分区中的记录。 This operation will be performed whilst holding an ACCESS EXCLUSIVE lock on the DEFAULT partition.此操作将在 DEFAULT 分区上持有 ACCESS EXCLUSIVE 锁的同时执行。 If the DEFAULT partition is itself a partitioned table, then each of its partitions will be recursively checked in the same way as the table being attached, as mentioned above.如果 DEFAULT 分区本身是一个分区表,那么它的每个分区将以与附加表相同的方式递归检查,如上所述。

But, the below doesn't work for me: task_time is not null and of type timestamp (6) with timezone .但是,以下内容对我不起作用: task_time not null并且类型为timestamp (6) with timezone

-- create new empty partition table
CREATE TABLE tasks_partitions.tasks_20230111
(LIKE tasks INCLUDING DEFAULTS INCLUDING CONSTRAINTS);

-- add CHECK constraint on new partition 
ALTER TABLE tasks_partitions.tasks_20230111 ADD CONSTRAINT tmp_20230111
CHECK (task_time >= '2023-01-11 00:00:00+00' AND task_time <= '2023-01-11 23:59:59.999999+00');

-- add CHECK constraint on default partition that excludes new partition constraint
ALTER TABLE tasks_partitions.tasks_20230111 ADD CONSTRAINT tmp20230111_default
CHECK (task_time < '2023-01-11 00:00:00+00' and task time > '2023-01-11 23:59:59.999999+00') NOT VALID;

-- attach partition
ALTER TABLE tasks ATTACH PARTITION tasks_partitions_tasks_20230111
FOR VALUES FROM ('2023-01-11 00:00:00+00') TO ('2023-01-11 23:59:59.999999+00')

Attaching the partition still holds the AccessExclusiveLock .附加分区仍然持有AccessExclusiveLock

This operation will always take an ACCESS EXCLUSIVE lock.此操作将始终采用ACCESS EXCLUSIVE锁。 The documentation only tells you how you can reduce the time the lock is held.该文档仅告诉您如何减少持有锁的时间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM