我使用的是PostgreSQL 12,其中有一个分区表。该表有需要删除的旧分区。我看过旧分区首先分离然后才删除的代码:
ALTER TABLE partitioned_table DETACH PARTITION partitioned_table_1;
DROP TABLE partitioned_table_1;
是否有任何理由在删除之前分离分区?只删除一个分区而不分离对数据库的其他查询的影响吗?
来自手册。
DROP TABLE partitioned_table_1;
表示删除表。 ACCESS EXCLUSIVE 父表上的锁。
ALTER TABLE partitioned_table DETACH PARTITION partitioned_table_1;
意味着 partitioned_table_1 仍然存在。 ACCESS EXCLUSIVE 父表上的锁
分离的分区继续作为一个独立的表存在,但是 不再与它分离的表有任何联系。
在 postgresql 14 中,
DETACH PARTITION partitioned_table_1 CONCURRENTLY
父表上的SHARE UPDATE EXCLUSIVE 锁。
更多信息:https://www.postgresql.org/docs/12/sql-altertable.html这是一个有趣的问题。
下面就拿这个分区表结构做参考吧(摘自PgAnalyze博文)
说到明智的锁定程序,两种类型的操作:
立即删除分区表(immediate-drop)
DROP TABLE people_partitioned_birthdays_1800_to_1850;
对
从根(父)表中分离分区表,然后删除它(detach-drop)
ALTER TABLE people_partitioned DETACH PARTITION people_partitioned_birthdays_1800_to_1850;
DROP TABLE people_partitioned_birthdays_1800_to_1850;
两者都需要在父表ACCESS EXCLUSIVE LOCK
上执行
people_partitioned
,这会阻止任何SELECT
(没有FOR UPDATE/SHARE
)声明在放置锁时针对people_partitioned
。
然而,当您需要对分区表执行额外的维护操作时,detach-drop 策略才是真正的亮点。您很可能想要使用
COPY
、pg_dump
、
执行数据聚合、分析等……在永久删除之前。而且由于这个分区表已经分离,它不会与父表发生锁冲突。
现在您可能想知道您仍然可以在删除分区的计划仍然存在的情况下执行这些维护操作吗?
-- perform maintenance action on people_partitioned_birthdays_1800_to_1850 ...
DROP TABLE people_partitioned_birthdays_1800_to_1850;
然后,如果有任何操作需要对父表进行排他锁(例如正在创建/删除另一个新分区,这也需要对父表进行排他锁),那么您上面的维护操作将被阻止,直到锁冲突被解决解决了。
总而言之,从根分区表detach-drop分区表通常比immediate-drop更安全。对现有分区表结构的任何操作都不应阻止您对分离分区的维护操作,反之亦然