summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2006-06-22 20:43:20 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2006-06-22 20:43:20 +0000
commit1c718dd8bffe9dcdf38b5a10991f4e1067e4821d (patch)
tree4daaba293b2ee7b2b1ba5df3b37f341e49567d4a
parent62ae14545b35798fcb51bfd0aa9b5038ad6a07ff (diff)
downloadpostgresql-1c718dd8bffe9dcdf38b5a10991f4e1067e4821d.tar.gz
pg_stop_backup was calling XLogArchiveNotify() twice for the newly created
backup history file. Bug introduced by the 8.1 change to make pg_stop_backup delete older history files. Per report from Masao Fujii.
-rw-r--r--src/backend/access/transam/xlog.c61
1 files changed, 28 insertions, 33 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index c20025f38b..e7e55ce4d5 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.222.2.3 2006/03/28 22:01:25 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.222.2.4 2006/06/22 20:43:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -459,7 +459,7 @@ static bool InRedo = false;
static void XLogArchiveNotify(const char *xlog);
static void XLogArchiveNotifySeg(uint32 log, uint32 seg);
-static bool XLogArchiveIsDone(const char *xlog);
+static bool XLogArchiveCheckDone(const char *xlog);
static void XLogArchiveCleanup(const char *xlog);
static void readRecoveryCommandFile(void);
static void exitArchiveRecovery(TimeLineID endTLI,
@@ -482,7 +482,7 @@ static bool RestoreArchivedFile(char *path, const char *xlogfname,
static int PreallocXlogFiles(XLogRecPtr endptr);
static void MoveOfflineLogs(uint32 log, uint32 seg, XLogRecPtr endptr,
int *nsegsremoved, int *nsegsrecycled);
-static void RemoveOldBackupHistory(void);
+static void CleanupBackupHistory(void);
static XLogRecord *ReadRecord(XLogRecPtr *RecPtr, int emode);
static bool ValidXLOGHeader(XLogPageHeader hdr, int emode);
static XLogRecord *ReadCheckpointRecord(XLogRecPtr RecPtr, int whichChkpt);
@@ -1071,24 +1071,30 @@ XLogArchiveNotifySeg(uint32 log, uint32 seg)
}
/*
- * XLogArchiveIsDone
+ * XLogArchiveCheckDone
*
- * Checks for a ".done" archive notification file. This is called when we
- * are ready to delete or recycle an old XLOG segment file. If it is okay
- * to delete it then return true.
+ * This is called when we are ready to delete or recycle an old XLOG segment
+ * file or backup history file. If it is okay to delete it then return true.
+ * If it is not time to delete it, make sure a .ready file exists, and return
+ * false.
*
* If <XLOG>.done exists, then return true; else if <XLOG>.ready exists,
- * then return false; else create <XLOG>.ready and return false. The
- * last case covers the possibility that the original attempt to create
- * <XLOG>.ready failed.
+ * then return false; else create <XLOG>.ready and return false.
+ *
+ * The reason we do things this way is so that if the original attempt to
+ * create <XLOG>.ready fails, we'll retry during subsequent checkpoints.
*/
static bool
-XLogArchiveIsDone(const char *xlog)
+XLogArchiveCheckDone(const char *xlog)
{
char archiveStatusPath[MAXPGPATH];
struct stat stat_buf;
- /* First check for .done --- this is the expected case */
+ /* Always deletable if archiving is off */
+ if (!XLogArchivingActive())
+ return true;
+
+ /* First check for .done --- this means archiver is done with it */
StatusFilePath(archiveStatusPath, xlog, ".done");
if (stat(archiveStatusPath, &stat_buf) == 0)
return true;
@@ -2383,14 +2389,7 @@ MoveOfflineLogs(uint32 log, uint32 seg, XLogRecPtr endptr,
strspn(xlde->d_name, "0123456789ABCDEF") == 24 &&
strcmp(xlde->d_name + 8, lastoff + 8) <= 0)
{
- bool recycle;
-
- if (XLogArchivingActive())
- recycle = XLogArchiveIsDone(xlde->d_name);
- else
- recycle = true;
-
- if (recycle)
+ if (XLogArchiveCheckDone(xlde->d_name))
{
snprintf(path, MAXPGPATH, XLOGDIR "/%s", xlde->d_name);
@@ -2432,10 +2431,12 @@ MoveOfflineLogs(uint32 log, uint32 seg, XLogRecPtr endptr,
}
/*
- * Remove previous backup history files
+ * Remove previous backup history files. This also retries creation of
+ * .ready files for any backup history files for which XLogArchiveNotify
+ * failed earlier.
*/
static void
-RemoveOldBackupHistory(void)
+CleanupBackupHistory(void)
{
DIR *xldir;
struct dirent *xlde;
@@ -2455,8 +2456,7 @@ RemoveOldBackupHistory(void)
strcmp(xlde->d_name + strlen(xlde->d_name) - strlen(".backup"),
".backup") == 0)
{
- /* Remove any *.backup files that have been archived. */
- if (!XLogArchivingActive() || XLogArchiveIsDone(xlde->d_name))
+ if (XLogArchiveCheckDone(xlde->d_name))
{
ereport(DEBUG2,
(errmsg("removing transaction log backup history file \"%s\"",
@@ -5824,17 +5824,12 @@ pg_stop_backup(PG_FUNCTION_ARGS)
errmsg("could not remove file \"%s\": %m",
BACKUP_LABEL_FILE)));
- RemoveOldBackupHistory();
-
/*
- * Notify archiver that history file may be archived immediately
+ * Clean out any no-longer-needed history files. As a side effect,
+ * this will post a .ready file for the newly created history file,
+ * notifying the archiver that history file may be archived immediately.
*/
- if (XLogArchivingActive())
- {
- BackupHistoryFileName(histfilepath, ThisTimeLineID, _logId, _logSeg,
- startpoint.xrecoff % XLogSegSize);
- XLogArchiveNotify(histfilepath);
- }
+ CleanupBackupHistory();
/*
* We're done. As a convenience, return the ending WAL offset.