diff options
author | Magnus Hagander <magnus@hagander.net> | 2014-05-28 12:40:45 +0200 |
---|---|---|
committer | Magnus Hagander <magnus@hagander.net> | 2014-05-28 12:43:29 +0200 |
commit | 8232d6df4c943a30c08e65d7ea893cb762bc5612 (patch) | |
tree | bd6db015a83e5437522adb9dc19369b1f52fdf5f /src | |
parent | c676315658973390c5550d73d3bb1fb7b92720b5 (diff) | |
download | postgresql-8232d6df4c943a30c08e65d7ea893cb762bc5612.tar.gz postgresql-8232d6df4c943a30c08e65d7ea893cb762bc5612.zip |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/replication/basebackup.c | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/src/backend/replication/basebackup.c b/src/backend/replication/basebackup.c index a3bf5001ec8..b387612c090 100644 --- a/src/backend/replication/basebackup.c +++ b/src/backend/replication/basebackup.c @@ -134,19 +134,12 @@ perform_base_backup(basebackup_options *opt, DIR *tblspcdir) startptr = do_pg_start_backup(opt->label, opt->fastcheckpoint, &starttli, &labelfile); - SendXlogRecPtrResult(startptr, starttli); - /* - * Calculate the relative path of temporary statistics directory in order - * to skip the files which are located in that directory later. + * Once do_pg_start_backup has been called, ensure that any failure causes + * us to abort the backup so we don't "leak" a backup counter. For this reason, + * *all* functionality between do_pg_start_backup() and do_pg_stop_backup() + * should be inside the error cleanup block! */ - if (is_absolute_path(pgstat_stat_directory) && - strncmp(pgstat_stat_directory, DataDir, datadirpathlen) == 0) - statrelpath = psprintf("./%s", pgstat_stat_directory + datadirpathlen + 1); - else if (strncmp(pgstat_stat_directory, "./", 2) != 0) - statrelpath = psprintf("./%s", pgstat_stat_directory); - else - statrelpath = pgstat_stat_directory; PG_ENSURE_ERROR_CLEANUP(base_backup_cleanup, (Datum) 0); { @@ -155,6 +148,20 @@ perform_base_backup(basebackup_options *opt, DIR *tblspcdir) struct dirent *de; tablespaceinfo *ti; + SendXlogRecPtrResult(startptr, starttli); + + /* + * Calculate the relative path of temporary statistics directory in order + * to skip the files which are located in that directory later. + */ + if (is_absolute_path(pgstat_stat_directory) && + strncmp(pgstat_stat_directory, DataDir, datadirpathlen) == 0) + statrelpath = psprintf("./%s", pgstat_stat_directory + datadirpathlen + 1); + else if (strncmp(pgstat_stat_directory, "./", 2) != 0) + statrelpath = psprintf("./%s", pgstat_stat_directory); + else + statrelpath = pgstat_stat_directory; + /* Collect information about all tablespaces */ while ((de = ReadDir(tblspcdir, "pg_tblspc")) != NULL) { |