Skip to content

Commit 854ae8c

Browse files
committed
Fix permanent memory leak in autovacuum launcher
get_database_list was uselessly allocating its output data, along some created along the way, in a permanent memory context. This didn't matter when autovacuum was a single, short-lived process, but now that the launcher is permanent, it shows up as a permanent leak. To fix, make get_database list allocate its output data in the caller's context, which is in charge of freeing it when appropriate; and the memory leaked by heap_beginscan et al is allocated in a throwaway transaction context.
1 parent 947d0c8 commit 854ae8c

File tree

1 file changed

+17
-3
lines changed

1 file changed

+17
-3
lines changed

src/backend/postmaster/autovacuum.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1754,6 +1754,9 @@ autovac_balance_cost(void)
17541754
* get_database_list
17551755
* Return a list of all databases found in pg_database.
17561756
*
1757+
* The list and associated data is allocated in the caller's memory context,
1758+
* which is in charge of ensuring that it's properly cleaned up afterwards.
1759+
*
17571760
* Note: this is the only function in which the autovacuum launcher uses a
17581761
* transaction. Although we aren't attached to any particular database and
17591762
* therefore can't access most catalogs, we do have enough infrastructure
@@ -1766,6 +1769,10 @@ get_database_list(void)
17661769
Relation rel;
17671770
HeapScanDesc scan;
17681771
HeapTuple tup;
1772+
MemoryContext resultcxt;
1773+
1774+
/* This is the context that we will allocate our output data in */
1775+
resultcxt = CurrentMemoryContext;
17691776

17701777
/*
17711778
* Start a transaction so we can access pg_database, and get a snapshot.
@@ -1777,16 +1784,22 @@ get_database_list(void)
17771784
StartTransactionCommand();
17781785
(void) GetTransactionSnapshot();
17791786

1780-
/* Allocate our results in AutovacMemCxt, not transaction context */
1781-
MemoryContextSwitchTo(AutovacMemCxt);
1782-
17831787
rel = heap_open(DatabaseRelationId, AccessShareLock);
17841788
scan = heap_beginscan(rel, SnapshotNow, 0, NULL);
17851789

17861790
while (HeapTupleIsValid(tup = heap_getnext(scan, ForwardScanDirection)))
17871791
{
17881792
Form_pg_database pgdatabase = (Form_pg_database) GETSTRUCT(tup);
17891793
avw_dbase *avdb;
1794+
MemoryContext oldcxt;
1795+
1796+
/*
1797+
* Allocate our results in the caller's context, not the transaction's.
1798+
* We do this inside the loop, and restore the original context at the
1799+
* end, so that leaky things like heap_getnext() are not called in a
1800+
* potentially long-lived context.
1801+
*/
1802+
oldcxt = MemoryContextSwitchTo(resultcxt);
17901803

17911804
avdb = (avw_dbase *) palloc(sizeof(avw_dbase));
17921805

@@ -1797,6 +1810,7 @@ get_database_list(void)
17971810
avdb->adw_entry = NULL;
17981811

17991812
dblist = lappend(dblist, avdb);
1813+
MemoryContextSwitchTo(oldcxt);
18001814
}
18011815

18021816
heap_endscan(scan);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy