@@ -64,9 +64,9 @@ static int checkpoint_timeout(PGconn *backup_conn);
6464static void * StreamLog (void * arg );
6565static bool stop_streaming (XLogRecPtr xlogpos , uint32 timeline ,
6666 bool segment_finished );
67- static void append_wal_segment (parray * filelist , uint32 timeline ,
68- XLogRecPtr xlogpos , char * basedir ,
69- uint32 xlog_seg_size );
67+ static void add_walsegment_to_filelist (parray * filelist , uint32 timeline ,
68+ XLogRecPtr xlogpos , char * basedir ,
69+ uint32 xlog_seg_size );
7070
7171/*
7272 * Run IDENTIFY_SYSTEM through a given connection and
@@ -244,12 +244,16 @@ StreamLog(void *arg)
244244 elog (ERROR , "Problem in receivexlog" );
245245#endif
246246
247- /* sort xlog_files_list */
247+ /* be paranoid and sort xlog_files_list,
248+ * so if stop_lsn segno is already in the list,
249+ * then list must be sorted to detect duplicates.
250+ */
248251 parray_qsort (xlog_files_list , pgFileCompareRelPathWithExternal );
249252
250- append_wal_segment (xlog_files_list , stream_arg -> starttli ,
251- stop_stream_lsn , (char * ) stream_arg -> basedir ,
252- instance_config .xlog_seg_size );
253+ /* Add the last segment to the list */
254+ add_walsegment_to_filelist (xlog_files_list , stream_arg -> starttli ,
255+ stop_stream_lsn , (char * ) stream_arg -> basedir ,
256+ instance_config .xlog_seg_size );
253257
254258 /*
255259 * TODO: remove redundant WAL segments
@@ -295,9 +299,9 @@ stop_streaming(XLogRecPtr xlogpos, uint32 timeline, bool segment_finished)
295299 elog (VERBOSE , _ ("finished segment at %X/%X (timeline %u)" ),
296300 (uint32 ) (xlogpos >> 32 ), (uint32 ) xlogpos , timeline );
297301
298- append_wal_segment (xlog_files_list , timeline , xlogpos ,
299- (char * ) stream_thread_arg .basedir ,
300- instance_config .xlog_seg_size );
302+ add_walsegment_to_filelist (xlog_files_list , timeline , xlogpos ,
303+ (char * ) stream_thread_arg .basedir ,
304+ instance_config .xlog_seg_size );
301305 }
302306
303307 /*
@@ -392,19 +396,22 @@ wait_WAL_streaming_end(parray *backup_files_list)
392396
393397/* Append streamed WAL segment to filelist */
394398void
395- append_wal_segment (parray * filelist , uint32 timeline , XLogRecPtr xlogpos , char * basedir , uint32 xlog_seg_size )
399+ add_walsegment_to_filelist (parray * filelist , uint32 timeline , XLogRecPtr xlogpos , char * basedir , uint32 xlog_seg_size )
396400{
397401 XLogSegNo xlog_segno ;
398402 char wal_segment_name [MAXFNAMELEN ];
399403 char wal_segment_relpath [MAXPGPATH ];
400404 char wal_segment_fullpath [MAXPGPATH ];
401405 pgFile * file = NULL ;
406+ pgFile * * existing_file = NULL ;
402407
403408 GetXLogSegNo (xlogpos , xlog_segno , xlog_seg_size );
404409
405410 /*
406- * xlogpos points to the current segment, and we need the finished - previous one
407- * inless xlogpos points to not 0 offset in segment
411+ * When xlogpos points to the zero offset (0/3000000),
412+ * it means that previous segment was just successfully streamed.
413+ * When xlogpos points to the positive offset,
414+ * then current segment is successfully streamed.
408415 */
409416 if (WalSegmentOffset (xlogpos , xlog_seg_size ) == 0 )
410417 xlog_segno -- ;
@@ -422,11 +429,16 @@ append_wal_segment(parray *filelist, uint32 timeline, XLogRecPtr xlogpos, char *
422429 * stop_lsn segment can be added to this list twice, so
423430 * try not to add duplicates
424431 */
425- if (parray_bsearch (filelist , file , pgFileCompareRelPathWithExternal ))
432+
433+ existing_file = (pgFile * * ) parray_bsearch (filelist , file , pgFileCompareRelPathWithExternal );
434+
435+ if (existing_file )
426436 {
427- if (!parray_rm (filelist , file , pgFileCompareRelPathWithExternal ))
428- elog (ERROR , "Failed to remove duplicate from array of streamed segments: %s" ,
429- file -> rel_path );
437+ (* existing_file )-> crc = pgFileGetCRC (wal_segment_fullpath , true, false);
438+ (* existing_file )-> write_size = xlog_seg_size ;
439+ (* existing_file )-> uncompressed_size = xlog_seg_size ;
440+
441+ return ;
430442 }
431443
432444 /* calculate crc */
@@ -437,6 +449,5 @@ append_wal_segment(parray *filelist, uint32 timeline, XLogRecPtr xlogpos, char *
437449 file -> uncompressed_size = xlog_seg_size ;
438450
439451 /* append file to filelist */
440- elog (VERBOSE , "Append WAL segment: \"%s\"" , wal_segment_relpath );
441452 parray_append (filelist , file );
442453}
0 commit comments