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

Commit7c0ca29

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 parentde1ca69 commit7c0ca29

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
@@ -1000,12 +1000,16 @@ get_partition_qual_relid(Oid relid)
10001000
* RelationGetPartitionDispatchInfo
10011001
*Returns information necessary to route tuples down a partition tree
10021002
*
1003-
* All the partitions will be locked with lockmode, unless it is NoLock.
1004-
* A list of the OIDs of all the leaf partitions of rel is returned in
1005-
* *leaf_part_oids.
1003+
* The number of elements in the returned array (that is, the number of
1004+
* PartitionDispatch objects for the partitioned tables in the partition tree)
1005+
* is returned in *num_parted and a list of the OIDs of all the leaf
1006+
* partitions of rel is returned in *leaf_part_oids.
1007+
*
1008+
* All the relations in the partition tree (including 'rel') must have been
1009+
* locked (using at least the AccessShareLock) by the caller.
10061010
*/
10071011
PartitionDispatch*
1008-
RelationGetPartitionDispatchInfo(Relationrel,intlockmode,
1012+
RelationGetPartitionDispatchInfo(Relationrel,
10091013
int*num_parted,List**leaf_part_oids)
10101014
{
10111015
PartitionDispatchData**pd;
@@ -1020,14 +1024,18 @@ RelationGetPartitionDispatchInfo(Relation rel, int lockmode,
10201024
offset;
10211025

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

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

10641067
/*

‎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
@@ -87,8 +87,7 @@ extern Expr *get_partition_qual_relid(Oid relid);
8787

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

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp