diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index d6c057a..46d52d3 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -10501,11 +10501,24 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p) * required files are available, a user should wait for them to be * archived, or include them into the backup. * - * We return the current minimum recovery point as the backup end + * We return the current last replayed point as the backup end * location. Note that it can be greater than the exact backup end - * location if the minimum recovery point is updated after the backup of + * location if the last replayed point is updated after the backup of * pg_control. This is harmless for current uses. * + * Using the last replayed point as the backup end location ensures that + * the end location will never be older than the start position, something + * that could happen if for example minRecoveryPoint is used as backup + * end location when it never gets updated because no buffer flushes + * occurred. By using the last replay location, note that the backup may + * include more WAL segments than necessary. If the additional WAL + * replayed since minRecoveryPoint does not include a checkpoint, there + * is actually no need for it. Even if it does include a checkpoint, + * only the portion up to the checkpoint itself is necessary and not + * the WAL generated beyond that. Still, in the case of a backup taken + * from a standby, with its master disconnected, this ensures that the + * backup is valid. + * * XXX currently a backup history file is for informational and debug * purposes only. It's not essential for an online backup. Furthermore, * even if it's created, it will not be archived during recovery because @@ -10522,6 +10535,8 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p) */ SpinLockAcquire(&XLogCtl->info_lck); recptr = XLogCtl->lastFpwDisableRecPtr; + stoppoint = XLogCtl->lastReplayedEndRecPtr; + stoptli = XLogCtl->lastReplayedTLI; SpinLockRelease(&XLogCtl->info_lck); if (startpoint <= recptr) @@ -10534,12 +10549,6 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p) "Enable full_page_writes and run CHECKPOINT on the master, " "and then try an online backup again."))); - - LWLockAcquire(ControlFileLock, LW_SHARED); - stoppoint = ControlFile->minRecoveryPoint; - stoptli = ControlFile->minRecoveryPointTLI; - LWLockRelease(ControlFileLock); - if (stoptli_p) *stoptli_p = stoptli; return stoppoint; diff --git a/src/test/recovery/t/001_stream_rep.pl b/src/test/recovery/t/001_stream_rep.pl index fd71095..981c00b 100644 --- a/src/test/recovery/t/001_stream_rep.pl +++ b/src/test/recovery/t/001_stream_rep.pl @@ -24,6 +24,11 @@ $node_standby_1->start; # pg_basebackup works on a standby). $node_standby_1->backup($backup_name); +# Take a second backup of the standby while the master is offline. +$node_master->stop; +$node_standby_1->backup('my_backup_2'); +$node_master->start; + # Create second standby node linking to standby 1 my $node_standby_2 = get_new_node('standby_2'); $node_standby_2->init_from_backup($node_standby_1, $backup_name,