7
7
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
8
8
* Portions Copyright (c) 1994, Regents of the University of California
9
9
*
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 $
11
11
*
12
12
*-------------------------------------------------------------------------
13
13
*/
@@ -460,7 +460,7 @@ static bool InRedo = false;
460
460
461
461
static void XLogArchiveNotify (const char * xlog );
462
462
static void XLogArchiveNotifySeg (uint32 log , uint32 seg );
463
- static bool XLogArchiveIsDone (const char * xlog );
463
+ static bool XLogArchiveCheckDone (const char * xlog );
464
464
static void XLogArchiveCleanup (const char * xlog );
465
465
static void readRecoveryCommandFile (void );
466
466
static void exitArchiveRecovery (TimeLineID endTLI ,
@@ -484,7 +484,7 @@ static bool RestoreArchivedFile(char *path, const char *xlogfname,
484
484
static int PreallocXlogFiles (XLogRecPtr endptr );
485
485
static void MoveOfflineLogs (uint32 log , uint32 seg , XLogRecPtr endptr ,
486
486
int * nsegsremoved , int * nsegsrecycled );
487
- static void RemoveOldBackupHistory (void );
487
+ static void CleanupBackupHistory (void );
488
488
static XLogRecord * ReadRecord (XLogRecPtr * RecPtr , int emode );
489
489
static bool ValidXLOGHeader (XLogPageHeader hdr , int emode );
490
490
static XLogRecord * ReadCheckpointRecord (XLogRecPtr RecPtr , int whichChkpt );
@@ -1109,24 +1109,30 @@ XLogArchiveNotifySeg(uint32 log, uint32 seg)
1109
1109
}
1110
1110
1111
1111
/*
1112
- * XLogArchiveIsDone
1112
+ * XLogArchiveCheckDone
1113
1113
*
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.
1117
1118
*
1118
1119
* 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.
1122
1124
*/
1123
1125
static bool
1124
- XLogArchiveIsDone (const char * xlog )
1126
+ XLogArchiveCheckDone (const char * xlog )
1125
1127
{
1126
1128
char archiveStatusPath [MAXPGPATH ];
1127
1129
struct stat stat_buf ;
1128
1130
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 */
1130
1136
StatusFilePath (archiveStatusPath , xlog , ".done" );
1131
1137
if (stat (archiveStatusPath , & stat_buf ) == 0 )
1132
1138
return true;
@@ -2438,14 +2444,7 @@ MoveOfflineLogs(uint32 log, uint32 seg, XLogRecPtr endptr,
2438
2444
strspn (xlde -> d_name , "0123456789ABCDEF" ) == 24 &&
2439
2445
strcmp (xlde -> d_name + 8 , lastoff + 8 ) <= 0 )
2440
2446
{
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 ))
2449
2448
{
2450
2449
snprintf (path , MAXPGPATH , XLOGDIR "/%s" , xlde -> d_name );
2451
2450
@@ -2487,10 +2486,12 @@ MoveOfflineLogs(uint32 log, uint32 seg, XLogRecPtr endptr,
2487
2486
}
2488
2487
2489
2488
/*
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.
2491
2492
*/
2492
2493
static void
2493
- RemoveOldBackupHistory (void )
2494
+ CleanupBackupHistory (void )
2494
2495
{
2495
2496
DIR * xldir ;
2496
2497
struct dirent * xlde ;
@@ -2510,8 +2511,7 @@ RemoveOldBackupHistory(void)
2510
2511
strcmp (xlde -> d_name + strlen (xlde -> d_name ) - strlen (".backup" ),
2511
2512
".backup" ) == 0 )
2512
2513
{
2513
- /* Remove any *.backup files that have been archived. */
2514
- if (!XLogArchivingActive () || XLogArchiveIsDone (xlde -> d_name ))
2514
+ if (XLogArchiveCheckDone (xlde -> d_name ))
2515
2515
{
2516
2516
ereport (DEBUG2 ,
2517
2517
(errmsg ("removing transaction log backup history file \"%s\"" ,
@@ -5968,17 +5968,12 @@ pg_stop_backup(PG_FUNCTION_ARGS)
5968
5968
errmsg ("could not remove file \"%s\": %m" ,
5969
5969
BACKUP_LABEL_FILE )));
5970
5970
5971
- RemoveOldBackupHistory ();
5972
-
5973
5971
/*
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.
5975
5975
*/
5976
- if (XLogArchivingActive ())
5977
- {
5978
- BackupHistoryFileName (histfilepath , ThisTimeLineID , _logId , _logSeg ,
5979
- startpoint .xrecoff % XLogSegSize );
5980
- XLogArchiveNotify (histfilepath );
5981
- }
5976
+ CleanupBackupHistory ();
5982
5977
5983
5978
/*
5984
5979
* We're done. As a convenience, return the ending WAL offset.
0 commit comments