diff options
author | Teodor Sigaev <teodor@sigaev.ru> | 2017-03-24 13:53:40 +0300 |
---|---|---|
committer | Teodor Sigaev <teodor@sigaev.ru> | 2017-03-24 13:53:40 +0300 |
commit | 78874531baf99769468dedfff19aa7e2068bc5e5 (patch) | |
tree | ab0fc9106324635b142052430035f6dc4de0d576 /src/backend/access/transam/xlogfuncs.c | |
parent | 457a4448732881b5008f7a3bcca76fc299075ac3 (diff) | |
download | postgresql-78874531baf99769468dedfff19aa7e2068bc5e5.tar.gz postgresql-78874531baf99769468dedfff19aa7e2068bc5e5.zip |
Fix backup canceling
Assert-enabled build crashes but without asserts it works by wrong way:
it may not reset forcing full page write and preventing from starting
exclusive backup with the same name as cancelled.
Patch replaces pair of booleans
nonexclusive_backup_running/exclusive_backup_running to single enum to
correctly describe backup state.
Backpatch to 9.6 where bug was introduced
Reported-by: David Steele
Authors: Michael Paquier, David Steele
Reviewed-by: Anastasia Lubennikova
https://commitfest.postgresql.org/13/1068/
Diffstat (limited to 'src/backend/access/transam/xlogfuncs.c')
-rw-r--r-- | src/backend/access/transam/xlogfuncs.c | 25 |
1 files changed, 10 insertions, 15 deletions
diff --git a/src/backend/access/transam/xlogfuncs.c b/src/backend/access/transam/xlogfuncs.c index 5073aaca84f..5041f0e2a94 100644 --- a/src/backend/access/transam/xlogfuncs.c +++ b/src/backend/access/transam/xlogfuncs.c @@ -42,8 +42,6 @@ */ static StringInfo label_file; static StringInfo tblspc_map_file; -static bool exclusive_backup_running = false; -static bool nonexclusive_backup_running = false; /* * Called when the backend exits with a running non-exclusive base backup, @@ -78,10 +76,11 @@ pg_start_backup(PG_FUNCTION_ARGS) char *backupidstr; XLogRecPtr startpoint; DIR *dir; + SessionBackupState status = get_backup_status(); backupidstr = text_to_cstring(backupid); - if (exclusive_backup_running || nonexclusive_backup_running) + if (status == SESSION_BACKUP_NON_EXCLUSIVE) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("a backup is already in progress in this session"))); @@ -96,7 +95,6 @@ pg_start_backup(PG_FUNCTION_ARGS) { startpoint = do_pg_start_backup(backupidstr, fast, NULL, NULL, dir, NULL, NULL, false, true); - exclusive_backup_running = true; } else { @@ -113,7 +111,6 @@ pg_start_backup(PG_FUNCTION_ARGS) startpoint = do_pg_start_backup(backupidstr, fast, NULL, label_file, dir, NULL, tblspc_map_file, false, true); - nonexclusive_backup_running = true; before_shmem_exit(nonexclusive_base_backup_cleanup, (Datum) 0); } @@ -147,8 +144,9 @@ Datum pg_stop_backup(PG_FUNCTION_ARGS) { XLogRecPtr stoppoint; + SessionBackupState status = get_backup_status(); - if (nonexclusive_backup_running) + if (status == SESSION_BACKUP_NON_EXCLUSIVE) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("non-exclusive backup in progress"), @@ -156,14 +154,12 @@ pg_stop_backup(PG_FUNCTION_ARGS) /* * Exclusive backups were typically started in a different connection, so - * don't try to verify that exclusive_backup_running is set in this one. - * Actual verification that an exclusive backup is in fact running is - * handled inside do_pg_stop_backup. + * 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); - exclusive_backup_running = false; - PG_RETURN_LSN(stoppoint); } @@ -199,6 +195,7 @@ pg_stop_backup_v2(PG_FUNCTION_ARGS) bool exclusive = PG_GETARG_BOOL(0); bool waitforarchive = PG_GETARG_BOOL(1); XLogRecPtr stoppoint; + SessionBackupState status = get_backup_status(); /* check to see if caller supports us returning a tuplestore */ if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo)) @@ -230,7 +227,7 @@ pg_stop_backup_v2(PG_FUNCTION_ARGS) if (exclusive) { - if (nonexclusive_backup_running) + if (status == SESSION_BACKUP_NON_EXCLUSIVE) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("non-exclusive backup in progress"), @@ -241,14 +238,13 @@ pg_stop_backup_v2(PG_FUNCTION_ARGS) * return NULL for both backup_label and tablespace_map. */ stoppoint = do_pg_stop_backup(NULL, waitforarchive, NULL); - exclusive_backup_running = false; nulls[1] = true; nulls[2] = true; } else { - if (!nonexclusive_backup_running) + if (status != SESSION_BACKUP_NON_EXCLUSIVE) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("non-exclusive backup is not in progress"), @@ -259,7 +255,6 @@ pg_stop_backup_v2(PG_FUNCTION_ARGS) * and tablespace map so they can be written to disk by the caller. */ stoppoint = do_pg_stop_backup(label_file->data, waitforarchive, NULL); - nonexclusive_backup_running = false; cancel_before_shmem_exit(nonexclusive_base_backup_cleanup, (Datum) 0); values[1] = CStringGetTextDatum(label_file->data); |