@@ -311,15 +311,12 @@ do_catchup_instance(const char *source_pgdata, const char *dest_pgdata, PGconn *
311
311
pgFile * file = (pgFile * ) parray_get (source_filelist , i );
312
312
char parent_dir [MAXPGPATH ];
313
313
314
- /* setup threads */
315
- pg_atomic_clear_flag (& file -> lock );
316
-
317
314
if (!S_ISDIR (file -> mode ))
318
315
continue ;
319
316
320
317
/*
321
318
* check if it is fake "directory" and is a tablespace link
322
- * это происходить потому что мы передали follow_symlink при построении списка
319
+ * это происходит потому что мы передали follow_symlink при построении списка
323
320
*/
324
321
/* get parent dir of rel_path */
325
322
strncpy (parent_dir , file -> rel_path , MAXPGPATH );
@@ -342,12 +339,14 @@ do_catchup_instance(const char *source_pgdata, const char *dest_pgdata, PGconn *
342
339
const char * linked_path = NULL ;
343
340
char to_path [MAXPGPATH ];
344
341
342
+ // perform additional check that this is actually synlink?
345
343
{ /* get full symlink path and map this path to new location */
346
344
char source_full_path [MAXPGPATH ];
347
345
char symlink_content [MAXPGPATH ];
348
346
join_path_components (source_full_path , source_pgdata , file -> rel_path );
349
347
fio_readlink (source_full_path , symlink_content , sizeof (symlink_content ), FIO_DB_HOST );
350
348
linked_path = leaked_abstraction_get_tablespace_mapping (symlink_content );
349
+ // TODO: check that linked_path != symlink_content in case of local catchup?
351
350
elog (WARNING , "Map tablespace full_path: \"%s\" old_symlink_content: \"%s\" old_symlink_content: \"%s\"\n" ,
352
351
source_full_path ,
353
352
symlink_content ,
@@ -373,6 +372,50 @@ do_catchup_instance(const char *source_pgdata, const char *dest_pgdata, PGconn *
373
372
}
374
373
}
375
374
375
+ if (!dest_pgdata_is_empty &&
376
+ (current .backup_mode == BACKUP_MODE_DIFF_PTRACK ||
377
+ current .backup_mode == BACKUP_MODE_DIFF_DELTA ))
378
+ {
379
+ elog (INFO , "Removing redundant files in destination directory" );
380
+ parray_qsort (dest_filelist , pgFileCompareRelPathWithExternalDesc );
381
+ for (i = 0 ; i < parray_num (dest_filelist ); i ++ )
382
+ {
383
+ bool redundant = true;
384
+ pgFile * file = (pgFile * ) parray_get (dest_filelist , i );
385
+
386
+ if (parray_bsearch (source_filelist , file , pgFileCompareRelPathWithExternal ))
387
+ redundant = false;
388
+
389
+ /* pg_filenode.map are always restored, because it's crc cannot be trusted */
390
+ if (file -> external_dir_num == 0 &&
391
+ pg_strcasecmp (file -> name , RELMAPPER_FILENAME ) == 0 )
392
+ redundant = true;
393
+
394
+ /* do not delete the useful internal directories */
395
+ if (S_ISDIR (file -> mode ) && !redundant )
396
+ continue ;
397
+
398
+ /* if file does not exists in destination list, then we can safely unlink it */
399
+ if (redundant )
400
+ {
401
+ char fullpath [MAXPGPATH ];
402
+
403
+ join_path_components (fullpath , dest_pgdata , file -> rel_path );
404
+
405
+ fio_delete (file -> mode , fullpath , FIO_DB_HOST );
406
+ elog (VERBOSE , "Deleted file \"%s\"" , fullpath );
407
+
408
+ /* shrink pgdata list */
409
+ pgFileFree (file );
410
+ parray_remove (dest_filelist , i );
411
+ i -- ;
412
+ }
413
+ }
414
+ }
415
+
416
+ /* clear file locks */
417
+ pfilearray_clear_locks (source_filelist );
418
+
376
419
/* Sort by size for load balancing */
377
420
parray_qsort (source_filelist , pgFileCompareSize );
378
421
0 commit comments