Skip to content

Commit f775ebb

Browse files
committed
refactoring, relax locks in refresh_pathman_relation_info() and find_inheritance_children_array()
1 parent 14e05f2 commit f775ebb

File tree

3 files changed

+85
-23
lines changed

3 files changed

+85
-23
lines changed

src/init.c

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -466,8 +466,12 @@ fill_prel_with_partitions(const Oid *partitions,
466466
*
467467
* borrowed from pg_inherits.c
468468
*/
469-
Oid *
470-
find_inheritance_children_array(Oid parentrelId, LOCKMODE lockmode, uint32 *size)
469+
find_children_status
470+
find_inheritance_children_array(Oid parentrelId,
471+
LOCKMODE lockmode,
472+
bool nowait,
473+
uint32 *children_size, /* ret value #1 */
474+
Oid **children) /* ret value #2 */
471475
{
472476
Relation relation;
473477
SysScanDesc scan;
@@ -485,8 +489,12 @@ find_inheritance_children_array(Oid parentrelId, LOCKMODE lockmode, uint32 *size
485489
*/
486490
if (!has_subclass(parentrelId))
487491
{
488-
*size = 0;
489-
return NULL;
492+
/* Init return values */
493+
*children_size = 0;
494+
children = NULL;
495+
496+
/* Ok, could not find any children */
497+
return FCS_NO_CHILDREN;
490498
}
491499

492500
/*
@@ -540,7 +548,25 @@ find_inheritance_children_array(Oid parentrelId, LOCKMODE lockmode, uint32 *size
540548
if (lockmode != NoLock)
541549
{
542550
/* Get the lock to synchronize against concurrent drop */
543-
LockRelationOid(inhrelid, lockmode);
551+
if (nowait)
552+
{
553+
if (!ConditionalLockRelationOid(inhrelid, lockmode))
554+
{
555+
uint32 j;
556+
557+
/* Unlock all previously locked children */
558+
for (j = 0; j < i; j++)
559+
UnlockRelationOid(oidarr[j], lockmode);
560+
561+
/* Init return values */
562+
*children_size = numoids;
563+
*children = oidarr;
564+
565+
/* We couldn't lock this child, retreat! */
566+
return FCS_COULD_NOT_LOCK;
567+
}
568+
}
569+
else LockRelationOid(inhrelid, lockmode);
544570

545571
/*
546572
* Now that we have the lock, double-check to see if the relation
@@ -557,8 +583,12 @@ find_inheritance_children_array(Oid parentrelId, LOCKMODE lockmode, uint32 *size
557583
}
558584
}
559585

560-
*size = numoids;
561-
return oidarr;
586+
/* Init return values */
587+
*children_size = numoids;
588+
*children = oidarr;
589+
590+
/* Ok, we have children */
591+
return FCS_FOUND;
562592
}
563593

564594
/*

src/init.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,19 @@ void fill_prel_with_partitions(const Oid *partitions,
109109
const uint32 parts_count,
110110
PartRelationInfo *prel);
111111

112-
Oid *find_inheritance_children_array(Oid parentrelId,
113-
LOCKMODE lockmode,
114-
uint32 *size);
112+
/* Result of find_inheritance_children_array() */
113+
typedef enum
114+
{
115+
FCS_NO_CHILDREN = 0, /* could not find any children (GOOD) */
116+
FCS_COULD_NOT_LOCK, /* could not lock one of the children */
117+
FCS_FOUND /* found some children (GOOD) */
118+
} find_children_status;
119+
120+
find_children_status find_inheritance_children_array(Oid parentrelId,
121+
LOCKMODE lockmode,
122+
bool nowait,
123+
uint32 *children_size,
124+
Oid **children);
115125

116126
char *build_check_constraint_name_internal(Oid relid,
117127
AttrNumber attno);

src/relation_info.c

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -75,16 +75,16 @@ refresh_pathman_relation_info(Oid relid,
7575
Oid *prel_children;
7676
uint32 prel_children_count = 0,
7777
i;
78-
bool found;
78+
bool found_entry;
7979
PartRelationInfo *prel;
8080
Datum param_values[Natts_pathman_config_params];
8181
bool param_isnull[Natts_pathman_config_params];
8282

8383
prel = (PartRelationInfo *) hash_search(partitioned_rels,
8484
(const void *) &relid,
85-
HASH_ENTER, &found);
85+
HASH_ENTER, &found_entry);
8686
elog(DEBUG2,
87-
found ?
87+
found_entry ?
8888
"Refreshing record for relation %u in pg_pathman's cache [%u]" :
8989
"Creating new record for relation %u in pg_pathman's cache [%u]",
9090
relid, MyProcPid);
@@ -96,7 +96,7 @@ refresh_pathman_relation_info(Oid relid,
9696
prel->cmp_proc = InvalidOid;
9797

9898
/* Clear outdated resources */
99-
if (found && PrelIsValid(prel))
99+
if (found_entry && PrelIsValid(prel))
100100
{
101101
/* Free these arrays iff they're not NULL */
102102
FreeChildrenArray(prel);
@@ -136,16 +136,38 @@ refresh_pathman_relation_info(Oid relid,
136136
prel->cmp_proc = typcache->cmp_proc;
137137
prel->hash_proc = typcache->hash_proc;
138138

139-
LockRelationOid(relid, lockmode);
140-
prel_children = find_inheritance_children_array(relid, lockmode,
141-
&prel_children_count);
142-
UnlockRelationOid(relid, lockmode);
139+
/* Try locking parent, exit fast if 'allow_incomplete' */
140+
if (allow_incomplete)
141+
{
142+
if (!ConditionalLockRelationOid(relid, lockmode))
143+
return NULL; /* leave an invalid entry */
144+
}
145+
else LockRelationOid(relid, lockmode);
143146

144-
/* If there's no children at all, remove this entry */
145-
if (prel_children_count == 0)
147+
/* Try searching for children (don't wait if we can't lock) */
148+
switch (find_inheritance_children_array(relid, lockmode, true,
149+
&prel_children_count,
150+
&prel_children))
146151
{
147-
remove_pathman_relation_info(relid);
148-
return NULL;
152+
/* If there's no children at all, remove this entry */
153+
case FCS_NO_CHILDREN:
154+
UnlockRelationOid(relid, lockmode);
155+
remove_pathman_relation_info(relid);
156+
return NULL; /* exit */
157+
158+
/* If can't lock children, leave an invalid entry */
159+
case FCS_COULD_NOT_LOCK:
160+
UnlockRelationOid(relid, lockmode);
161+
return NULL; /* exit */
162+
163+
/* Found some children, just unlock parent */
164+
case FCS_FOUND:
165+
UnlockRelationOid(relid, lockmode);
166+
break; /* continue */
167+
168+
/* Error: unknown result code */
169+
default:
170+
elog(ERROR, "error in " CppAsString(find_inheritance_children_array));
149171
}
150172

151173
/*
@@ -156,7 +178,7 @@ refresh_pathman_relation_info(Oid relid,
156178
*/
157179
fill_prel_with_partitions(prel_children, prel_children_count, prel);
158180

159-
/* Add "partition+parent" tuple to cache */
181+
/* Add "partition+parent" pair to cache */
160182
for (i = 0; i < prel_children_count; i++)
161183
cache_parent_of_partition(prel_children[i], relid);
162184

0 commit comments

Comments
 (0)