diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index f13f9c1..c4bc332 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -505,10 +505,13 @@ typedef struct XLogCtlInsert * of streaming base backups currently in progress. forcePageWrites is set * to true when either of these is non-zero. lastBackupStart is the latest * checkpoint redo location used as a starting point for an online backup. + * exclusiveBackupStarted is true while pg_start_backup() is being called + * during an exclusive backup. */ bool exclusiveBackup; int nonExclusiveBackups; XLogRecPtr lastBackupStart; + bool exclusiveBackupStarted; /* * WAL insertion locks. @@ -9833,7 +9836,8 @@ do_pg_start_backup(const char *backupidstr, bool fast, TimeLineID *starttli_p, WALInsertLockAcquireExclusive(); if (exclusive) { - if (XLogCtl->Insert.exclusiveBackup) + if (XLogCtl->Insert.exclusiveBackup || + XLogCtl->Insert.exclusiveBackupStarted) { WALInsertLockRelease(); ereport(ERROR, @@ -9842,6 +9846,7 @@ do_pg_start_backup(const char *backupidstr, bool fast, TimeLineID *starttli_p, errhint("Run pg_stop_backup() and try again."))); } XLogCtl->Insert.exclusiveBackup = true; + XLogCtl->Insert.exclusiveBackupStarted = true; } else XLogCtl->Insert.nonExclusiveBackups++; @@ -10178,6 +10183,16 @@ do_pg_start_backup(const char *backupidstr, bool fast, TimeLineID *starttli_p, PG_END_ENSURE_ERROR_CLEANUP(pg_start_backup_callback, (Datum) BoolGetDatum(exclusive)); /* + * Mark that start phase has correctly finished for an exclusive backup. + */ + if (exclusive) + { + WALInsertLockAcquireExclusive(); + XLogCtl->Insert.exclusiveBackupStarted = false; + WALInsertLockRelease(); + } + + /* * We're done. As a convenience, return the starting WAL location. */ if (starttli_p) @@ -10195,8 +10210,10 @@ pg_start_backup_callback(int code, Datum arg) WALInsertLockAcquireExclusive(); if (exclusive) { - Assert(XLogCtl->Insert.exclusiveBackup); + Assert(XLogCtl->Insert.exclusiveBackup && + XLogCtl->Insert.exclusiveBackupStarted); XLogCtl->Insert.exclusiveBackup = false; + XLogCtl->Insert.exclusiveBackupStarted = false; } else { @@ -10287,6 +10304,13 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p) (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("exclusive backup not in progress"))); } + if (XLogCtl->Insert.exclusiveBackupStarted) + { + WALInsertLockRelease(); + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("exclusive backup currently starting"))); + } XLogCtl->Insert.exclusiveBackup = false; } else