diff options
Diffstat (limited to 'src/backend/access/transam/xlogfuncs.c')
-rw-r--r-- | src/backend/access/transam/xlogfuncs.c | 253 |
1 files changed, 47 insertions, 206 deletions
diff --git a/src/backend/access/transam/xlogfuncs.c b/src/backend/access/transam/xlogfuncs.c index 2752be63c10..b61ae6c0b4a 100644 --- a/src/backend/access/transam/xlogfuncs.c +++ b/src/backend/access/transam/xlogfuncs.c @@ -39,13 +39,13 @@ #include "utils/tuplestore.h" /* - * Store label file and tablespace map during non-exclusive backups. + * Store label file and tablespace map during backups. */ static StringInfo label_file; static StringInfo tblspc_map_file; /* - * pg_start_backup: set up for taking an on-line backup dump + * 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 @@ -57,105 +57,44 @@ static StringInfo tblspc_map_file; * GRANT system. */ Datum -pg_start_backup(PG_FUNCTION_ARGS) +pg_backup_start(PG_FUNCTION_ARGS) { text *backupid = PG_GETARG_TEXT_PP(0); bool fast = PG_GETARG_BOOL(1); - bool exclusive = PG_GETARG_BOOL(2); char *backupidstr; XLogRecPtr startpoint; SessionBackupState status = get_backup_status(); + MemoryContext oldcontext; backupidstr = text_to_cstring(backupid); - if (status == SESSION_BACKUP_NON_EXCLUSIVE) + if (status == SESSION_BACKUP_RUNNING) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("a backup is already in progress in this session"))); - if (exclusive) - { - startpoint = do_pg_start_backup(backupidstr, fast, NULL, NULL, - NULL, NULL); - } - else - { - MemoryContext oldcontext; - - /* - * Label file and tablespace map file need to be long-lived, since - * they are read in pg_stop_backup. - */ - oldcontext = MemoryContextSwitchTo(TopMemoryContext); - label_file = makeStringInfo(); - tblspc_map_file = makeStringInfo(); - MemoryContextSwitchTo(oldcontext); + /* + * Label file and tablespace map file need to be long-lived, since + * they are read in pg_backup_stop. + */ + oldcontext = MemoryContextSwitchTo(TopMemoryContext); + label_file = makeStringInfo(); + tblspc_map_file = makeStringInfo(); + MemoryContextSwitchTo(oldcontext); - register_persistent_abort_backup_handler(); + register_persistent_abort_backup_handler(); - startpoint = do_pg_start_backup(backupidstr, fast, NULL, label_file, - NULL, tblspc_map_file); - } + startpoint = do_pg_backup_start(backupidstr, fast, NULL, label_file, + NULL, tblspc_map_file); PG_RETURN_LSN(startpoint); } -/* - * pg_stop_backup: finish taking an on-line backup dump - * - * We write an end-of-backup WAL record, and remove the backup label file - * created by pg_start_backup, creating a backup history file in pg_wal - * instead (whence it will immediately be archived). The backup history file - * contains the same info found in the label file, plus the backup-end time - * and WAL location. Before 9.0, the backup-end time was read from the backup - * history file at the beginning of archive recovery, but we now use the WAL - * record for that and the file is for informational and debug purposes only. - * - * Note: different from CancelBackup which just cancels online backup mode. - * - * Note: this version is only called to stop an exclusive backup. The function - * pg_stop_backup_v2 (overloaded as pg_stop_backup in SQL) is called to - * stop non-exclusive backups. - * - * Permission checking for this function is managed through the normal - * GRANT system. - */ -Datum -pg_stop_backup(PG_FUNCTION_ARGS) -{ - XLogRecPtr stoppoint; - SessionBackupState status = get_backup_status(); - - if (status == SESSION_BACKUP_NON_EXCLUSIVE) - ereport(ERROR, - (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("non-exclusive backup in progress"), - errhint("Did you mean to use pg_stop_backup('f')?"))); - - /* - * Exclusive backups were typically started in a different connection, so - * don't try to verify that status of backup is set to - * SESSION_BACKUP_EXCLUSIVE in this function. Actual verification that an - * exclusive backup is in fact running is handled inside - * do_pg_stop_backup. - */ - stoppoint = do_pg_stop_backup(NULL, true, NULL); - - PG_RETURN_LSN(stoppoint); -} - /* - * pg_stop_backup_v2: finish taking exclusive or nonexclusive on-line backup. - * - * Works the same as pg_stop_backup, except for non-exclusive backups it returns - * the backup label and tablespace map files as text fields in as part of the - * resultset. + * pg_backup_stop: finish taking an on-line backup. * - * The first parameter (variable 'exclusive') allows the user to tell us if - * this is an exclusive or a non-exclusive backup. - * - * The second parameter (variable 'waitforarchive'), which is optional, + * The first parameter (variable 'waitforarchive'), which is optional, * 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. * @@ -163,15 +102,14 @@ pg_stop_backup(PG_FUNCTION_ARGS) * GRANT system. */ Datum -pg_stop_backup_v2(PG_FUNCTION_ARGS) +pg_backup_stop(PG_FUNCTION_ARGS) { #define PG_STOP_BACKUP_V2_COLS 3 TupleDesc tupdesc; Datum values[PG_STOP_BACKUP_V2_COLS]; bool nulls[PG_STOP_BACKUP_V2_COLS]; - bool exclusive = PG_GETARG_BOOL(0); - bool waitforarchive = PG_GETARG_BOOL(1); + bool waitforarchive = PG_GETARG_BOOL(0); XLogRecPtr stoppoint; SessionBackupState status = get_backup_status(); @@ -182,51 +120,29 @@ pg_stop_backup_v2(PG_FUNCTION_ARGS) MemSet(values, 0, sizeof(values)); MemSet(nulls, 0, sizeof(nulls)); - if (exclusive) - { - if (status == SESSION_BACKUP_NON_EXCLUSIVE) - ereport(ERROR, - (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("non-exclusive backup in progress"), - errhint("Did you mean to use pg_stop_backup('f')?"))); - - /* - * Stop the exclusive backup, and since we're in an exclusive backup - * return NULL for both backup_label and tablespace_map. - */ - stoppoint = do_pg_stop_backup(NULL, waitforarchive, NULL); - - nulls[1] = true; - nulls[2] = true; - } - else - { - if (status != SESSION_BACKUP_NON_EXCLUSIVE) - ereport(ERROR, - (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("non-exclusive backup is not in progress"), - errhint("Did you mean to use pg_stop_backup('t')?"))); + if (status != SESSION_BACKUP_RUNNING) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("backup is not in progress"), + errhint("Did you call pg_backup_start()?"))); - /* - * Stop the non-exclusive backup. Return a copy of the backup label - * and tablespace map so they can be written to disk by the caller. - */ - stoppoint = do_pg_stop_backup(label_file->data, waitforarchive, NULL); - - 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; - } + /* + * 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); - /* Stoppoint is included on both exclusive and nonexclusive backups */ 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; /* Returns the record as Datum */ PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls))); @@ -298,7 +214,7 @@ pg_create_restore_point(PG_FUNCTION_ARGS) } /* - * Report the current WAL write location (same format as pg_start_backup etc) + * Report the current WAL write location (same format as pg_backup_start etc) * * This is useful for determining how much of WAL is visible to an external * archiving process. Note that the data before this point is written out @@ -321,7 +237,7 @@ pg_current_wal_lsn(PG_FUNCTION_ARGS) } /* - * Report the current WAL insert location (same format as pg_start_backup etc) + * Report the current WAL insert location (same format as pg_backup_start etc) * * This function is mostly for debugging purposes. */ @@ -342,7 +258,7 @@ pg_current_wal_insert_lsn(PG_FUNCTION_ARGS) } /* - * Report the current WAL flush location (same format as pg_start_backup etc) + * Report the current WAL flush location (same format as pg_backup_start etc) * * This function is mostly for debugging purposes. */ @@ -363,7 +279,7 @@ pg_current_wal_flush_lsn(PG_FUNCTION_ARGS) } /* - * Report the last WAL receive location (same format as pg_start_backup etc) + * Report the last WAL receive location (same format as pg_backup_start etc) * * This is useful for determining how much of WAL is guaranteed to be received * and synced to disk by walreceiver. @@ -382,7 +298,7 @@ pg_last_wal_receive_lsn(PG_FUNCTION_ARGS) } /* - * Report the last WAL replay location (same format as pg_start_backup etc) + * Report the last WAL replay location (same format as pg_backup_start etc) * * This is useful for determining how much of WAL is visible to read-only * connections during recovery. @@ -402,7 +318,7 @@ pg_last_wal_replay_lsn(PG_FUNCTION_ARGS) /* * Compute an xlog file name and decimal byte offset given a WAL location, - * such as is returned by pg_stop_backup() or pg_switch_wal(). + * such as is returned by pg_backup_stop() or pg_switch_wal(). * * Note that a location exactly at a segment boundary is taken to be in * the previous segment. This is usually the right thing, since the @@ -470,7 +386,7 @@ pg_walfile_name_offset(PG_FUNCTION_ARGS) /* * Compute an xlog file name given a WAL location, - * such as is returned by pg_stop_backup() or pg_switch_wal(). + * such as is returned by pg_backup_stop() or pg_switch_wal(). */ Datum pg_walfile_name(PG_FUNCTION_ARGS) @@ -646,81 +562,6 @@ pg_wal_lsn_diff(PG_FUNCTION_ARGS) } /* - * Returns bool with current on-line backup mode, a global state. - */ -Datum -pg_is_in_backup(PG_FUNCTION_ARGS) -{ - PG_RETURN_BOOL(BackupInProgress()); -} - -/* - * Returns start time of an online exclusive backup. - * - * When there's no exclusive backup in progress, the function - * returns NULL. - */ -Datum -pg_backup_start_time(PG_FUNCTION_ARGS) -{ - Datum xtime; - FILE *lfp; - char fline[MAXPGPATH]; - char backup_start_time[30]; - - /* - * See if label file is present - */ - lfp = AllocateFile(BACKUP_LABEL_FILE, "r"); - if (lfp == NULL) - { - if (errno != ENOENT) - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not read file \"%s\": %m", - BACKUP_LABEL_FILE))); - PG_RETURN_NULL(); - } - - /* - * Parse the file to find the START TIME line. - */ - backup_start_time[0] = '\0'; - while (fgets(fline, sizeof(fline), lfp) != NULL) - { - if (sscanf(fline, "START TIME: %25[^\n]\n", backup_start_time) == 1) - break; - } - - /* Check for a read error. */ - if (ferror(lfp)) - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not read file \"%s\": %m", BACKUP_LABEL_FILE))); - - /* Close the backup label file. */ - if (FreeFile(lfp)) - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not close file \"%s\": %m", BACKUP_LABEL_FILE))); - - if (strlen(backup_start_time) == 0) - ereport(ERROR, - (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE))); - - /* - * Convert the time string read from file to TimestampTz form. - */ - xtime = DirectFunctionCall3(timestamptz_in, - CStringGetDatum(backup_start_time), - ObjectIdGetDatum(InvalidOid), - Int32GetDatum(-1)); - - PG_RETURN_DATUM(xtime); -} - -/* * Promotes a standby server. * * A result of "true" means that promotion has been completed if "wait" is |