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
461461static void XLogArchiveNotify (const char * xlog );
462462static void XLogArchiveNotifySeg (uint32 log ,uint32 seg );
463- static bool XLogArchiveIsDone (const char * xlog );
463+ static bool XLogArchiveCheckDone (const char * xlog );
464464static void XLogArchiveCleanup (const char * xlog );
465465static void readRecoveryCommandFile (void );
466466static void exitArchiveRecovery (TimeLineID endTLI ,
@@ -484,7 +484,7 @@ static bool RestoreArchivedFile(char *path, const char *xlogfname,
484484static int PreallocXlogFiles (XLogRecPtr endptr );
485485static void MoveOfflineLogs (uint32 log ,uint32 seg ,XLogRecPtr endptr ,
486486int * nsegsremoved ,int * nsegsrecycled );
487- static void RemoveOldBackupHistory (void );
487+ static void CleanupBackupHistory (void );
488488static XLogRecord * ReadRecord (XLogRecPtr * RecPtr ,int emode );
489489static bool ValidXLOGHeader (XLogPageHeader hdr ,int emode );
490490static 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 */
11231125static bool
1124- XLogArchiveIsDone (const char * xlog )
1126+ XLogArchiveCheckDone (const char * xlog )
11251127{
11261128char archiveStatusPath [MAXPGPATH ];
11271129struct 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 */
11301136StatusFilePath (archiveStatusPath ,xlog ,".done" );
11311137if (stat (archiveStatusPath ,& stat_buf )== 0 )
11321138return true;
@@ -2438,14 +2444,7 @@ MoveOfflineLogs(uint32 log, uint32 seg, XLogRecPtr endptr,
24382444strspn (xlde -> d_name ,"0123456789ABCDEF" )== 24 &&
24392445strcmp (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{
24502449snprintf (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 */
24922493static void
2493- RemoveOldBackupHistory (void )
2494+ CleanupBackupHistory (void )
24942495{
24952496DIR * xldir ;
24962497struct dirent * xlde ;
@@ -2510,8 +2511,7 @@ RemoveOldBackupHistory(void)
25102511strcmp (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{
25162516ereport (DEBUG2 ,
25172517(errmsg ("removing transaction log backup history file \"%s\"" ,
@@ -5968,17 +5968,12 @@ pg_stop_backup(PG_FUNCTION_ARGS)
59685968errmsg ("could not remove file \"%s\": %m" ,
59695969BACKUP_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.