Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 52f8a59

Browse files
committed
Make pg_stop_backup's wait_for_archive flag work on standbys.
Previously, it had no effect. Now, if archive_mode=always, it will work, and if not, you'll get a warning. Masahiko Sawada, Michael Paquier, and Robert Haas. The patch as submitted also changed the behavior so that we would write and remove history files on standbys, but that seems like material for a separate patch to me. Discussion: http://postgr.es/m/CAD21AoC2Xw6M=ZJyejq_9d_iDkReC_=rpvQRw5QsyzKQdfYpkw@mail.gmail.com
1 parent eccead9 commit 52f8a59

File tree

3 files changed

+81
-67
lines changed

3 files changed

+81
-67
lines changed

doc/src/sgml/backup.sgml

+9-4
Original file line numberDiff line numberDiff line change
@@ -1012,10 +1012,15 @@ SELECT pg_start_backup('label', true);
10121012
<programlisting>
10131013
SELECT pg_stop_backup();
10141014
</programlisting>
1015-
This terminates the backup mode and performs an automatic switch to
1016-
the next WAL segment. The reason for the switch is to arrange for
1017-
the last WAL segment file written during the backup interval to be
1018-
ready to archive.
1015+
This function, when called on a primary, terminates the backup mode and
1016+
performs an automatic switch to the next WAL segment. The reason for the
1017+
switch is to arrange for the last WAL segment written during the backup
1018+
interval to be ready to archive. When called on a standby, this function
1019+
only terminates backup mode. A subsequent WAL segment switch will be
1020+
needed in order to ensure that all WAL files needed to restore the backup
1021+
can be archived; if the primary does not have sufficient write activity
1022+
to trigger one, <function>pg_switch_wal</function> should be executed on
1023+
the primary.
10191024
</para>
10201025
</listitem>
10211026
<listitem>

doc/src/sgml/func.sgml

+6-1
Original file line numberDiff line numberDiff line change
@@ -18597,7 +18597,12 @@ postgres=# select pg_start_backup('label_goes_here');
1859718597
WAL to be archived. This behavior is only useful for backup
1859818598
software which independently monitors WAL archiving. Otherwise, WAL
1859918599
required to make the backup consistent might be missing and make the backup
18600-
useless.
18600+
useless. When this parameter is set to true, <function>pg_stop_backup</>
18601+
will wait for WAL to be archived when archiving is enabled; on the standby,
18602+
this means that it will wait only when <varname>archive_mode = always</>.
18603+
If write activity on the primary is low, it may be useful to run
18604+
<function>pg_switch_wal</> on the primary in order to trigger
18605+
an immediate segment switch.
1860118606
</para>
1860218607

1860318608
<para>

src/backend/access/transam/xlog.c

+66-62
Original file line numberDiff line numberDiff line change
@@ -10880,11 +10880,13 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p)
1088010880
* backup. We have no way of checking if pg_control wasn't backed up last
1088110881
* however.
1088210882
*
10883-
* We don't force a switch to new WAL file and wait for all the required
10884-
* files to be archived. This is okay if we use the backup to start the
10885-
* standby. But, if it's for an archive recovery, to ensure all the
10886-
* required files are available, a user should wait for them to be
10887-
* archived, or include them into the backup.
10883+
* We don't force a switch to new WAL file but it is still possible to
10884+
* wait for all the required files to be archived if waitforarchive is
10885+
* true. This is okay if we use the backup to start a standby and fetch
10886+
* the missing WAL using streaming replication. But in the case of an
10887+
* archive recovery, a user should set waitforarchive to true and wait for
10888+
* them to be archived to ensure that all the required files are
10889+
* available.
1088810890
*
1088910891
* We return the current minimum recovery point as the backup end
1089010892
* location. Note that it can be greater than the exact backup end
@@ -10924,66 +10926,65 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p)
1092410926
stoppoint = ControlFile->minRecoveryPoint;
1092510927
stoptli = ControlFile->minRecoveryPointTLI;
1092610928
LWLockRelease(ControlFileLock);
10927-
10928-
if (stoptli_p)
10929-
*stoptli_p = stoptli;
10930-
return stoppoint;
1093110929
}
10930+
else
10931+
{
10932+
/*
10933+
* Write the backup-end xlog record
10934+
*/
10935+
XLogBeginInsert();
10936+
XLogRegisterData((char *) (&startpoint), sizeof(startpoint));
10937+
stoppoint = XLogInsert(RM_XLOG_ID, XLOG_BACKUP_END);
10938+
stoptli = ThisTimeLineID;
1093210939

10933-
/*
10934-
* Write the backup-end xlog record
10935-
*/
10936-
XLogBeginInsert();
10937-
XLogRegisterData((char *) (&startpoint), sizeof(startpoint));
10938-
stoppoint = XLogInsert(RM_XLOG_ID, XLOG_BACKUP_END);
10939-
stoptli = ThisTimeLineID;
10940-
10941-
/*
10942-
* Force a switch to a new xlog segment file, so that the backup is valid
10943-
* as soon as archiver moves out the current segment file.
10944-
*/
10945-
RequestXLogSwitch(false);
10940+
/*
10941+
* Force a switch to a new xlog segment file, so that the backup is
10942+
* valid as soon as archiver moves out the current segment file.
10943+
*/
10944+
RequestXLogSwitch(false);
1094610945

10947-
XLByteToPrevSeg(stoppoint, _logSegNo);
10948-
XLogFileName(stopxlogfilename, ThisTimeLineID, _logSegNo);
10946+
XLByteToPrevSeg(stoppoint, _logSegNo);
10947+
XLogFileName(stopxlogfilename, stoptli, _logSegNo);
1094910948

10950-
/* Use the log timezone here, not the session timezone */
10951-
stamp_time = (pg_time_t) time(NULL);
10952-
pg_strftime(strfbuf, sizeof(strfbuf),
10953-
"%Y-%m-%d %H:%M:%S %Z",
10954-
pg_localtime(&stamp_time, log_timezone));
10949+
/* Use the log timezone here, not the session timezone */
10950+
stamp_time = (pg_time_t) time(NULL);
10951+
pg_strftime(strfbuf, sizeof(strfbuf),
10952+
"%Y-%m-%d %H:%M:%S %Z",
10953+
pg_localtime(&stamp_time, log_timezone));
1095510954

10956-
/*
10957-
* Write the backup history file
10958-
*/
10959-
XLByteToSeg(startpoint, _logSegNo);
10960-
BackupHistoryFilePath(histfilepath, ThisTimeLineID, _logSegNo,
10961-
(uint32) (startpoint % XLogSegSize));
10962-
fp = AllocateFile(histfilepath, "w");
10963-
if (!fp)
10964-
ereport(ERROR,
10965-
(errcode_for_file_access(),
10966-
errmsg("could not create file \"%s\": %m",
10967-
histfilepath)));
10968-
fprintf(fp, "START WAL LOCATION: %X/%X (file %s)\n",
10969-
(uint32) (startpoint >> 32), (uint32) startpoint, startxlogfilename);
10970-
fprintf(fp, "STOP WAL LOCATION: %X/%X (file %s)\n",
10971-
(uint32) (stoppoint >> 32), (uint32) stoppoint, stopxlogfilename);
10972-
/* transfer remaining lines from label to history file */
10973-
fprintf(fp, "%s", remaining);
10974-
fprintf(fp, "STOP TIME: %s\n", strfbuf);
10975-
if (fflush(fp) || ferror(fp) || FreeFile(fp))
10976-
ereport(ERROR,
10977-
(errcode_for_file_access(),
10978-
errmsg("could not write file \"%s\": %m",
10979-
histfilepath)));
10955+
/*
10956+
* Write the backup history file
10957+
*/
10958+
XLByteToSeg(startpoint, _logSegNo);
10959+
BackupHistoryFilePath(histfilepath, stoptli, _logSegNo,
10960+
(uint32) (startpoint % XLogSegSize));
10961+
fp = AllocateFile(histfilepath, "w");
10962+
if (!fp)
10963+
ereport(ERROR,
10964+
(errcode_for_file_access(),
10965+
errmsg("could not create file \"%s\": %m",
10966+
histfilepath)));
10967+
fprintf(fp, "START WAL LOCATION: %X/%X (file %s)\n",
10968+
(uint32) (startpoint >> 32), (uint32) startpoint, startxlogfilename);
10969+
fprintf(fp, "STOP WAL LOCATION: %X/%X (file %s)\n",
10970+
(uint32) (stoppoint >> 32), (uint32) stoppoint, stopxlogfilename);
10971+
/* transfer remaining lines from label to history file */
10972+
fprintf(fp, "%s", remaining);
10973+
fprintf(fp, "STOP TIME: %s\n", strfbuf);
10974+
if (fflush(fp) || ferror(fp) || FreeFile(fp))
10975+
ereport(ERROR,
10976+
(errcode_for_file_access(),
10977+
errmsg("could not write file \"%s\": %m",
10978+
histfilepath)));
1098010979

10981-
/*
10982-
* Clean out any no-longer-needed history files. As a side effect, this
10983-
* will post a .ready file for the newly created history file, notifying
10984-
* the archiver that history file may be archived immediately.
10985-
*/
10986-
CleanupBackupHistory();
10980+
/*
10981+
* Clean out any no-longer-needed history files. As a side effect,
10982+
* this will post a .ready file for the newly created history file,
10983+
* notifying the archiver that history file may be archived
10984+
* immediately.
10985+
*/
10986+
CleanupBackupHistory();
10987+
}
1098710988

1098810989
/*
1098910990
* If archiving is enabled, wait for all the required WAL files to be
@@ -11005,13 +11006,16 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p)
1100511006
* or you can set statement_timeout. Also, some notices are issued to
1100611007
* clue in anyone who might be doing this interactively.
1100711008
*/
11008-
if (waitforarchive && XLogArchivingActive())
11009+
11010+
if (waitforarchive &&
11011+
((!backup_started_in_recovery && XLogArchivingActive()) ||
11012+
(backup_started_in_recovery && XLogArchivingAlways())))
1100911013
{
1101011014
XLByteToPrevSeg(stoppoint, _logSegNo);
11011-
XLogFileName(lastxlogfilename, ThisTimeLineID, _logSegNo);
11015+
XLogFileName(lastxlogfilename, stoptli, _logSegNo);
1101211016

1101311017
XLByteToSeg(startpoint, _logSegNo);
11014-
BackupHistoryFileName(histfilename, ThisTimeLineID, _logSegNo,
11018+
BackupHistoryFileName(histfilename, stoptli, _logSegNo,
1101511019
(uint32) (startpoint % XLogSegSize));
1101611020

1101711021
seconds_before_warning = 60;

0 commit comments

Comments
 (0)