Skip to content

Commit 972b6ec

Browse files
committed
Fix lock upgrade hazard in ATExecAttachPartition.
Amit Langote Discussion: http://postgr.es/m/CAFjFpReT_kq_uwU_B8aWDxR7jNGE=P0iELycdq5oupi=xSQTOw@mail.gmail.com
1 parent 583df3b commit 972b6ec

File tree

1 file changed

+13
-10
lines changed

1 file changed

+13
-10
lines changed

src/backend/commands/tablecmds.c

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13489,9 +13489,20 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd)
1348913489
/*
1349013490
* Prevent circularity by seeing if rel is a partition of attachrel. (In
1349113491
* particular, this disallows making a rel a partition of itself.)
13492+
*
13493+
* We do that by checking if rel is a member of the list of attachRel's
13494+
* partitions provided the latter is partitioned at all. We want to avoid
13495+
* having to construct this list again, so we request the strongest lock
13496+
* on all partitions. We need the strongest lock, because we may decide
13497+
* to scan them if we find out that the table being attached (or its leaf
13498+
* partitions) may contain rows that violate the partition constraint.
13499+
* If the table has a constraint that would prevent such rows, which by
13500+
* definition is present in all the partitions, we need not scan the
13501+
* table, nor its partitions. But we cannot risk a deadlock by taking a
13502+
* weaker lock now and the stronger one only when needed.
1349213503
*/
1349313504
attachrel_children = find_all_inheritors(RelationGetRelid(attachrel),
13494-
AccessShareLock, NULL);
13505+
AccessExclusiveLock, NULL);
1349513506
if (list_member_oid(attachrel_children, RelationGetRelid(rel)))
1349613507
ereport(ERROR,
1349713508
(errcode(ERRCODE_DUPLICATE_TABLE),
@@ -13694,17 +13705,9 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd)
1369413705
else
1369513706
{
1369613707
/* Constraints proved insufficient, so we need to scan the table. */
13697-
List *all_parts;
1369813708
ListCell *lc;
1369913709

13700-
/* Take an exclusive lock on the partitions to be checked */
13701-
if (attachrel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
13702-
all_parts = find_all_inheritors(RelationGetRelid(attachrel),
13703-
AccessExclusiveLock, NULL);
13704-
else
13705-
all_parts = list_make1_oid(RelationGetRelid(attachrel));
13706-
13707-
foreach(lc, all_parts)
13710+
foreach(lc, attachrel_children)
1370813711
{
1370913712
AlteredTableInfo *tab;
1371013713
Oid part_relid = lfirst_oid(lc);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy