mirror of
https://github.com/postgres/postgres.git
synced 2025-04-22 23:02:54 +03:00
Have pg_stop_backup() wait for all archive files to be sent, rather than
returing right away. This guarantees that when pg_stop_backup() returns, you have a valid backup. Simon Riggs
This commit is contained in:
parent
a0fad9762a
commit
2a1cf97c22
@ -1,4 +1,4 @@
|
|||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/backup.sgml,v 2.116 2008/03/28 15:00:28 heikki Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/backup.sgml,v 2.117 2008/04/05 01:34:05 momjian Exp $ -->
|
||||||
|
|
||||||
<chapter id="backup">
|
<chapter id="backup">
|
||||||
<title>Backup and Restore</title>
|
<title>Backup and Restore</title>
|
||||||
@ -761,12 +761,19 @@ SELECT pg_stop_backup();
|
|||||||
<para>
|
<para>
|
||||||
Once the WAL segment files used during the backup are archived, you are
|
Once the WAL segment files used during the backup are archived, you are
|
||||||
done. The file identified by <function>pg_stop_backup</>'s result is
|
done. The file identified by <function>pg_stop_backup</>'s result is
|
||||||
the last segment that needs to be archived to complete the backup.
|
the last segment that is required to form a complete set of backup files.
|
||||||
Archival of these files will happen automatically, since you have
|
<function>pg_stop_backup</> does not return until the last segment has
|
||||||
already configured <varname>archive_command</>. In many cases, this
|
been archived.
|
||||||
happens fairly quickly, but you are advised to monitor your archival
|
Archiving of these files happens automatically since you have
|
||||||
system to ensure this has taken place so that you can be certain you
|
already configured <varname>archive_command</>. In most cases this
|
||||||
have a complete backup.
|
happens quickly, but you are advised to monitor your archive
|
||||||
|
system to ensure there are no delays.
|
||||||
|
If the archive process has fallen behind
|
||||||
|
because of failures of the archive command, it will keep retrying
|
||||||
|
until the archive succeeds and the backup is complete.
|
||||||
|
If you wish to place a time limit on the execution of
|
||||||
|
<function>pg_stop_backup</>, set an appropriate
|
||||||
|
<varname>statement_timeout</varname> value.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</orderedlist>
|
</orderedlist>
|
||||||
@ -1044,7 +1051,7 @@ restore_command = 'cp /mnt/server/archivedir/%f %p'
|
|||||||
<note>
|
<note>
|
||||||
<para>
|
<para>
|
||||||
The stop point must be after the ending time of the base backup, i.e.,
|
The stop point must be after the ending time of the base backup, i.e.,
|
||||||
the time of <function>pg_stop_backup</>. You cannot use a base backup
|
the end time of <function>pg_stop_backup</>. You cannot use a base backup
|
||||||
to recover to a time when that backup was still going on. (To
|
to recover to a time when that backup was still going on. (To
|
||||||
recover to such a time, you must go back to your previous base backup
|
recover to such a time, you must go back to your previous base backup
|
||||||
and roll forward from there.)
|
and roll forward from there.)
|
||||||
@ -1322,6 +1329,7 @@ tar -rf /var/lib/pgsql/backup.tar /var/lib/pgsql/archive/
|
|||||||
After the backup the switch file is removed. Archived WAL files are
|
After the backup the switch file is removed. Archived WAL files are
|
||||||
then added to the backup so that both base backup and all required
|
then added to the backup so that both base backup and all required
|
||||||
WAL files are part of the same <application>tar</> file.
|
WAL files are part of the same <application>tar</> file.
|
||||||
|
Please remember to add error handling to your backup scripts.
|
||||||
</para>
|
</para>
|
||||||
</sect3>
|
</sect3>
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.295 2008/03/25 22:42:42 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.296 2008/04/05 01:34:06 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -382,7 +382,7 @@ static bool InRedo = false;
|
|||||||
|
|
||||||
static void XLogArchiveNotify(const char *xlog);
|
static void XLogArchiveNotify(const char *xlog);
|
||||||
static void XLogArchiveNotifySeg(uint32 log, uint32 seg);
|
static void XLogArchiveNotifySeg(uint32 log, uint32 seg);
|
||||||
static bool XLogArchiveCheckDone(const char *xlog);
|
static bool XLogArchiveCheckDone(const char *xlog, bool create_if_missing);
|
||||||
static void XLogArchiveCleanup(const char *xlog);
|
static void XLogArchiveCleanup(const char *xlog);
|
||||||
static void readRecoveryCommandFile(void);
|
static void readRecoveryCommandFile(void);
|
||||||
static void exitArchiveRecovery(TimeLineID endTLI,
|
static void exitArchiveRecovery(TimeLineID endTLI,
|
||||||
@ -1128,7 +1128,7 @@ XLogArchiveNotifySeg(uint32 log, uint32 seg)
|
|||||||
* create <XLOG>.ready fails, we'll retry during subsequent checkpoints.
|
* create <XLOG>.ready fails, we'll retry during subsequent checkpoints.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
XLogArchiveCheckDone(const char *xlog)
|
XLogArchiveCheckDone(const char *xlog, bool create_if_missing)
|
||||||
{
|
{
|
||||||
char archiveStatusPath[MAXPGPATH];
|
char archiveStatusPath[MAXPGPATH];
|
||||||
struct stat stat_buf;
|
struct stat stat_buf;
|
||||||
@ -1153,7 +1153,9 @@ XLogArchiveCheckDone(const char *xlog)
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* Retry creation of the .ready file */
|
/* Retry creation of the .ready file */
|
||||||
XLogArchiveNotify(xlog);
|
if (create_if_missing)
|
||||||
|
XLogArchiveNotify(xlog);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2704,7 +2706,7 @@ RemoveOldXlogFiles(uint32 log, uint32 seg, XLogRecPtr endptr)
|
|||||||
strspn(xlde->d_name, "0123456789ABCDEF") == 24 &&
|
strspn(xlde->d_name, "0123456789ABCDEF") == 24 &&
|
||||||
strcmp(xlde->d_name + 8, lastoff + 8) <= 0)
|
strcmp(xlde->d_name + 8, lastoff + 8) <= 0)
|
||||||
{
|
{
|
||||||
if (XLogArchiveCheckDone(xlde->d_name))
|
if (XLogArchiveCheckDone(xlde->d_name, true))
|
||||||
{
|
{
|
||||||
snprintf(path, MAXPGPATH, XLOGDIR "/%s", xlde->d_name);
|
snprintf(path, MAXPGPATH, XLOGDIR "/%s", xlde->d_name);
|
||||||
|
|
||||||
@ -2771,7 +2773,7 @@ CleanupBackupHistory(void)
|
|||||||
strcmp(xlde->d_name + strlen(xlde->d_name) - strlen(".backup"),
|
strcmp(xlde->d_name + strlen(xlde->d_name) - strlen(".backup"),
|
||||||
".backup") == 0)
|
".backup") == 0)
|
||||||
{
|
{
|
||||||
if (XLogArchiveCheckDone(xlde->d_name))
|
if (XLogArchiveCheckDone(xlde->d_name, true))
|
||||||
{
|
{
|
||||||
ereport(DEBUG2,
|
ereport(DEBUG2,
|
||||||
(errmsg("removing transaction log backup history file \"%s\"",
|
(errmsg("removing transaction log backup history file \"%s\"",
|
||||||
@ -6556,6 +6558,8 @@ pg_stop_backup(PG_FUNCTION_ARGS)
|
|||||||
FILE *fp;
|
FILE *fp;
|
||||||
char ch;
|
char ch;
|
||||||
int ich;
|
int ich;
|
||||||
|
int seconds_before_warning;
|
||||||
|
int waits = 0;
|
||||||
|
|
||||||
if (!superuser())
|
if (!superuser())
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
@ -6659,6 +6663,39 @@ pg_stop_backup(PG_FUNCTION_ARGS)
|
|||||||
*/
|
*/
|
||||||
CleanupBackupHistory();
|
CleanupBackupHistory();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wait until the history file has been archived. We assume that the
|
||||||
|
* alphabetic sorting property of the WAL files ensures the last WAL
|
||||||
|
* file is guaranteed archived by the time the history file is archived.
|
||||||
|
*
|
||||||
|
* We wait forever, since archive_command is supposed to work and
|
||||||
|
* we assume the admin wanted his backup to work completely. If you
|
||||||
|
* don't wish to wait, you can SET statement_timeout = xx;
|
||||||
|
*
|
||||||
|
* If the status file is missing, we assume that is because it was
|
||||||
|
* set to .ready before we slept, then while asleep it has been set
|
||||||
|
* to .done and then removed by a concurrent checkpoint.
|
||||||
|
*/
|
||||||
|
BackupHistoryFileName(histfilepath, ThisTimeLineID, _logId, _logSeg,
|
||||||
|
startpoint.xrecoff % XLogSegSize);
|
||||||
|
|
||||||
|
seconds_before_warning = 60;
|
||||||
|
waits = 0;
|
||||||
|
|
||||||
|
while (!XLogArchiveCheckDone(histfilepath, false))
|
||||||
|
{
|
||||||
|
CHECK_FOR_INTERRUPTS();
|
||||||
|
|
||||||
|
pg_usleep(1000000L);
|
||||||
|
|
||||||
|
if (++waits >= seconds_before_warning)
|
||||||
|
{
|
||||||
|
seconds_before_warning *= 2; /* This wraps in >10 years... */
|
||||||
|
elog(WARNING, "pg_stop_backup() waiting for archive to complete "
|
||||||
|
"(%d seconds delay)", waits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We're done. As a convenience, return the ending WAL location.
|
* We're done. As a convenience, return the ending WAL location.
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user