On Fri, Jul 7, 2017 at 3:48 PM, Michael Paquier <michael.paqu...@gmail.com> wrote: > On Wed, Jul 5, 2017 at 4:57 PM, Michael Paquier > <michael.paqu...@gmail.com> wrote: >> Why not refactoring a bit do_pg_stop_backup() so as the wait phase >> happens even if a backup is started in recovery? Now wait_for_archive >> is ignored because no wait is happening and the stop point is directly >> returned back to the caller. For the wait actually happening, I don't >> have a better idea than documenting the fact that enforcing manually a >> segment switch on the primary needs to happen. That's better than >> having users including WAL in their base backups but not actually >> having everything they need. And I think that documenting that >> properly is better than restricting things that should work. > > While looking at that in more details, I got surprised by two things: > 1) No backup history file is generated on a standby during a base backup. > 2) Because of 1), those files are not archived even if archive_mode = always. > > This sounds to me like a missing optimization of archive_mode = > always, and the following comment block in xlog.c is at least > incorrect as an archiver can be invoked in recovery: > * 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 > * an archiver is not invoked. So it doesn't seem worthwhile to write a > * backup history file during recovery. > > So I would suggest the following things to address this issue: > 1) Generate a backup history file for backups taken at recovery as well. > 2) Archive it if archive_mode = always. > 3) Wait for both the segment of the stop point and the backup history > files to be archived before returning back to the caller of > pg_stop_backup. > > It would be nice to get all that addressed in 10. Thoughts?
Yeah, I agree. Attached patch makes it works and deals with the history file issue. Regards, -- Masahiko Sawada NIPPON TELEGRAPH AND TELEPHONE CORPORATION NTT Open Source Software Center
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 3631922..eb47742 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -18594,10 +18594,12 @@ postgres=# select pg_start_backup('label_goes_here'); backup (and not in the data directory). There is an optional second parameter of type <type>boolean</type>. If false, the <function>pg_stop_backup</> will return immediately after the backup is completed without waiting for - WAL to be archived. This behavior is only useful for backup - software which independently monitors WAL archiving. Otherwise, WAL - required to make the backup consistent might be missing and make the backup - useless. + WAL to be archived. This behavior is only useful for backup software + which independently monitors WAL archiving. Otherwise, WAL required to + make the backup consistent might be missing and make the backup useless. + If second parameter is true and on standby, <function>pg_stop_backup</> + waits for WAL to be archived without forcibly switching WAL on standby. + So enforcing manually a WAL switch on primary needs to happen. </para> <para> diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 5b6cec8..8efb174 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -10875,10 +10875,10 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p) * however. * * We don't force a switch to new WAL file and wait for all the required - * files to be archived. This is okay if we use the backup to start the - * standby. But, if it's for an archive recovery, to ensure all the - * required files are available, a user should wait for them to be - * archived, or include them into the backup. + * files to be archived if waitforarchive is false. This is okay if we use + * the backup to start the standby. But, if it's for an archive recovery, + * to ensure all the required files are available, a user should set + * waitforarchive true and wait for them to be archived. * * We return the current minimum recovery point as the backup end * location. Note that it can be greater than the exact backup end @@ -10886,10 +10886,7 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p) * pg_control. This is harmless for current uses. * * 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 - * an archiver is not invoked. So it doesn't seem worthwhile to write a - * backup history file during recovery. + * purposes only. It's not essential for an online backup. */ if (backup_started_in_recovery) { @@ -10919,39 +10916,40 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p) stoptli = ControlFile->minRecoveryPointTLI; LWLockRelease(ControlFileLock); - if (stoptli_p) - *stoptli_p = stoptli; - return stoppoint; + XLByteToPrevSeg(stoppoint, _logSegNo); + XLogFileName(stopxlogfilename, ThisTimeLineID, _logSegNo); } + else + { + /* + * Write the backup-end xlog record + */ + XLogBeginInsert(); + XLogRegisterData((char *) (&startpoint), sizeof(startpoint)); + stoppoint = XLogInsert(RM_XLOG_ID, XLOG_BACKUP_END); + stoptli = ThisTimeLineID; - /* - * Write the backup-end xlog record - */ - XLogBeginInsert(); - XLogRegisterData((char *) (&startpoint), sizeof(startpoint)); - stoppoint = XLogInsert(RM_XLOG_ID, XLOG_BACKUP_END); - stoptli = ThisTimeLineID; - - /* - * Force a switch to a new xlog segment file, so that the backup is valid - * as soon as archiver moves out the current segment file. - */ - RequestXLogSwitch(false); + /* + * Force a switch to a new xlog segment file, so that the backup is valid + * as soon as archiver moves out the current segment file. + */ + RequestXLogSwitch(false); - XLByteToPrevSeg(stoppoint, _logSegNo); - XLogFileName(stopxlogfilename, ThisTimeLineID, _logSegNo); + XLByteToPrevSeg(stoppoint, _logSegNo); + XLogFileName(stopxlogfilename, ThisTimeLineID, _logSegNo); - /* Use the log timezone here, not the session timezone */ - stamp_time = (pg_time_t) time(NULL); - pg_strftime(strfbuf, sizeof(strfbuf), - "%Y-%m-%d %H:%M:%S %Z", - pg_localtime(&stamp_time, log_timezone)); + /* Use the log timezone here, not the session timezone */ + stamp_time = (pg_time_t) time(NULL); + pg_strftime(strfbuf, sizeof(strfbuf), + "%Y-%m-%d %H:%M:%S %Z", + pg_localtime(&stamp_time, log_timezone)); + } /* * Write the backup history file */ XLByteToSeg(startpoint, _logSegNo); - BackupHistoryFilePath(histfilepath, ThisTimeLineID, _logSegNo, + BackupHistoryFilePath(histfilepath, stoptli, _logSegNo, (uint32) (startpoint % XLogSegSize)); fp = AllocateFile(histfilepath, "w"); if (!fp) @@ -11002,10 +11000,10 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p) if (waitforarchive && XLogArchivingActive()) { XLByteToPrevSeg(stoppoint, _logSegNo); - XLogFileName(lastxlogfilename, ThisTimeLineID, _logSegNo); + XLogFileName(lastxlogfilename, stoptli, _logSegNo); XLByteToSeg(startpoint, _logSegNo); - BackupHistoryFileName(histfilename, ThisTimeLineID, _logSegNo, + BackupHistoryFileName(histfilename, stoptli, _logSegNo, (uint32) (startpoint % XLogSegSize)); seconds_before_warning = 60;
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers