aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/transam/xlogfuncs.c
diff options
context:
space:
mode:
authorMichael Paquier <michael@paquier.xyz>2022-09-26 11:15:47 +0900
committerMichael Paquier <michael@paquier.xyz>2022-09-26 11:15:47 +0900
commit7d708093b7400327658a30d1aa1d5e284d37622c (patch)
treeee2cbc99967484634c55100d4c8399f4452a8cef /src/backend/access/transam/xlogfuncs.c
parent216f9c1ab3a4f333632ce576e1dc1e3643427eb8 (diff)
downloadpostgresql-7d708093b7400327658a30d1aa1d5e284d37622c.tar.gz
postgresql-7d708093b7400327658a30d1aa1d5e284d37622c.zip
Refactor creation of backup_label and backup history files
This change simplifies some of the logic related to the generation and creation of the backup_label and backup history files, which has become unnecessarily complicated since the removal of the exclusive backup mode in commit 39969e2. The code was previously generating the contents of these files as a string (start phase for the backup_label and stop phase for the backup history file), one problem being that the contents of the backup_label string were scanned to grab some of its internal contents at the stop phase. This commit changes the logic so as we store the data required to build these files in an intermediate structure named BackupState. The backup_label file and backup history file strings are generated when they are ready to be sent back to the client. Both files are now generated with the same code path. While on it, this commit renames some variables for clarity. Two new files named xlogbackup.{c,h} are introduced in this commit, to remove from xlog.c some of the logic around base backups. Note that more could be moved to this new set of files. Author: Bharath Rupireddy, Michael Paquier Reviewed-by: Fujii Masao Discussion: https://postgr.es/m/CALj2ACXWwTDgJqCjdaPyfR7djwm6SrybGcrZyrvojzcsmt4FFw@mail.gmail.com
Diffstat (limited to 'src/backend/access/transam/xlogfuncs.c')
-rw-r--r--src/backend/access/transam/xlogfuncs.c96
1 files changed, 60 insertions, 36 deletions
diff --git a/src/backend/access/transam/xlogfuncs.c b/src/backend/access/transam/xlogfuncs.c
index 27aeb6e2819..f724b18733a 100644
--- a/src/backend/access/transam/xlogfuncs.c
+++ b/src/backend/access/transam/xlogfuncs.c
@@ -20,6 +20,7 @@
#include "access/htup_details.h"
#include "access/xlog_internal.h"
+#include "access/xlogbackup.h"
#include "access/xlogrecovery.h"
#include "access/xlogutils.h"
#include "catalog/pg_type.h"
@@ -39,19 +40,16 @@
#include "utils/tuplestore.h"
/*
- * Store label file and tablespace map during backups.
+ * Backup-related variables.
*/
-static StringInfo label_file;
-static StringInfo tblspc_map_file;
+static BackupState *backup_state = NULL;
+static StringInfo tablespace_map = NULL;
/*
* pg_backup_start: set up for taking an on-line backup dump
*
- * Essentially what this does is to create a backup label file in $PGDATA,
- * where it will be archived as part of the backup dump. The label file
- * contains the user-supplied label string (typically this would be used
- * to tell where the backup dump will be stored) and the starting time and
- * starting WAL location for the dump.
+ * Essentially what this does is to create the contents required for the
+ * backup_label file and the tablespace map.
*
* Permission checking for this function is managed through the normal
* GRANT system.
@@ -62,7 +60,6 @@ pg_backup_start(PG_FUNCTION_ARGS)
text *backupid = PG_GETARG_TEXT_PP(0);
bool fast = PG_GETARG_BOOL(1);
char *backupidstr;
- XLogRecPtr startpoint;
SessionBackupState status = get_backup_status();
MemoryContext oldcontext;
@@ -74,20 +71,35 @@ pg_backup_start(PG_FUNCTION_ARGS)
errmsg("a backup is already in progress in this session")));
/*
- * Label file and tablespace map file need to be long-lived, since they
- * are read in pg_backup_stop.
+ * backup_state and tablespace_map need to be long-lived as they are used
+ * in pg_backup_stop().
*/
oldcontext = MemoryContextSwitchTo(TopMemoryContext);
- label_file = makeStringInfo();
- tblspc_map_file = makeStringInfo();
+
+ /* Allocate backup state or reset it, if it comes from a previous run */
+ if (backup_state == NULL)
+ backup_state = (BackupState *) palloc0(sizeof(BackupState));
+ else
+ MemSet(backup_state, 0, sizeof(BackupState));
+
+ /*
+ * tablespace_map may have been created in a previous backup, so take this
+ * occasion to clean it.
+ */
+ if (tablespace_map != NULL)
+ {
+ pfree(tablespace_map->data);
+ pfree(tablespace_map);
+ tablespace_map = NULL;
+ }
+
+ tablespace_map = makeStringInfo();
MemoryContextSwitchTo(oldcontext);
register_persistent_abort_backup_handler();
+ do_pg_backup_start(backupidstr, fast, NULL, backup_state, tablespace_map);
- startpoint = do_pg_backup_start(backupidstr, fast, NULL, label_file,
- NULL, tblspc_map_file);
-
- PG_RETURN_LSN(startpoint);
+ PG_RETURN_LSN(backup_state->startpoint);
}
@@ -98,6 +110,15 @@ pg_backup_start(PG_FUNCTION_ARGS)
* allows the user to choose if they want to wait for the WAL to be archived
* or if we should just return as soon as the WAL record is written.
*
+ * This function stops an in-progress backup, creates backup_label contents and
+ * it returns the backup stop LSN, backup_label and tablespace_map contents.
+ *
+ * The backup_label contains the user-supplied label string (typically this
+ * would be used to tell where the backup dump will be stored), the starting
+ * time, starting WAL location for the dump and so on. It is the caller's
+ * responsibility to write the backup_label and tablespace_map files in the
+ * data folder that will be restored from this backup.
+ *
* Permission checking for this function is managed through the normal
* GRANT system.
*/
@@ -108,9 +129,8 @@ pg_backup_stop(PG_FUNCTION_ARGS)
TupleDesc tupdesc;
Datum values[PG_BACKUP_STOP_V2_COLS] = {0};
bool nulls[PG_BACKUP_STOP_V2_COLS] = {0};
-
bool waitforarchive = PG_GETARG_BOOL(0);
- XLogRecPtr stoppoint;
+ StringInfo backup_label;
SessionBackupState status = get_backup_status();
/* Initialize attributes information in the tuple descriptor */
@@ -123,23 +143,27 @@ pg_backup_stop(PG_FUNCTION_ARGS)
errmsg("backup is not in progress"),
errhint("Did you call pg_backup_start()?")));
- /*
- * Stop the backup. Return a copy of the backup label and tablespace map
- * so they can be written to disk by the caller.
- */
- stoppoint = do_pg_backup_stop(label_file->data, waitforarchive, NULL);
-
- values[0] = LSNGetDatum(stoppoint);
- values[1] = CStringGetTextDatum(label_file->data);
- values[2] = CStringGetTextDatum(tblspc_map_file->data);
-
- /* Free structures allocated in TopMemoryContext */
- pfree(label_file->data);
- pfree(label_file);
- label_file = NULL;
- pfree(tblspc_map_file->data);
- pfree(tblspc_map_file);
- tblspc_map_file = NULL;
+ Assert(backup_state != NULL);
+ Assert(tablespace_map != NULL);
+
+ /* Stop the backup */
+ do_pg_backup_stop(backup_state, waitforarchive);
+
+ /* Build the contents of backup_label */
+ backup_label = build_backup_content(backup_state, false);
+
+ values[0] = LSNGetDatum(backup_state->stoppoint);
+ values[1] = CStringGetTextDatum(backup_label->data);
+ values[2] = CStringGetTextDatum(tablespace_map->data);
+
+ /* Deallocate backup-related variables */
+ pfree(backup_state);
+ backup_state = NULL;
+ pfree(tablespace_map->data);
+ pfree(tablespace_map);
+ tablespace_map = NULL;
+ pfree(backup_label->data);
+ pfree(backup_label);
/* Returns the record as Datum */
PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls)));