Skip to content

Commit 8232d6d

Browse files
committed
Ensure cleanup in case of early errors in streaming base backups
Move the code that sends the initial status information as well as the calculation of paths inside the ENSURE_ERROR_CLEANUP block. If this code failed, we would "leak" a counter of number of concurrent backups, thereby making the system always believe it was in backup mode. This could happen if the sending failed (which it probably never did given that the small amount of data to send would never cause a flush) or if the psprintf calls ran out of memory. Both are very low risk, but all operations after do_pg_start_backup should be protected.
1 parent c676315 commit 8232d6d

File tree

1 file changed

+18
-11
lines changed

1 file changed

+18
-11
lines changed

src/backend/replication/basebackup.c

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -134,19 +134,12 @@ perform_base_backup(basebackup_options *opt, DIR *tblspcdir)
134134

135135
startptr = do_pg_start_backup(opt->label, opt->fastcheckpoint, &starttli,
136136
&labelfile);
137-
SendXlogRecPtrResult(startptr, starttli);
138-
139137
/*
140-
* Calculate the relative path of temporary statistics directory in order
141-
* to skip the files which are located in that directory later.
138+
* Once do_pg_start_backup has been called, ensure that any failure causes
139+
* us to abort the backup so we don't "leak" a backup counter. For this reason,
140+
* *all* functionality between do_pg_start_backup() and do_pg_stop_backup()
141+
* should be inside the error cleanup block!
142142
*/
143-
if (is_absolute_path(pgstat_stat_directory) &&
144-
strncmp(pgstat_stat_directory, DataDir, datadirpathlen) == 0)
145-
statrelpath = psprintf("./%s", pgstat_stat_directory + datadirpathlen + 1);
146-
else if (strncmp(pgstat_stat_directory, "./", 2) != 0)
147-
statrelpath = psprintf("./%s", pgstat_stat_directory);
148-
else
149-
statrelpath = pgstat_stat_directory;
150143

151144
PG_ENSURE_ERROR_CLEANUP(base_backup_cleanup, (Datum) 0);
152145
{
@@ -155,6 +148,20 @@ perform_base_backup(basebackup_options *opt, DIR *tblspcdir)
155148
struct dirent *de;
156149
tablespaceinfo *ti;
157150

151+
SendXlogRecPtrResult(startptr, starttli);
152+
153+
/*
154+
* Calculate the relative path of temporary statistics directory in order
155+
* to skip the files which are located in that directory later.
156+
*/
157+
if (is_absolute_path(pgstat_stat_directory) &&
158+
strncmp(pgstat_stat_directory, DataDir, datadirpathlen) == 0)
159+
statrelpath = psprintf("./%s", pgstat_stat_directory + datadirpathlen + 1);
160+
else if (strncmp(pgstat_stat_directory, "./", 2) != 0)
161+
statrelpath = psprintf("./%s", pgstat_stat_directory);
162+
else
163+
statrelpath = pgstat_stat_directory;
164+
158165
/* Collect information about all tablespaces */
159166
while ((de = ReadDir(tblspcdir, "pg_tblspc")) != NULL)
160167
{

0 commit comments

Comments
 (0)