Skip to content

Commit 6cc6619

Browse files
committed
Improve memory handling across SQL-callable backup functions
Since pg_backup_start() and pg_backup_stop() exist, the tablespace map data and the backup state data (backup_label string until 7d70809) have been allocated in the TopMemoryContext. This approach would cause memory leaks in the session calling these functions if failures happen before pg_backup_stop() ends, leaking more memory on repeated failures. Both things need little memory so that would not be really noticeable for most users, except perhaps connection poolers with long-lived connections able to trigger backup failures with these functions. This commit improves the logic in this area by not allocating anymore the backup-related data that needs to travel across the SQL-callable backup functions in TopMemoryContext, by using instead a dedicated memory context child of TopMemoryContext. The memory context is created in pg_backup_start() and deleted when finishing pg_backup_stop(). In the event of an in-flight failure, this memory context gets reset in the follow-up pg_backup_start() call, so as we are sure that only one run worth of data is leaked at any time. Some cleanup was already done for the backup data on a follow-up call of pg_backup_start(), but using a memory context makes the whole simpler. BASE_BACKUP commands are executed in isolation, relying on the memory context created for replication commands, hence these do not need such an extra logic. Author: Bharath Rupireddy Reviewed-by: Robert Haas, Alvaro Herrera, Cary Huang, Michael Paquier Discussion: https://postgr.es/m/CALj2ACXqvfKF2B0beQ=aJMdWnpNohmBPsRg=EDQj_6y1t2O8mQ@mail.gmail.com
1 parent 1f0c4fa commit 6cc6619

File tree

1 file changed

+22
-19
lines changed

1 file changed

+22
-19
lines changed

src/backend/access/transam/xlogfuncs.c

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@
4545
static BackupState *backup_state = NULL;
4646
static StringInfo tablespace_map = NULL;
4747

48+
/* Session-level context for the SQL-callable backup functions */
49+
static MemoryContext backupcontext = NULL;
50+
4851
/*
4952
* pg_backup_start: set up for taking an on-line backup dump
5053
*
@@ -72,27 +75,26 @@ pg_backup_start(PG_FUNCTION_ARGS)
7275

7376
/*
7477
* backup_state and tablespace_map need to be long-lived as they are used
75-
* in pg_backup_stop().
78+
* in pg_backup_stop(). These are allocated in a dedicated memory context
79+
* child of TopMemoryContext, deleted at the end of pg_backup_stop(). If
80+
* an error happens before ending the backup, memory would be leaked in
81+
* this context until pg_backup_start() is called again.
7682
*/
77-
oldcontext = MemoryContextSwitchTo(TopMemoryContext);
78-
79-
/* Allocate backup state or reset it, if it comes from a previous run */
80-
if (backup_state == NULL)
81-
backup_state = (BackupState *) palloc0(sizeof(BackupState));
83+
if (backupcontext == NULL)
84+
{
85+
backupcontext = AllocSetContextCreate(TopMemoryContext,
86+
"on-line backup context",
87+
ALLOCSET_START_SMALL_SIZES);
88+
}
8289
else
83-
MemSet(backup_state, 0, sizeof(BackupState));
84-
85-
/*
86-
* tablespace_map may have been created in a previous backup, so take this
87-
* occasion to clean it.
88-
*/
89-
if (tablespace_map != NULL)
9090
{
91-
pfree(tablespace_map->data);
92-
pfree(tablespace_map);
91+
backup_state = NULL;
9392
tablespace_map = NULL;
93+
MemoryContextReset(backupcontext);
9494
}
9595

96+
oldcontext = MemoryContextSwitchTo(backupcontext);
97+
backup_state = (BackupState *) palloc0(sizeof(BackupState));
9698
tablespace_map = makeStringInfo();
9799
MemoryContextSwitchTo(oldcontext);
98100

@@ -157,12 +159,13 @@ pg_backup_stop(PG_FUNCTION_ARGS)
157159
values[2] = CStringGetTextDatum(tablespace_map->data);
158160

159161
/* Deallocate backup-related variables */
160-
pfree(backup_state);
162+
pfree(backup_label);
163+
164+
/* Clean up the session-level state and its memory context */
161165
backup_state = NULL;
162-
pfree(tablespace_map->data);
163-
pfree(tablespace_map);
164166
tablespace_map = NULL;
165-
pfree(backup_label);
167+
MemoryContextDelete(backupcontext);
168+
backupcontext = NULL;
166169

167170
/* Returns the record as Datum */
168171
PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls)));

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