Skip to content

Commit d383d71

Browse files
committed
WIP place some more close_pathman_relation_info()
1 parent f81fcf7 commit d383d71

9 files changed

+363
-360
lines changed

src/hooks.c

+199-199
Large diffs are not rendered by default.

src/include/relation_info.h

-3
Original file line numberDiff line numberDiff line change
@@ -323,9 +323,6 @@ void invalidate_pathman_relation_info_cache(void);
323323
void close_pathman_relation_info(PartRelationInfo *prel);
324324
bool has_pathman_relation_info(Oid relid);
325325
PartRelationInfo *get_pathman_relation_info(Oid relid);
326-
PartRelationInfo *get_pathman_relation_info_after_lock(Oid relid,
327-
bool unlock_if_not_found,
328-
LockAcquireResult *lock_result);
329326

330327
void shout_if_prel_is_invalid(const Oid parent_oid,
331328
const PartRelationInfo *prel,

src/partition_creation.c

+13-3
Original file line numberDiff line numberDiff line change
@@ -334,26 +334,36 @@ create_partitions_for_value_internal(Oid relid, Datum value, Oid value_type,
334334

335335
PG_TRY();
336336
{
337-
LockAcquireResult lock_result; /* could we lock the parent? */
338337
Datum values[Natts_pathman_config];
339338
bool isnull[Natts_pathman_config];
340339

341340
/* Get both PartRelationInfo & PATHMAN_CONFIG contents for this relation */
342341
if (pathman_config_contains_relation(relid, values, isnull, NULL, NULL))
343342
{
344343
PartRelationInfo *prel;
344+
LockAcquireResult lock_result; /* could we lock the parent? */
345345
Oid base_bound_type; /* base type of prel->ev_type */
346346
Oid base_value_type; /* base type of value_type */
347347

348+
/* Prevent modifications of partitioning scheme */
349+
lock_result = xact_lock_rel(relid, ShareUpdateExclusiveLock, false);
350+
348351
/* Fetch PartRelationInfo by 'relid' */
349-
prel = get_pathman_relation_info_after_lock(relid, true, &lock_result);
352+
prel = get_pathman_relation_info(relid);
350353
shout_if_prel_is_invalid(relid, prel, PT_RANGE);
351354

352355
/* Fetch base types of prel->ev_type & value_type */
353356
base_bound_type = getBaseType(prel->ev_type);
354357
base_value_type = getBaseType(value_type);
355358

356-
/* Search for a suitable partition if we didn't hold it */
359+
/*
360+
* Search for a suitable partition if we didn't hold it,
361+
* since somebody might have just created it for us.
362+
*
363+
* If the table is locked, it means that we've
364+
* already failed to find a suitable partition
365+
* and called this function to do the job.
366+
*/
357367
Assert(lock_result != LOCKACQUIRE_NOT_AVAIL);
358368
if (lock_result == LOCKACQUIRE_OK)
359369
{

src/pathman_workers.c

+10-6
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,7 @@ partition_table_concurrently(PG_FUNCTION_ARGS)
691691
int empty_slot_idx = -1, /* do we have a slot for BGWorker? */
692692
i;
693693
TransactionId rel_xmin;
694+
LOCKMODE lockmode = ShareUpdateExclusiveLock;
694695

695696
/* Check batch_size */
696697
if (batch_size < 1 || batch_size > 10000)
@@ -703,12 +704,12 @@ partition_table_concurrently(PG_FUNCTION_ARGS)
703704
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
704705
errmsg("'sleep_time' should not be less than 0.5")));
705706

707+
/* Prevent concurrent function calls */
708+
LockRelationOid(relid, lockmode);
709+
706710
/* Check if relation is a partitioned table */
707-
shout_if_prel_is_invalid(relid,
708-
/* We also lock the parent relation */
709-
get_pathman_relation_info_after_lock(relid, true, NULL),
710-
/* Partitioning type does not matter here */
711-
PT_ANY);
711+
if (!has_pathman_relation_info(relid))
712+
shout_if_prel_is_invalid(relid, NULL, PT_ANY);
712713

713714
/* Check that partitioning operation result is visible */
714715
if (pathman_config_contains_relation(relid, NULL, NULL, &rel_xmin, NULL))
@@ -723,7 +724,7 @@ partition_table_concurrently(PG_FUNCTION_ARGS)
723724

724725
/*
725726
* Look for an empty slot and also check that a concurrent
726-
* partitioning operation for this table hasn't been started yet
727+
* partitioning operation for this table hasn't started yet.
727728
*/
728729
for (i = 0; i < PART_WORKER_SLOTS; i++)
729730
{
@@ -797,6 +798,9 @@ partition_table_concurrently(PG_FUNCTION_ARGS)
797798
CppAsString(stop_concurrent_part_task),
798799
get_rel_name(relid));
799800

801+
/* We don't need this lock anymore */
802+
UnlockRelationOid(relid, lockmode);
803+
800804
PG_RETURN_VOID();
801805
}
802806

src/pl_funcs.c

+18-15
Original file line numberDiff line numberDiff line change
@@ -75,22 +75,22 @@ PG_FUNCTION_INFO_V1( pathman_version );
7575
/* User context for function show_partition_list_internal() */
7676
typedef struct
7777
{
78-
Relation pathman_config;
79-
HeapScanDesc pathman_config_scan;
80-
Snapshot snapshot;
78+
Relation pathman_config;
79+
HeapScanDesc pathman_config_scan;
80+
Snapshot snapshot;
8181

82-
const PartRelationInfo *current_prel; /* selected PartRelationInfo */
82+
PartRelationInfo *current_prel; /* selected PartRelationInfo */
8383

84-
Size child_number; /* child we're looking at */
85-
SPITupleTable *tuptable; /* buffer for tuples */
84+
Size child_number; /* child we're looking at */
85+
SPITupleTable *tuptable; /* buffer for tuples */
8686
} show_partition_list_cxt;
8787

8888
/* User context for function show_pathman_cache_stats_internal() */
8989
typedef struct
9090
{
91-
MemoryContext pathman_contexts[PATHMAN_MCXT_COUNT];
92-
HTAB *pathman_htables[PATHMAN_MCXT_COUNT];
93-
int current_item;
91+
MemoryContext pathman_contexts[PATHMAN_MCXT_COUNT];
92+
HTAB *pathman_htables[PATHMAN_MCXT_COUNT];
93+
int current_item;
9494
} show_cache_stats_cxt;
9595

9696
/*
@@ -362,10 +362,10 @@ show_partition_list_internal(PG_FUNCTION_ARGS)
362362
/* Iterate through pathman cache */
363363
for (;;)
364364
{
365-
const PartRelationInfo *prel;
366-
HeapTuple htup;
367-
Datum values[Natts_pathman_partition_list];
368-
bool isnull[Natts_pathman_partition_list] = { 0 };
365+
HeapTuple htup;
366+
Datum values[Natts_pathman_partition_list];
367+
bool isnull[Natts_pathman_partition_list] = { 0 };
368+
PartRelationInfo *prel;
369369

370370
/* Fetch next PartRelationInfo if needed */
371371
if (usercxt->current_prel == NULL)
@@ -401,6 +401,9 @@ show_partition_list_internal(PG_FUNCTION_ARGS)
401401
/* If we've run out of partitions, switch to the next 'prel' */
402402
if (usercxt->child_number >= PrelChildrenCount(prel))
403403
{
404+
/* Don't forget to close 'prel'! */
405+
close_pathman_relation_info(prel);
406+
404407
usercxt->current_prel = NULL;
405408
usercxt->child_number = 0;
406409

@@ -787,13 +790,13 @@ add_to_pathman_config(PG_FUNCTION_ARGS)
787790
{
788791
pfree(children);
789792

790-
/* Now try to create a PartRelationInfo */
791793
PG_TRY();
792794
{
793795
/* Some flags might change during refresh attempt */
794796
save_pathman_init_state(&init_state);
795797

796-
get_pathman_relation_info(relid);
798+
/* Now try to create a PartRelationInfo */
799+
has_pathman_relation_info(relid);
797800
}
798801
PG_CATCH();
799802
{

0 commit comments

Comments
 (0)