|
45 | 45 | static BackupState *backup_state = NULL;
|
46 | 46 | static StringInfo tablespace_map = NULL;
|
47 | 47 |
|
| 48 | +/* Session-level context for the SQL-callable backup functions */ |
| 49 | +static MemoryContext backupcontext = NULL; |
| 50 | + |
48 | 51 | /*
|
49 | 52 | * pg_backup_start: set up for taking an on-line backup dump
|
50 | 53 | *
|
@@ -72,27 +75,26 @@ pg_backup_start(PG_FUNCTION_ARGS)
|
72 | 75 |
|
73 | 76 | /*
|
74 | 77 | * 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. |
76 | 82 | */
|
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 | + } |
82 | 89 | 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) |
90 | 90 | {
|
91 |
| - pfree(tablespace_map->data); |
92 |
| - pfree(tablespace_map); |
| 91 | + backup_state = NULL; |
93 | 92 | tablespace_map = NULL;
|
| 93 | + MemoryContextReset(backupcontext); |
94 | 94 | }
|
95 | 95 |
|
| 96 | + oldcontext = MemoryContextSwitchTo(backupcontext); |
| 97 | + backup_state = (BackupState *) palloc0(sizeof(BackupState)); |
96 | 98 | tablespace_map = makeStringInfo();
|
97 | 99 | MemoryContextSwitchTo(oldcontext);
|
98 | 100 |
|
@@ -157,12 +159,13 @@ pg_backup_stop(PG_FUNCTION_ARGS)
|
157 | 159 | values[2] = CStringGetTextDatum(tablespace_map->data);
|
158 | 160 |
|
159 | 161 | /* Deallocate backup-related variables */
|
160 |
| - pfree(backup_state); |
| 162 | + pfree(backup_label); |
| 163 | + |
| 164 | + /* Clean up the session-level state and its memory context */ |
161 | 165 | backup_state = NULL;
|
162 |
| - pfree(tablespace_map->data); |
163 |
| - pfree(tablespace_map); |
164 | 166 | tablespace_map = NULL;
|
165 |
| - pfree(backup_label); |
| 167 | + MemoryContextDelete(backupcontext); |
| 168 | + backupcontext = NULL; |
166 | 169 |
|
167 | 170 | /* Returns the record as Datum */
|
168 | 171 | PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls)));
|
|
0 commit comments