7
7
* Portions Copyright (c) 1996-2008, 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.295 2008/03/25 22:42:42 tgl Exp $
10
+ * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.296 2008/04/05 01:34:06 momjian Exp $
11
11
*
12
12
*-------------------------------------------------------------------------
13
13
*/
@@ -382,7 +382,7 @@ static bool InRedo = false;
382
382
383
383
static void XLogArchiveNotify (const char * xlog );
384
384
static void XLogArchiveNotifySeg (uint32 log , uint32 seg );
385
- static bool XLogArchiveCheckDone (const char * xlog );
385
+ static bool XLogArchiveCheckDone (const char * xlog , bool create_if_missing );
386
386
static void XLogArchiveCleanup (const char * xlog );
387
387
static void readRecoveryCommandFile (void );
388
388
static void exitArchiveRecovery (TimeLineID endTLI ,
@@ -1128,7 +1128,7 @@ XLogArchiveNotifySeg(uint32 log, uint32 seg)
1128
1128
* create <XLOG>.ready fails, we'll retry during subsequent checkpoints.
1129
1129
*/
1130
1130
static bool
1131
- XLogArchiveCheckDone (const char * xlog )
1131
+ XLogArchiveCheckDone (const char * xlog , bool create_if_missing )
1132
1132
{
1133
1133
char archiveStatusPath [MAXPGPATH ];
1134
1134
struct stat stat_buf ;
@@ -1153,7 +1153,9 @@ XLogArchiveCheckDone(const char *xlog)
1153
1153
return true;
1154
1154
1155
1155
/* Retry creation of the .ready file */
1156
- XLogArchiveNotify (xlog );
1156
+ if (create_if_missing )
1157
+ XLogArchiveNotify (xlog );
1158
+
1157
1159
return false;
1158
1160
}
1159
1161
@@ -2704,7 +2706,7 @@ RemoveOldXlogFiles(uint32 log, uint32 seg, XLogRecPtr endptr)
2704
2706
strspn (xlde -> d_name , "0123456789ABCDEF" ) == 24 &&
2705
2707
strcmp (xlde -> d_name + 8 , lastoff + 8 ) <= 0 )
2706
2708
{
2707
- if (XLogArchiveCheckDone (xlde -> d_name ))
2709
+ if (XLogArchiveCheckDone (xlde -> d_name , true ))
2708
2710
{
2709
2711
snprintf (path , MAXPGPATH , XLOGDIR "/%s" , xlde -> d_name );
2710
2712
@@ -2771,7 +2773,7 @@ CleanupBackupHistory(void)
2771
2773
strcmp (xlde -> d_name + strlen (xlde -> d_name ) - strlen (".backup" ),
2772
2774
".backup" ) == 0 )
2773
2775
{
2774
- if (XLogArchiveCheckDone (xlde -> d_name ))
2776
+ if (XLogArchiveCheckDone (xlde -> d_name , true ))
2775
2777
{
2776
2778
ereport (DEBUG2 ,
2777
2779
(errmsg ("removing transaction log backup history file \"%s\"" ,
@@ -6556,6 +6558,8 @@ pg_stop_backup(PG_FUNCTION_ARGS)
6556
6558
FILE * fp ;
6557
6559
char ch ;
6558
6560
int ich ;
6561
+ int seconds_before_warning ;
6562
+ int waits = 0 ;
6559
6563
6560
6564
if (!superuser ())
6561
6565
ereport (ERROR ,
@@ -6659,6 +6663,39 @@ pg_stop_backup(PG_FUNCTION_ARGS)
6659
6663
*/
6660
6664
CleanupBackupHistory ();
6661
6665
6666
+ /*
6667
+ * Wait until the history file has been archived. We assume that the
6668
+ * alphabetic sorting property of the WAL files ensures the last WAL
6669
+ * file is guaranteed archived by the time the history file is archived.
6670
+ *
6671
+ * We wait forever, since archive_command is supposed to work and
6672
+ * we assume the admin wanted his backup to work completely. If you
6673
+ * don't wish to wait, you can SET statement_timeout = xx;
6674
+ *
6675
+ * If the status file is missing, we assume that is because it was
6676
+ * set to .ready before we slept, then while asleep it has been set
6677
+ * to .done and then removed by a concurrent checkpoint.
6678
+ */
6679
+ BackupHistoryFileName (histfilepath , ThisTimeLineID , _logId , _logSeg ,
6680
+ startpoint .xrecoff % XLogSegSize );
6681
+
6682
+ seconds_before_warning = 60 ;
6683
+ waits = 0 ;
6684
+
6685
+ while (!XLogArchiveCheckDone (histfilepath , false))
6686
+ {
6687
+ CHECK_FOR_INTERRUPTS ();
6688
+
6689
+ pg_usleep (1000000L );
6690
+
6691
+ if (++ waits >= seconds_before_warning )
6692
+ {
6693
+ seconds_before_warning *= 2 ; /* This wraps in >10 years... */
6694
+ elog (WARNING , "pg_stop_backup() waiting for archive to complete "
6695
+ "(%d seconds delay)" , waits );
6696
+ }
6697
+ }
6698
+
6662
6699
/*
6663
6700
* We're done. As a convenience, return the ending WAL location.
6664
6701
*/
0 commit comments