From 15979957334de59b21082ce1029cad240e937d99 Mon Sep 17 00:00:00 2001 From: Asif Rehman Date: Wed, 30 Oct 2019 10:21:38 +0500 Subject: [PATCH 1/7] remove PG_ENSURE_ERROR_CLEANUP macro from basebackup. register base_backup_cleanup with before_shmem_exit handler. This will make sure that call is always made when wal sender exits. --- src/backend/replication/basebackup.c | 182 +++++++++++++-------------- 1 file changed, 90 insertions(+), 92 deletions(-) diff --git a/src/backend/replication/basebackup.c b/src/backend/replication/basebackup.c index 1fa4551eff..71a8b4fb4c 100644 --- a/src/backend/replication/basebackup.c +++ b/src/backend/replication/basebackup.c @@ -243,6 +243,8 @@ perform_base_backup(basebackup_options *opt) StringInfo tblspc_map_file = NULL; int datadirpathlen; List *tablespaces = NIL; + ListCell *lc; + tablespaceinfo *ti; datadirpathlen = strlen(DataDir); @@ -261,121 +263,117 @@ perform_base_backup(basebackup_options *opt) /* * 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 the end of - * do_pg_stop_backup() should be inside the error cleanup block! + * reason, register base_backup_cleanup with before_shmem_exit handler. This + * will make sure that call is always made when process exits. In success, + * do_pg_stop_backup will have taken the system out of backup mode and this + * callback will have no effect, Otherwise the required cleanup will be done + * in any case. */ + before_shmem_exit(base_backup_cleanup, (Datum) 0); - PG_ENSURE_ERROR_CLEANUP(base_backup_cleanup, (Datum) 0); - { - ListCell *lc; - tablespaceinfo *ti; - - SendXlogRecPtrResult(startptr, starttli); + 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; - - /* Add a node for the base directory at the end */ - ti = palloc0(sizeof(tablespaceinfo)); - ti->size = opt->progress ? sendDir(".", 1, true, tablespaces, true) : -1; - tablespaces = lappend(tablespaces, ti); + /* + * 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; - /* Send tablespace header */ - SendBackupHeader(tablespaces); + /* Add a node for the base directory at the end */ + ti = palloc0(sizeof(tablespaceinfo)); + ti->size = opt->progress ? sendDir(".", 1, true, tablespaces, true) : -1; + tablespaces = lappend(tablespaces, ti); - /* Setup and activate network throttling, if client requested it */ - if (opt->maxrate > 0) - { - throttling_sample = - (int64) opt->maxrate * (int64) 1024 / THROTTLING_FREQUENCY; + /* Send tablespace header */ + SendBackupHeader(tablespaces); - /* - * The minimum amount of time for throttling_sample bytes to be - * transferred. - */ - elapsed_min_unit = USECS_PER_SEC / THROTTLING_FREQUENCY; - - /* Enable throttling. */ - throttling_counter = 0; + /* Setup and activate network throttling, if client requested it */ + if (opt->maxrate > 0) + { + throttling_sample = + (int64) opt->maxrate * (int64) 1024 / THROTTLING_FREQUENCY; - /* The 'real data' starts now (header was ignored). */ - throttled_last = GetCurrentTimestamp(); - } - else - { - /* Disable throttling. */ - throttling_counter = -1; - } + /* + * The minimum amount of time for throttling_sample bytes to be + * transferred. + */ + elapsed_min_unit = USECS_PER_SEC / THROTTLING_FREQUENCY; - /* Send off our tablespaces one by one */ - foreach(lc, tablespaces) - { - tablespaceinfo *ti = (tablespaceinfo *) lfirst(lc); - StringInfoData buf; + /* Enable throttling. */ + throttling_counter = 0; - /* Send CopyOutResponse message */ - pq_beginmessage(&buf, 'H'); - pq_sendbyte(&buf, 0); /* overall format */ - pq_sendint16(&buf, 0); /* natts */ - pq_endmessage(&buf); + /* The 'real data' starts now (header was ignored). */ + throttled_last = GetCurrentTimestamp(); + } + else + { + /* Disable throttling. */ + throttling_counter = -1; + } - if (ti->path == NULL) - { - struct stat statbuf; + /* Send off our tablespaces one by one */ + foreach(lc, tablespaces) + { + tablespaceinfo *ti = (tablespaceinfo *) lfirst(lc); + StringInfoData buf; - /* In the main tar, include the backup_label first... */ - sendFileWithContent(BACKUP_LABEL_FILE, labelfile->data); + /* Send CopyOutResponse message */ + pq_beginmessage(&buf, 'H'); + pq_sendbyte(&buf, 0); /* overall format */ + pq_sendint16(&buf, 0); /* natts */ + pq_endmessage(&buf); - /* - * Send tablespace_map file if required and then the bulk of - * the files. - */ - if (tblspc_map_file && opt->sendtblspcmapfile) - { - sendFileWithContent(TABLESPACE_MAP, tblspc_map_file->data); - sendDir(".", 1, false, tablespaces, false); - } - else - sendDir(".", 1, false, tablespaces, true); + if (ti->path == NULL) + { + struct stat statbuf; - /* ... and pg_control after everything else. */ - if (lstat(XLOG_CONTROL_FILE, &statbuf) != 0) - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not stat file \"%s\": %m", - XLOG_CONTROL_FILE))); - sendFile(XLOG_CONTROL_FILE, XLOG_CONTROL_FILE, &statbuf, false, InvalidOid); - } - else - sendTablespace(ti->path, false); + /* In the main tar, include the backup_label first... */ + sendFileWithContent(BACKUP_LABEL_FILE, labelfile->data); /* - * If we're including WAL, and this is the main data directory we - * don't terminate the tar stream here. Instead, we will append - * the xlog files below and terminate it then. This is safe since - * the main data directory is always sent *last*. + * Send tablespace_map file if required and then the bulk of + * the files. */ - if (opt->includewal && ti->path == NULL) + if (tblspc_map_file && opt->sendtblspcmapfile) { - Assert(lnext(tablespaces, lc) == NULL); + sendFileWithContent(TABLESPACE_MAP, tblspc_map_file->data); + sendDir(".", 1, false, tablespaces, false); } else - pq_putemptymessage('c'); /* CopyDone */ + sendDir(".", 1, false, tablespaces, true); + + /* ... and pg_control after everything else. */ + if (lstat(XLOG_CONTROL_FILE, &statbuf) != 0) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not stat file \"%s\": %m", + XLOG_CONTROL_FILE))); + sendFile(XLOG_CONTROL_FILE, XLOG_CONTROL_FILE, &statbuf, false, InvalidOid); } + else + sendTablespace(ti->path, false); - endptr = do_pg_stop_backup(labelfile->data, !opt->nowait, &endtli); + /* + * If we're including WAL, and this is the main data directory we + * don't terminate the tar stream here. Instead, we will append + * the xlog files below and terminate it then. This is safe since + * the main data directory is always sent *last*. + */ + if (opt->includewal && ti->path == NULL) + { + Assert(lnext(tablespaces, lc) == NULL); + } + else + pq_putemptymessage('c'); /* CopyDone */ } - PG_END_ENSURE_ERROR_CLEANUP(base_backup_cleanup, (Datum) 0); + endptr = do_pg_stop_backup(labelfile->data, !opt->nowait, &endtli); if (opt->includewal) { -- 2.21.0 (Apple Git-122.2)