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

Commit 3a04f53

Browse files
committed
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.
1 parent 39bed3b commit 3a04f53

File tree

1 file changed

+28
-33
lines changed
  • src/backend/access/transam

1 file changed

+28
-33
lines changed

src/backend/access/transam/xlog.c

+28-33
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.240 2006/06/18 18:30:20 tgl Exp $
10+
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.241 2006/06/22 20:42:57 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -460,7 +460,7 @@ static bool InRedo = false;
460460

461461
static void XLogArchiveNotify(const char *xlog);
462462
static void XLogArchiveNotifySeg(uint32 log, uint32 seg);
463-
static bool XLogArchiveIsDone(const char *xlog);
463+
static bool XLogArchiveCheckDone(const char *xlog);
464464
static void XLogArchiveCleanup(const char *xlog);
465465
static void readRecoveryCommandFile(void);
466466
static void exitArchiveRecovery(TimeLineID endTLI,
@@ -484,7 +484,7 @@ static bool RestoreArchivedFile(char *path, const char *xlogfname,
484484
static int PreallocXlogFiles(XLogRecPtr endptr);
485485
static void MoveOfflineLogs(uint32 log, uint32 seg, XLogRecPtr endptr,
486486
int *nsegsremoved, int *nsegsrecycled);
487-
static void RemoveOldBackupHistory(void);
487+
static void CleanupBackupHistory(void);
488488
static XLogRecord *ReadRecord(XLogRecPtr *RecPtr, int emode);
489489
static bool ValidXLOGHeader(XLogPageHeader hdr, int emode);
490490
static XLogRecord *ReadCheckpointRecord(XLogRecPtr RecPtr, int whichChkpt);
@@ -1109,24 +1109,30 @@ XLogArchiveNotifySeg(uint32 log, uint32 seg)
11091109
}
11101110

11111111
/*
1112-
* XLogArchiveIsDone
1112+
* XLogArchiveCheckDone
11131113
*
1114-
* Checks for a ".done" archive notification file. This is called when we
1115-
* are ready to delete or recycle an old XLOG segment file. If it is okay
1116-
* to delete it then return true.
1114+
* This is called when we are ready to delete or recycle an old XLOG segment
1115+
* file or backup history file. If it is okay to delete it then return true.
1116+
* If it is not time to delete it, make sure a .ready file exists, and return
1117+
* false.
11171118
*
11181119
* If <XLOG>.done exists, then return true; else if <XLOG>.ready exists,
1119-
* then return false; else create <XLOG>.ready and return false. The
1120-
* last case covers the possibility that the original attempt to create
1121-
* <XLOG>.ready failed.
1120+
* then return false; else create <XLOG>.ready and return false.
1121+
*
1122+
* The reason we do things this way is so that if the original attempt to
1123+
* create <XLOG>.ready fails, we'll retry during subsequent checkpoints.
11221124
*/
11231125
static bool
1124-
XLogArchiveIsDone(const char *xlog)
1126+
XLogArchiveCheckDone(const char *xlog)
11251127
{
11261128
char archiveStatusPath[MAXPGPATH];
11271129
struct stat stat_buf;
11281130

1129-
/* First check for .done --- this is the expected case */
1131+
/* Always deletable if archiving is off */
1132+
if (!XLogArchivingActive())
1133+
return true;
1134+
1135+
/* First check for .done --- this means archiver is done with it */
11301136
StatusFilePath(archiveStatusPath, xlog, ".done");
11311137
if (stat(archiveStatusPath, &stat_buf) == 0)
11321138
return true;
@@ -2438,14 +2444,7 @@ MoveOfflineLogs(uint32 log, uint32 seg, XLogRecPtr endptr,
24382444
strspn(xlde->d_name, "0123456789ABCDEF") == 24 &&
24392445
strcmp(xlde->d_name + 8, lastoff + 8) <= 0)
24402446
{
2441-
bool recycle;
2442-
2443-
if (XLogArchivingActive())
2444-
recycle = XLogArchiveIsDone(xlde->d_name);
2445-
else
2446-
recycle = true;
2447-
2448-
if (recycle)
2447+
if (XLogArchiveCheckDone(xlde->d_name))
24492448
{
24502449
snprintf(path, MAXPGPATH, XLOGDIR "/%s", xlde->d_name);
24512450

@@ -2487,10 +2486,12 @@ MoveOfflineLogs(uint32 log, uint32 seg, XLogRecPtr endptr,
24872486
}
24882487

24892488
/*
2490-
* Remove previous backup history files
2489+
* Remove previous backup history files. This also retries creation of
2490+
* .ready files for any backup history files for which XLogArchiveNotify
2491+
* failed earlier.
24912492
*/
24922493
static void
2493-
RemoveOldBackupHistory(void)
2494+
CleanupBackupHistory(void)
24942495
{
24952496
DIR *xldir;
24962497
struct dirent *xlde;
@@ -2510,8 +2511,7 @@ RemoveOldBackupHistory(void)
25102511
strcmp(xlde->d_name + strlen(xlde->d_name) - strlen(".backup"),
25112512
".backup") == 0)
25122513
{
2513-
/* Remove any *.backup files that have been archived. */
2514-
if (!XLogArchivingActive() || XLogArchiveIsDone(xlde->d_name))
2514+
if (XLogArchiveCheckDone(xlde->d_name))
25152515
{
25162516
ereport(DEBUG2,
25172517
(errmsg("removing transaction log backup history file \"%s\"",
@@ -5968,17 +5968,12 @@ pg_stop_backup(PG_FUNCTION_ARGS)
59685968
errmsg("could not remove file \"%s\": %m",
59695969
BACKUP_LABEL_FILE)));
59705970

5971-
RemoveOldBackupHistory();
5972-
59735971
/*
5974-
* Notify archiver that history file may be archived immediately
5972+
* Clean out any no-longer-needed history files. As a side effect,
5973+
* this will post a .ready file for the newly created history file,
5974+
* notifying the archiver that history file may be archived immediately.
59755975
*/
5976-
if (XLogArchivingActive())
5977-
{
5978-
BackupHistoryFileName(histfilepath, ThisTimeLineID, _logId, _logSeg,
5979-
startpoint.xrecoff % XLogSegSize);
5980-
XLogArchiveNotify(histfilepath);
5981-
}
5976+
CleanupBackupHistory();
59825977

59835978
/*
59845979
* We're done. As a convenience, return the ending WAL offset.

0 commit comments

Comments
 (0)