diff options
Diffstat (limited to 'src/backend/utils/cache/relcache.c')
-rw-r--r-- | src/backend/utils/cache/relcache.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index eba77491fd5..84609e07253 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -94,6 +94,19 @@ #define RELCACHE_INIT_FILEMAGIC 0x573266 /* version ID value */ /* + * Default policy for whether to apply RECOVER_RELATION_BUILD_MEMORY: + * do so in clobber-cache builds but not otherwise. This choice can be + * overridden at compile time with -DRECOVER_RELATION_BUILD_MEMORY=1 or =0. + */ +#ifndef RECOVER_RELATION_BUILD_MEMORY +#if defined(CLOBBER_CACHE_ALWAYS) || defined(CLOBBER_CACHE_RECURSIVELY) +#define RECOVER_RELATION_BUILD_MEMORY 1 +#else +#define RECOVER_RELATION_BUILD_MEMORY 0 +#endif +#endif + +/* * hardcoded tuple descriptors, contents generated by genbki.pl */ static const FormData_pg_attribute Desc_pg_class[Natts_pg_class] = {Schema_pg_class}; @@ -1015,6 +1028,28 @@ RelationBuildDesc(Oid targetRelId, bool insertIt) Form_pg_class relp; /* + * This function and its subroutines can allocate a good deal of transient + * data in CurrentMemoryContext. Traditionally we've just leaked that + * data, reasoning that the caller's context is at worst of transaction + * scope, and relcache loads shouldn't happen so often that it's essential + * to recover transient data before end of statement/transaction. However + * that's definitely not true in clobber-cache test builds, and perhaps + * it's not true in other cases. If RECOVER_RELATION_BUILD_MEMORY is not + * zero, arrange to allocate the junk in a temporary context that we'll + * free before returning. Make it a child of caller's context so that it + * will get cleaned up appropriately if we error out partway through. + */ +#if RECOVER_RELATION_BUILD_MEMORY + MemoryContext tmpcxt; + MemoryContext oldcxt; + + tmpcxt = AllocSetContextCreate(CurrentMemoryContext, + "RelationBuildDesc workspace", + ALLOCSET_DEFAULT_SIZES); + oldcxt = MemoryContextSwitchTo(tmpcxt); +#endif + + /* * find the tuple in pg_class corresponding to the given relation id */ pg_class_tuple = ScanPgRelation(targetRelId, true, false); @@ -1023,7 +1058,14 @@ RelationBuildDesc(Oid targetRelId, bool insertIt) * if no such tuple exists, return NULL */ if (!HeapTupleIsValid(pg_class_tuple)) + { +#if RECOVER_RELATION_BUILD_MEMORY + /* Return to caller's context, and blow away the temporary context */ + MemoryContextSwitchTo(oldcxt); + MemoryContextDelete(tmpcxt); +#endif return NULL; + } /* * get information from the pg_class_tuple @@ -1203,6 +1245,12 @@ RelationBuildDesc(Oid targetRelId, bool insertIt) /* It's fully valid */ relation->rd_isvalid = true; +#if RECOVER_RELATION_BUILD_MEMORY + /* Return to caller's context, and blow away the temporary context */ + MemoryContextSwitchTo(oldcxt); + MemoryContextDelete(tmpcxt); +#endif + return relation; } |