From cc5103479506aba20ed1c115755fe329343fbcf2 Mon Sep 17 00:00:00 2001 From: amit Date: Mon, 16 Apr 2018 16:10:16 +0900 Subject: [PATCH v1 2/3] Cache all partitioning info under one memory context Instead of having one for PartitionKey and another for PartitionDesc, use just one. Also, instead of allocating partition constraint expression tree directly under CacheMemoryContext, do it under the aforementioned context. --- src/backend/utils/cache/partcache.c | 33 +++++++----------------------- src/backend/utils/cache/relcache.c | 40 +++++++++++++++++++++++++------------ src/include/utils/rel.h | 4 ++-- 3 files changed, 36 insertions(+), 41 deletions(-) diff --git a/src/backend/utils/cache/partcache.c b/src/backend/utils/cache/partcache.c index 0c8bbec12d..e234320e30 100644 --- a/src/backend/utils/cache/partcache.c +++ b/src/backend/utils/cache/partcache.c @@ -72,8 +72,7 @@ RelationBuildPartitionKey(Relation relation) oidvector *collation; ListCell *partexprs_item; Datum datum; - MemoryContext partkeycxt, - oldcxt; + MemoryContext oldcxt; int16 procnum; tuple = SearchSysCache1(PARTRELID, @@ -86,13 +85,7 @@ RelationBuildPartitionKey(Relation relation) if (!HeapTupleIsValid(tuple)) return; - partkeycxt = AllocSetContextCreate(CurTransactionContext, - "partition key", - ALLOCSET_SMALL_SIZES); - MemoryContextCopyAndSetIdentifier(partkeycxt, - RelationGetRelationName(relation)); - - key = (PartitionKey) MemoryContextAllocZero(partkeycxt, + key = (PartitionKey) MemoryContextAllocZero(relation->rd_partcxt, sizeof(PartitionKeyData)); /* Fixed-length attributes */ @@ -144,12 +137,12 @@ RelationBuildPartitionKey(Relation relation) expr = eval_const_expressions(NULL, expr); fix_opfuncids(expr); - oldcxt = MemoryContextSwitchTo(partkeycxt); + oldcxt = MemoryContextSwitchTo(relation->rd_partcxt); key->partexprs = (List *) copyObject(expr); MemoryContextSwitchTo(oldcxt); } - oldcxt = MemoryContextSwitchTo(partkeycxt); + oldcxt = MemoryContextSwitchTo(relation->rd_partcxt); key->partattrs = (AttrNumber *) palloc0(key->partnatts * sizeof(AttrNumber)); key->partopfamily = (Oid *) palloc0(key->partnatts * sizeof(Oid)); key->partopcintype = (Oid *) palloc0(key->partnatts * sizeof(Oid)); @@ -211,7 +204,7 @@ RelationBuildPartitionKey(Relation relation) * first to the caller's memory context, so setting the memory context * here may seem pointless. */ - fmgr_info_cxt(funcid, &key->partsupfunc[i], partkeycxt); + fmgr_info_cxt(funcid, &key->partsupfunc[i], relation->rd_partcxt); /* Collation */ key->partcollation[i] = collation->values[i]; @@ -245,13 +238,6 @@ RelationBuildPartitionKey(Relation relation) } ReleaseSysCache(tuple); - - /* - * Success --- reparent our context and make the relcache point to the - * newly constructed key - */ - MemoryContextSetParent(partkeycxt, CacheMemoryContext); - relation->rd_partkeycxt = partkeycxt; relation->rd_partkey = key; } @@ -583,12 +569,7 @@ RelationBuildPartitionDesc(Relation rel) } /* Now build the actual relcache partition descriptor */ - rel->rd_pdcxt = AllocSetContextCreate(CacheMemoryContext, - "partition descriptor", - ALLOCSET_DEFAULT_SIZES); - MemoryContextCopyAndSetIdentifier(rel->rd_pdcxt, RelationGetRelationName(rel)); - - oldcxt = MemoryContextSwitchTo(rel->rd_pdcxt); + oldcxt = MemoryContextSwitchTo(rel->rd_partcxt); result = (PartitionDescData *) palloc0(sizeof(PartitionDescData)); result->nparts = nparts; @@ -1043,7 +1024,7 @@ generate_partition_qual(Relation rel) elog(ERROR, "unexpected whole-row reference found in partition key"); /* Save a copy in the relcache */ - oldcxt = MemoryContextSwitchTo(CacheMemoryContext); + oldcxt = MemoryContextSwitchTo(rel->rd_partcxt); rel->rd_partcheck = copyObject(result); MemoryContextSwitchTo(oldcxt); diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index 86bff9c53b..16081bc932 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -1129,17 +1129,36 @@ RelationBuildDesc(Oid targetRelId, bool insertIt) * If we need to initialize partitioning info, do that in a dedicated * context that's attached to the cache context. */ - if (relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) + if (relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE || + relation->rd_rel->relispartition) { - RelationBuildPartitionKey(relation); - RelationBuildPartitionDesc(relation); + relation->rd_partcxt = AllocSetContextCreate(CacheMemoryContext, + "partition info", + ALLOCSET_SMALL_SIZES); + MemoryContextCopyAndSetIdentifier(relation->rd_partcxt, + RelationGetRelationName(relation)); + + /* + * For a partitioned table, initialize partition key and partition + * descriptor. + */ + if (relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) + { + RelationBuildPartitionKey(relation); + RelationBuildPartitionDesc(relation); + } + + /* + * Partition constraint of a partition itself is built only when + * needed. See RelationGetPartitionQual(). + */ } else { - relation->rd_partkeycxt = NULL; + relation->rd_partcxt = NULL; relation->rd_partkey = NULL; - relation->rd_pdcxt = NULL; relation->rd_partdesc = NULL; + relation->rd_partcheck = NIL; } /* @@ -2142,12 +2161,8 @@ RelationDestroyRelation(Relation relation, bool remember_tupdesc) MemoryContextDelete(relation->rd_rulescxt); if (relation->rd_rsdesc) MemoryContextDelete(relation->rd_rsdesc->rscxt); - if (relation->rd_partkeycxt) - MemoryContextDelete(relation->rd_partkeycxt); - if (relation->rd_pdcxt) - MemoryContextDelete(relation->rd_pdcxt); - if (relation->rd_partcheck) - pfree(relation->rd_partcheck); + if (relation->rd_partcxt) + MemoryContextDelete(relation->rd_partcxt); if (relation->rd_fdwroutine) pfree(relation->rd_fdwroutine); pfree(relation); @@ -5492,9 +5507,8 @@ load_relcache_init_file(bool shared) rel->rd_rulescxt = NULL; rel->trigdesc = NULL; rel->rd_rsdesc = NULL; - rel->rd_partkeycxt = NULL; + rel->rd_partcxt = NULL; rel->rd_partkey = NULL; - rel->rd_pdcxt = NULL; rel->rd_partdesc = NULL; rel->rd_partcheck = NIL; rel->rd_indexprs = NIL; diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h index f5b84ed60a..378401abca 100644 --- a/src/include/utils/rel.h +++ b/src/include/utils/rel.h @@ -95,9 +95,9 @@ typedef struct RelationData List *rd_fkeylist; /* list of ForeignKeyCacheInfo (see below) */ bool rd_fkeyvalid; /* true if list has been computed */ - MemoryContext rd_partkeycxt; /* private memory cxt for the below */ + MemoryContext rd_partcxt; /* private memory cxt for the values contained + * in the fields related to partitioning */ struct PartitionKeyData *rd_partkey; /* partition key, or NULL */ - MemoryContext rd_pdcxt; /* private context for partdesc */ struct PartitionDescData *rd_partdesc; /* partitions, or NULL */ List *rd_partcheck; /* partition CHECK quals */ -- 2.11.0