diff options
| author | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2010-11-08 18:35:42 -0300 | 
|---|---|---|
| committer | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2010-11-08 18:36:55 -0300 | 
| commit | 0f0294930420133c7254ac0e3b3a40b8ad74dc80 (patch) | |
| tree | a5bfa4aab6905745b46cc3acf0523b1d8e24a579 /src | |
| parent | ba007262a7661234588b1ebe297e3a95924ba587 (diff) | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/backend/postmaster/autovacuum.c | 20 | 
1 files changed, 17 insertions, 3 deletions
| diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index 78f06672710..6e2741531b5 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -1754,6 +1754,9 @@ autovac_balance_cost(void)   * get_database_list   *		Return a list of all databases found in pg_database.   * + * The list and associated data is allocated in the caller's memory context, + * which is in charge of ensuring that it's properly cleaned up afterwards. + *   * Note: this is the only function in which the autovacuum launcher uses a   * transaction.  Although we aren't attached to any particular database and   * therefore can't access most catalogs, we do have enough infrastructure @@ -1766,6 +1769,10 @@ get_database_list(void)  	Relation	rel;  	HeapScanDesc scan;  	HeapTuple	tup; +	MemoryContext	resultcxt; + +	/* This is the context that we will allocate our output data in */ +	resultcxt = CurrentMemoryContext;  	/*  	 * Start a transaction so we can access pg_database, and get a snapshot. @@ -1777,9 +1784,6 @@ get_database_list(void)  	StartTransactionCommand();  	(void) GetTransactionSnapshot(); -	/* Allocate our results in AutovacMemCxt, not transaction context */ -	MemoryContextSwitchTo(AutovacMemCxt); -  	rel = heap_open(DatabaseRelationId, AccessShareLock);  	scan = heap_beginscan(rel, SnapshotNow, 0, NULL); @@ -1787,6 +1791,15 @@ get_database_list(void)  	{  		Form_pg_database pgdatabase = (Form_pg_database) GETSTRUCT(tup);  		avw_dbase  *avdb; +		MemoryContext	oldcxt; + +		/* +		 * Allocate our results in the caller's context, not the transaction's. +		 * We do this inside the loop, and restore the original context at the +		 * end, so that leaky things like heap_getnext() are not called in a +		 * potentially long-lived context. +		 */ +		oldcxt = MemoryContextSwitchTo(resultcxt);  		avdb = (avw_dbase *) palloc(sizeof(avw_dbase)); @@ -1797,6 +1810,7 @@ get_database_list(void)  		avdb->adw_entry = NULL;  		dblist = lappend(dblist, avdb); +		MemoryContextSwitchTo(oldcxt);  	}  	heap_endscan(scan); | 
