Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit54cde0c

Browse files
committed
Don't lock tables in RelationGetPartitionDispatchInfo.
Instead, lock them in the caller using find_all_inheritors so thatthey get locked in the standard order, minimizing deadlock risks.Also in RelationGetPartitionDispatchInfo, avoid opening tables whichare not partitioned; there's no need.Amit Langote, reviewed by Ashutosh Bapat and Amit KhandekarDiscussion:http://postgr.es/m/91b36fa1-c197-b72f-ca6e-56c593bae68c@lab.ntt.co.jp
1 parentecfe59e commit54cde0c

File tree

3 files changed

+37
-31
lines changed

3 files changed

+37
-31
lines changed

‎src/backend/catalog/partition.c

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -999,12 +999,16 @@ get_partition_qual_relid(Oid relid)
999999
* RelationGetPartitionDispatchInfo
10001000
*Returns information necessary to route tuples down a partition tree
10011001
*
1002-
* All the partitions will be locked with lockmode, unless it is NoLock.
1003-
* A list of the OIDs of all the leaf partitions of rel is returned in
1004-
* *leaf_part_oids.
1002+
* The number of elements in the returned array (that is, the number of
1003+
* PartitionDispatch objects for the partitioned tables in the partition tree)
1004+
* is returned in *num_parted and a list of the OIDs of all the leaf
1005+
* partitions of rel is returned in *leaf_part_oids.
1006+
*
1007+
* All the relations in the partition tree (including 'rel') must have been
1008+
* locked (using at least the AccessShareLock) by the caller.
10051009
*/
10061010
PartitionDispatch*
1007-
RelationGetPartitionDispatchInfo(Relationrel,intlockmode,
1011+
RelationGetPartitionDispatchInfo(Relationrel,
10081012
int*num_parted,List**leaf_part_oids)
10091013
{
10101014
PartitionDispatchData**pd;
@@ -1019,14 +1023,18 @@ RelationGetPartitionDispatchInfo(Relation rel, int lockmode,
10191023
offset;
10201024

10211025
/*
1022-
* Lock partitions and make a list of the partitioned ones to prepare
1023-
* their PartitionDispatch objects below.
1026+
* We rely on the relcache to traverse the partition tree to build both
1027+
* the leaf partition OIDs list and the array of PartitionDispatch objects
1028+
* for the partitioned tables in the tree. That means every partitioned
1029+
* table in the tree must be locked, which is fine since we require the
1030+
* caller to lock all the partitions anyway.
10241031
*
1025-
* Cannot use find_all_inheritors() here, because then the order of OIDs
1026-
* in parted_rels list would be unknown, which does not help, because we
1027-
* assign indexes within individual PartitionDispatch in an order that is
1028-
* predetermined (determined by the order of OIDs in individual partition
1029-
* descriptors).
1032+
* For every partitioned table in the tree, starting with the root
1033+
* partitioned table, add its relcache entry to parted_rels, while also
1034+
* queuing its partitions (in the order in which they appear in the
1035+
* partition descriptor) to be looked at later in the same loop. This is
1036+
* a bit tricky but works because the foreach() macro doesn't fetch the
1037+
* next list element until the bottom of the loop.
10301038
*/
10311039
*num_parted=1;
10321040
parted_rels=list_make1(rel);
@@ -1035,29 +1043,24 @@ RelationGetPartitionDispatchInfo(Relation rel, int lockmode,
10351043
APPEND_REL_PARTITION_OIDS(rel,all_parts,all_parents);
10361044
forboth(lc1,all_parts,lc2,all_parents)
10371045
{
1038-
Relationpartrel=heap_open(lfirst_oid(lc1),lockmode);
1046+
Oidpartrelid=lfirst_oid(lc1);
10391047
Relationparent=lfirst(lc2);
1040-
PartitionDescpartdesc=RelationGetPartitionDesc(partrel);
10411048

1042-
/*
1043-
* If this partition is a partitioned table, add its children to the
1044-
* end of the list, so that they are processed as well.
1045-
*/
1046-
if (partdesc)
1049+
if (get_rel_relkind(partrelid)==RELKIND_PARTITIONED_TABLE)
10471050
{
1051+
/*
1052+
* Already locked by the caller. Note that it is the
1053+
* responsibility of the caller to close the below relcache entry,
1054+
* once done using the information being collected here (for
1055+
* example, in ExecEndModifyTable).
1056+
*/
1057+
Relationpartrel=heap_open(partrelid,NoLock);
1058+
10481059
(*num_parted)++;
10491060
parted_rels=lappend(parted_rels,partrel);
10501061
parted_rel_parents=lappend(parted_rel_parents,parent);
10511062
APPEND_REL_PARTITION_OIDS(partrel,all_parts,all_parents);
10521063
}
1053-
else
1054-
heap_close(partrel,NoLock);
1055-
1056-
/*
1057-
* We keep the partitioned ones open until we're done using the
1058-
* information being collected here (for example, see
1059-
* ExecEndModifyTable).
1060-
*/
10611064
}
10621065

10631066
/*

‎src/backend/executor/execMain.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include"access/xact.h"
4444
#include"catalog/namespace.h"
4545
#include"catalog/partition.h"
46+
#include"catalog/pg_inherits_fn.h"
4647
#include"catalog/pg_publication.h"
4748
#include"commands/matview.h"
4849
#include"commands/trigger.h"
@@ -3249,9 +3250,12 @@ ExecSetupPartitionTupleRouting(Relation rel,
32493250
inti;
32503251
ResultRelInfo*leaf_part_rri;
32513252

3252-
/* Get the tuple-routing information and lock partitions */
3253-
*pd=RelationGetPartitionDispatchInfo(rel,RowExclusiveLock,num_parted,
3254-
&leaf_parts);
3253+
/*
3254+
* Get the information about the partition tree after locking all the
3255+
* partitions.
3256+
*/
3257+
(void)find_all_inheritors(RelationGetRelid(rel),RowExclusiveLock,NULL);
3258+
*pd=RelationGetPartitionDispatchInfo(rel,num_parted,&leaf_parts);
32553259
*num_partitions=list_length(leaf_parts);
32563260
*partitions= (ResultRelInfo*)palloc(*num_partitions*
32573261
sizeof(ResultRelInfo));

‎src/include/catalog/partition.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,7 @@ extern Expr *get_partition_qual_relid(Oid relid);
8888

8989
/* For tuple routing */
9090
externPartitionDispatch*RelationGetPartitionDispatchInfo(Relationrel,
91-
intlockmode,int*num_parted,
92-
List**leaf_part_oids);
91+
int*num_parted,List**leaf_part_oids);
9392
externvoidFormPartitionKeyDatum(PartitionDispatchpd,
9493
TupleTableSlot*slot,
9594
EState*estate,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp