@@ -37,28 +37,58 @@ static PGresult *HandleCopyStream(PGconn *conn, XLogRecPtr startpos,
37
37
uint32 timeline , char * basedir ,
38
38
stream_stop_callback stream_stop , int standby_message_timeout ,
39
39
char * partial_suffix , XLogRecPtr * stoppos ,
40
- bool synchronous );
40
+ bool synchronous , bool mark_done );
41
41
static int CopyStreamPoll (PGconn * conn , long timeout_ms );
42
42
static int CopyStreamReceive (PGconn * conn , long timeout , char * * buffer );
43
43
static bool ProcessKeepaliveMsg (PGconn * conn , char * copybuf , int len ,
44
44
XLogRecPtr blockpos , int64 * last_status );
45
45
static bool ProcessXLogDataMsg (PGconn * conn , char * copybuf , int len ,
46
46
XLogRecPtr * blockpos , uint32 timeline ,
47
47
char * basedir , stream_stop_callback stream_stop ,
48
- char * partial_suffix );
48
+ char * partial_suffix , bool mark_done );
49
49
static PGresult * HandleEndOfCopyStream (PGconn * conn , char * copybuf ,
50
50
XLogRecPtr blockpos , char * basedir , char * partial_suffix ,
51
- XLogRecPtr * stoppos );
51
+ XLogRecPtr * stoppos , bool mark_done );
52
52
static bool CheckCopyStreamStop (PGconn * conn , XLogRecPtr blockpos ,
53
53
uint32 timeline , char * basedir ,
54
54
stream_stop_callback stream_stop ,
55
- char * partial_suffix , XLogRecPtr * stoppos );
55
+ char * partial_suffix , XLogRecPtr * stoppos ,
56
+ bool mark_done );
56
57
static long CalculateCopyStreamSleeptime (int64 now , int standby_message_timeout ,
57
58
int64 last_status );
58
59
59
60
static bool ReadEndOfStreamingResult (PGresult * res , XLogRecPtr * startpos ,
60
61
uint32 * timeline );
61
62
63
+ static bool
64
+ mark_file_as_archived (const char * basedir , const char * fname )
65
+ {
66
+ int fd ;
67
+ static char tmppath [MAXPGPATH ];
68
+
69
+ snprintf (tmppath , sizeof (tmppath ), "%s/archive_status/%s.done" ,
70
+ basedir , fname );
71
+
72
+ fd = open (tmppath , O_WRONLY | O_CREAT | PG_BINARY , S_IRUSR | S_IWUSR );
73
+ if (fd < 0 )
74
+ {
75
+ fprintf (stderr , _ ("%s: could not create archive status file \"%s\": %s\n" ),
76
+ progname , tmppath , strerror (errno ));
77
+ return false;
78
+ }
79
+
80
+ if (fsync (fd ) != 0 )
81
+ {
82
+ fprintf (stderr , _ ("%s: could not fsync file \"%s\": %s\n" ),
83
+ progname , tmppath , strerror (errno ));
84
+ return false;
85
+ }
86
+
87
+ close (fd );
88
+
89
+ return true;
90
+ }
91
+
62
92
/*
63
93
* Open a new WAL file in the specified directory.
64
94
*
@@ -152,7 +182,7 @@ open_walfile(XLogRecPtr startpoint, uint32 timeline, char *basedir,
152
182
* and returns false, otherwise returns true.
153
183
*/
154
184
static bool
155
- close_walfile (char * basedir , char * partial_suffix , XLogRecPtr pos )
185
+ close_walfile (char * basedir , char * partial_suffix , XLogRecPtr pos , bool mark_done )
156
186
{
157
187
off_t currpos ;
158
188
@@ -206,6 +236,19 @@ close_walfile(char *basedir, char *partial_suffix, XLogRecPtr pos)
206
236
_ ("%s: not renaming \"%s%s\", segment is not complete\n" ),
207
237
progname , current_walfile_name , partial_suffix );
208
238
239
+ /*
240
+ * Mark file as archived if requested by the caller - pg_basebackup needs
241
+ * to do so as files can otherwise get archived again after promotion of a
242
+ * new node. This is in line with walreceiver.c always doing a
243
+ * XLogArchiveForceDone() after a complete segment.
244
+ */
245
+ if (currpos == XLOG_SEG_SIZE && mark_done )
246
+ {
247
+ /* writes error message if failed */
248
+ if (!mark_file_as_archived (basedir , current_walfile_name ))
249
+ return false;
250
+ }
251
+
209
252
lastFlushPosition = pos ;
210
253
return true;
211
254
}
@@ -248,7 +291,8 @@ existsTimeLineHistoryFile(char *basedir, TimeLineID tli)
248
291
}
249
292
250
293
static bool
251
- writeTimeLineHistoryFile (char * basedir , TimeLineID tli , char * filename , char * content )
294
+ writeTimeLineHistoryFile (char * basedir , TimeLineID tli , char * filename ,
295
+ char * content , bool mark_done )
252
296
{
253
297
int size = strlen (content );
254
298
char path [MAXPGPATH ];
@@ -327,6 +371,14 @@ writeTimeLineHistoryFile(char *basedir, TimeLineID tli, char *filename, char *co
327
371
return false;
328
372
}
329
373
374
+ /* Maintain archive_status, check close_walfile() for details. */
375
+ if (mark_done )
376
+ {
377
+ /* writes error message if failed */
378
+ if (!mark_file_as_archived (basedir , histfname ))
379
+ return false;
380
+ }
381
+
330
382
return true;
331
383
}
332
384
@@ -447,7 +499,7 @@ ReceiveXlogStream(PGconn *conn, XLogRecPtr startpos, uint32 timeline,
447
499
char * sysidentifier , char * basedir ,
448
500
stream_stop_callback stream_stop ,
449
501
int standby_message_timeout , char * partial_suffix ,
450
- bool synchronous )
502
+ bool synchronous , bool mark_done )
451
503
{
452
504
char query [128 ];
453
505
char slotcmd [128 ];
@@ -562,7 +614,8 @@ ReceiveXlogStream(PGconn *conn, XLogRecPtr startpos, uint32 timeline,
562
614
/* Write the history file to disk */
563
615
writeTimeLineHistoryFile (basedir , timeline ,
564
616
PQgetvalue (res , 0 , 0 ),
565
- PQgetvalue (res , 0 , 1 ));
617
+ PQgetvalue (res , 0 , 1 ),
618
+ mark_done );
566
619
567
620
PQclear (res );
568
621
}
@@ -592,7 +645,7 @@ ReceiveXlogStream(PGconn *conn, XLogRecPtr startpos, uint32 timeline,
592
645
/* Stream the WAL */
593
646
res = HandleCopyStream (conn , startpos , timeline , basedir , stream_stop ,
594
647
standby_message_timeout , partial_suffix ,
595
- & stoppos , synchronous );
648
+ & stoppos , synchronous , mark_done );
596
649
if (res == NULL )
597
650
goto error ;
598
651
@@ -757,7 +810,7 @@ static PGresult *
757
810
HandleCopyStream (PGconn * conn , XLogRecPtr startpos , uint32 timeline ,
758
811
char * basedir , stream_stop_callback stream_stop ,
759
812
int standby_message_timeout , char * partial_suffix ,
760
- XLogRecPtr * stoppos , bool synchronous )
813
+ XLogRecPtr * stoppos , bool synchronous , bool mark_done )
761
814
{
762
815
char * copybuf = NULL ;
763
816
int64 last_status = -1 ;
@@ -775,7 +828,8 @@ HandleCopyStream(PGconn *conn, XLogRecPtr startpos, uint32 timeline,
775
828
* Check if we should continue streaming, or abort at this point.
776
829
*/
777
830
if (!CheckCopyStreamStop (conn , blockpos , timeline , basedir ,
778
- stream_stop , partial_suffix , stoppos ))
831
+ stream_stop , partial_suffix , stoppos ,
832
+ mark_done ))
779
833
goto error ;
780
834
781
835
now = feGetCurrentTimestamp ();
@@ -830,7 +884,8 @@ HandleCopyStream(PGconn *conn, XLogRecPtr startpos, uint32 timeline,
830
884
if (r == -2 )
831
885
{
832
886
PGresult * res = HandleEndOfCopyStream (conn , copybuf , blockpos ,
833
- basedir , partial_suffix , stoppos );
887
+ basedir , partial_suffix ,
888
+ stoppos , mark_done );
834
889
if (res == NULL )
835
890
goto error ;
836
891
else
@@ -847,14 +902,16 @@ HandleCopyStream(PGconn *conn, XLogRecPtr startpos, uint32 timeline,
847
902
else if (copybuf [0 ] == 'w' )
848
903
{
849
904
if (!ProcessXLogDataMsg (conn , copybuf , r , & blockpos ,
850
- timeline , basedir , stream_stop , partial_suffix ))
905
+ timeline , basedir , stream_stop ,
906
+ partial_suffix , true))
851
907
goto error ;
852
908
853
909
/*
854
910
* Check if we should continue streaming, or abort at this point.
855
911
*/
856
912
if (!CheckCopyStreamStop (conn , blockpos , timeline , basedir ,
857
- stream_stop , partial_suffix , stoppos ))
913
+ stream_stop , partial_suffix , stoppos ,
914
+ mark_done ))
858
915
goto error ;
859
916
}
860
917
else
@@ -1055,7 +1112,7 @@ static bool
1055
1112
ProcessXLogDataMsg (PGconn * conn , char * copybuf , int len ,
1056
1113
XLogRecPtr * blockpos , uint32 timeline ,
1057
1114
char * basedir , stream_stop_callback stream_stop ,
1058
- char * partial_suffix )
1115
+ char * partial_suffix , bool mark_done )
1059
1116
{
1060
1117
int xlogoff ;
1061
1118
int bytes_left ;
@@ -1163,7 +1220,7 @@ ProcessXLogDataMsg(PGconn *conn, char *copybuf, int len,
1163
1220
/* Did we reach the end of a WAL segment? */
1164
1221
if (* blockpos % XLOG_SEG_SIZE == 0 )
1165
1222
{
1166
- if (!close_walfile (basedir , partial_suffix , * blockpos ))
1223
+ if (!close_walfile (basedir , partial_suffix , * blockpos , mark_done ))
1167
1224
/* Error message written in close_walfile() */
1168
1225
return false;
1169
1226
@@ -1193,7 +1250,7 @@ ProcessXLogDataMsg(PGconn *conn, char *copybuf, int len,
1193
1250
static PGresult *
1194
1251
HandleEndOfCopyStream (PGconn * conn , char * copybuf ,
1195
1252
XLogRecPtr blockpos , char * basedir , char * partial_suffix ,
1196
- XLogRecPtr * stoppos )
1253
+ XLogRecPtr * stoppos , bool mark_done )
1197
1254
{
1198
1255
PGresult * res = PQgetResult (conn );
1199
1256
@@ -1204,7 +1261,7 @@ HandleEndOfCopyStream(PGconn *conn, char *copybuf,
1204
1261
*/
1205
1262
if (still_sending )
1206
1263
{
1207
- if (!close_walfile (basedir , partial_suffix , blockpos ))
1264
+ if (!close_walfile (basedir , partial_suffix , blockpos , mark_done ))
1208
1265
{
1209
1266
/* Error message written in close_walfile() */
1210
1267
PQclear (res );
@@ -1236,11 +1293,11 @@ HandleEndOfCopyStream(PGconn *conn, char *copybuf,
1236
1293
static bool
1237
1294
CheckCopyStreamStop (PGconn * conn , XLogRecPtr blockpos , uint32 timeline ,
1238
1295
char * basedir , stream_stop_callback stream_stop ,
1239
- char * partial_suffix , XLogRecPtr * stoppos )
1296
+ char * partial_suffix , XLogRecPtr * stoppos , bool mark_done )
1240
1297
{
1241
1298
if (still_sending && stream_stop (blockpos , timeline , false))
1242
1299
{
1243
- if (!close_walfile (basedir , partial_suffix , blockpos ))
1300
+ if (!close_walfile (basedir , partial_suffix , blockpos , mark_done ))
1244
1301
{
1245
1302
/* Potential error message is written by close_walfile */
1246
1303
return false;
0 commit comments