]> granicus.if.org Git - postgresql/commitdiff
Defend against leaks into RelationBuildPartitionDesc.
authorRobert Haas <rhaas@postgresql.org>
Thu, 14 Mar 2019 16:03:31 +0000 (12:03 -0400)
committerRobert Haas <rhaas@postgresql.org>
Thu, 14 Mar 2019 16:14:47 +0000 (12:14 -0400)
In normal builds, this isn't very important, because the leaks go
into fairly short-lived contexts, but under CLOBBER_CACHE_ALWAYS,
this can result in leaking hundreds of megabytes into MessageContext,
which probably explains recent failures on hyrax.

This may or may not be the best long-term strategy for dealing
with this leak, but we can change it later if we come up with
something better.  For now, do this to make the buildfarm green
again (hopefully).  Commit 898e5e3290a72d288923260143930fb32036c00c
seems to have exacerbated this problem for reasons that are not
quite clear, but I don't believe it's actually the cause.

Discussion: http://postgr.es/m/CA+TgmoY3bRmGB6-DUnoVy5fJoreiBJ43rwMrQRCdPXuKt4Ykaw@mail.gmail.com

src/backend/partitioning/partdesc.c

index a4494aca7aaa2b6e935b68d32315d85b33dc4c03..0593f044c22c0feaf4a8a20638600422a8c8bc9a 100644 (file)
@@ -68,6 +68,17 @@ RelationBuildPartitionDesc(Relation rel)
        PartitionKey key = RelationGetPartitionKey(rel);
        MemoryContext oldcxt;
        int                *mapping;
+       MemoryContext rbcontext = NULL;
+
+       /*
+        * While building the partition descriptor, we create various temporary
+        * data structures; in CLOBBER_CACHE_ALWAYS mode, at least, it's important
+        * not to leak them, since this can get called a lot.
+        */
+       rbcontext = AllocSetContextCreate(CurrentMemoryContext,
+                                                                         "RelationBuildPartitionDesc",
+                                                                         ALLOCSET_DEFAULT_SIZES);
+       oldcxt = MemoryContextSwitchTo(rbcontext);
 
        /*
         * Get partition oids from pg_inherits.  This uses a single snapshot to
@@ -180,7 +191,7 @@ RelationBuildPartitionDesc(Relation rel)
        MemoryContextCopyAndSetIdentifier(rel->rd_pdcxt,
                                                                          RelationGetRelationName(rel));
 
-       oldcxt = MemoryContextSwitchTo(rel->rd_pdcxt);
+       MemoryContextSwitchTo(rel->rd_pdcxt);
        partdesc = (PartitionDescData *) palloc0(sizeof(PartitionDescData));
        partdesc->nparts = nparts;
        /* oids and boundinfo are allocated below. */
@@ -189,7 +200,11 @@ RelationBuildPartitionDesc(Relation rel)
 
        if (nparts == 0)
        {
+               /* We can exit early in this case. */
                rel->rd_partdesc = partdesc;
+
+               /* Blow away the temporary context. */
+               MemoryContextDelete(rbcontext);
                return;
        }
 
@@ -220,6 +235,9 @@ RelationBuildPartitionDesc(Relation rel)
        MemoryContextSwitchTo(oldcxt);
 
        rel->rd_partdesc = partdesc;
+
+       /* Blow away the temporary context. */
+       MemoryContextDelete(rbcontext);
 }
 
 /*