@@ -61,6 +61,9 @@ do_catchup(const char *source_pgdata, const char *dest_pgdata, int num_threads)
61
61
//Besides, the name of this function looks strange to me.
62
62
//Maybe catchup_init_state() or catchup_setup() will do better?
63
63
//I'd also suggest to wrap all these fields into some CatchupState, but it isn't urgent.
64
+ /*
65
+ * Prepare for work: fill some globals, open connection to source database
66
+ */
64
67
static PGconn *
65
68
catchup_collect_info (PGNodeInfo * source_node_info , const char * source_pgdata , const char * dest_pgdata )
66
69
{
@@ -186,7 +189,7 @@ catchup_preflight_checks(PGNodeInfo *source_node_info, PGconn *source_conn,
186
189
187
190
/*
188
191
* Check that all tablespaces exists in tablespace mapping (--tablespace-mapping option)
189
- * Emit fatal error if that tablespace found
192
+ * Emit fatal error if that (not existent in map) tablespace found
190
193
*/
191
194
static void
192
195
check_tablespaces_existance_in_tbsmapping (PGconn * conn )
@@ -227,6 +230,7 @@ check_tablespaces_existance_in_tbsmapping(PGconn *conn)
227
230
/*
228
231
* TODO:
229
232
* - add description
233
+ * main worker function, to be moved into do_catchup() and then to be split into meaningful pieces
230
234
*/
231
235
static void
232
236
do_catchup_instance (const char * source_pgdata , const char * dest_pgdata , PGconn * source_conn ,
@@ -315,13 +319,10 @@ do_catchup_instance(const char *source_pgdata, const char *dest_pgdata, PGconn *
315
319
(uint32 ) (dest_redo .lsn >> 32 ), (uint32 ) (dest_redo .lsn ));
316
320
317
321
/* Start stream replication */
318
- if (stream_wal )
319
- {
320
- join_path_components (dest_xlog_path , dest_pgdata , PG_XLOG_DIR );
321
- fio_mkdir (dest_xlog_path , DIR_PERMISSION , FIO_BACKUP_HOST );
322
- start_WAL_streaming (source_conn , dest_xlog_path , & instance_config .conn_opt ,
323
- current .start_lsn , current .tli );
324
- }
322
+ join_path_components (dest_xlog_path , dest_pgdata , PG_XLOG_DIR );
323
+ fio_mkdir (dest_xlog_path , DIR_PERMISSION , FIO_BACKUP_HOST );
324
+ start_WAL_streaming (source_conn , dest_xlog_path , & instance_config .conn_opt ,
325
+ current .start_lsn , current .tli );
325
326
326
327
source_filelist = parray_new ();
327
328
@@ -358,7 +359,6 @@ do_catchup_instance(const char *source_pgdata, const char *dest_pgdata, PGconn *
358
359
*/
359
360
parray_qsort (source_filelist , pgFileCompareRelPathWithExternal );
360
361
361
- //REVIEW Please adjust the comment.
362
362
/* Extract information about files in source_filelist parsing their names:*/
363
363
parse_filelist_filenames (source_filelist , source_pgdata );
364
364
@@ -408,7 +408,7 @@ do_catchup_instance(const char *source_pgdata, const char *dest_pgdata, PGconn *
408
408
409
409
/*
410
410
* check if it is fake "directory" and is a tablespace link
411
- * это происходит потому что мы передали follow_symlink при построении списка
411
+ * this is because we passed the follow_symlink when building the list
412
412
*/
413
413
/* get parent dir of rel_path */
414
414
strncpy (parent_dir , file -> rel_path , MAXPGPATH );
@@ -431,18 +431,20 @@ do_catchup_instance(const char *source_pgdata, const char *dest_pgdata, PGconn *
431
431
const char * linked_path = NULL ;
432
432
char to_path [MAXPGPATH ];
433
433
434
- // perform additional check that this is actually synlink ?
434
+ // perform additional check that this is actually symlink ?
435
435
//REVIEW Why is this code block separated?
436
+ //REVIEW_ANSWER because i want to localize usage of source_full_path and symlink_content
436
437
{ /* get full symlink path and map this path to new location */
437
438
char source_full_path [MAXPGPATH ];
438
439
char symlink_content [MAXPGPATH ];
439
440
join_path_components (source_full_path , source_pgdata , file -> rel_path );
440
441
fio_readlink (source_full_path , symlink_content , sizeof (symlink_content ), FIO_DB_HOST );
441
442
//REVIEW What if we won't find mapping for this tablespace?
442
443
//I'd expect a failure. Otherwise, we may spoil source database data.
444
+ // REVIEW_ANSWER we checked that in preflight_checks for local catchup
445
+ // and for remote catchup this may be correct behavior
443
446
linked_path = leaked_abstraction_get_tablespace_mapping (symlink_content );
444
- // TODO: check that linked_path != symlink_content in case of local catchup?
445
- elog (WARNING , "Map tablespace full_path: \"%s\" old_symlink_content: \"%s\" old_symlink_content: \"%s\"\n" ,
447
+ elog (INFO , "Map tablespace full_path: \"%s\" old_symlink_content: \"%s\" new_symlink_content: \"%s\"\n" ,
446
448
source_full_path ,
447
449
symlink_content ,
448
450
linked_path );
@@ -457,15 +459,15 @@ do_catchup_instance(const char *source_pgdata, const char *dest_pgdata, PGconn *
457
459
elog (VERBOSE , "Create directory \"%s\" and symbolic link \"%s\"" ,
458
460
linked_path , to_path );
459
461
460
- //REVIEW Handle return value here.
461
- //We should not proceed if failed to create dir.
462
462
/* create tablespace directory */
463
- fio_mkdir (linked_path , DIR_PERMISSION , FIO_BACKUP_HOST );
463
+ if (fio_mkdir (linked_path , file -> mode , FIO_BACKUP_HOST ) != 0 )
464
+ elog (ERROR , "Could not create tablespace directory \"%s\": %s" ,
465
+ linked_path , strerror (errno ));
464
466
465
467
/* create link to linked_path */
466
468
if (fio_symlink (linked_path , to_path , true, FIO_BACKUP_HOST ) < 0 )
467
- elog (ERROR , "Could not create symbolic link \"%s\": %s" ,
468
- to_path , strerror (errno ));
469
+ elog (ERROR , "Could not create symbolic link \"%s\" -> \"%s\" : %s" ,
470
+ linked_path , to_path , strerror (errno ));
469
471
}
470
472
}
471
473
@@ -475,7 +477,7 @@ do_catchup_instance(const char *source_pgdata, const char *dest_pgdata, PGconn *
475
477
*/
476
478
{
477
479
int control_file_elem_index ;
478
- pgFile search_key ;
480
+ pgFile search_key ;
479
481
MemSet (& search_key , 0 , sizeof (pgFile ));
480
482
/* pgFileCompareRelPathWithExternal uses only .rel_path and .external_dir_num for comparision */
481
483
search_key .rel_path = XLOG_CONTROL_FILE ;
@@ -502,12 +504,13 @@ do_catchup_instance(const char *source_pgdata, const char *dest_pgdata, PGconn *
502
504
503
505
//REVIEW Can we maybe optimize it and use some merge-like algorithm
504
506
//instead of bsearch for each file? Of course it isn't an urgent fix.
507
+ //REVIEW_ANSWER yes, merge will be better
505
508
if (parray_bsearch (source_filelist , file , pgFileCompareRelPathWithExternal ))
506
509
redundant = false;
507
510
508
511
/* pg_filenode.map are always restored, because it's crc cannot be trusted */
509
- if (file -> external_dir_num == 0 &&
510
- pg_strcasecmp (file -> name , RELMAPPER_FILENAME ) == 0 )
512
+ Assert (file -> external_dir_num == 0 );
513
+ if ( pg_strcasecmp (file -> name , RELMAPPER_FILENAME ) == 0 )
511
514
redundant = true;
512
515
513
516
//REVIEW This check seems unneded. Anyway we delete only redundant stuff below.
@@ -588,6 +591,7 @@ do_catchup_instance(const char *source_pgdata, const char *dest_pgdata, PGconn *
588
591
}
589
592
590
593
/* at last copy control file */
594
+ if (catchup_isok )
591
595
{
592
596
char from_fullpath [MAXPGPATH ];
593
597
char to_fullpath [MAXPGPATH ];
@@ -678,9 +682,8 @@ do_catchup_instance(const char *source_pgdata, const char *dest_pgdata, PGconn *
678
682
/* Cleanup */
679
683
pg_free (query_text );
680
684
681
- //REVIEW Please adjust the comment.
682
- /* In case of backup from replica >= 9.6 we must fix minRecPoint,
683
- * First we must find pg_control in source_filelist.
685
+ /*
686
+ * In case of backup from replica >= 9.6 we must fix minRecPoint
684
687
*/
685
688
if (current .from_replica && !exclusive_backup )
686
689
{
@@ -712,19 +715,9 @@ do_catchup_instance(const char *source_pgdata, const char *dest_pgdata, PGconn *
712
715
continue ;
713
716
714
717
/* construct fullpath */
715
- if (file -> external_dir_num == 0 )
716
- join_path_components (to_fullpath , dest_pgdata , file -> rel_path );
717
- //REVIEW Let's clean this.
718
- /* TODO разобраться с external */
719
- /*else
720
- {
721
- char external_dst[MAXPGPATH];
718
+ Assert (file -> external_dir_num == 0 );
719
+ join_path_components (to_fullpath , dest_pgdata , file -> rel_path );
722
720
723
- makeExternalDirPathByNum(external_dst, external_prefix,
724
- file->external_dir_num);
725
- join_path_components(to_fullpath, external_dst, file->rel_path);
726
- }
727
- */
728
721
if (fio_sync (to_fullpath , FIO_BACKUP_HOST ) != 0 )
729
722
elog (ERROR , "Cannot sync file \"%s\": %s" , to_fullpath , strerror (errno ));
730
723
}
@@ -754,7 +747,7 @@ do_catchup_instance(const char *source_pgdata, const char *dest_pgdata, PGconn *
754
747
}
755
748
756
749
/*
757
- * TODO: add description
750
+ * Catchup file copier executed in separate threads
758
751
*/
759
752
static void *
760
753
catchup_thread_runner (void * arg )
@@ -788,27 +781,9 @@ catchup_thread_runner(void *arg)
788
781
i + 1 , n_files , file -> rel_path );
789
782
790
783
/* construct destination filepath */
791
- /* TODO разобраться нужен ли external */
792
- if (file -> external_dir_num == 0 )
793
- {
794
- join_path_components (from_fullpath , arguments -> from_root , file -> rel_path );
795
- join_path_components (to_fullpath , arguments -> to_root , file -> rel_path );
796
- }
797
- //REVIEW Let's clean this.
798
- /*else
799
- {
800
- char external_dst[MAXPGPATH];
801
- char *external_path = parray_get(arguments->external_dirs,
802
- file->external_dir_num - 1);
803
-
804
- makeExternalDirPathByNum(external_dst,
805
- arguments->external_prefix,
806
- file->external_dir_num);
807
-
808
- join_path_components(to_fullpath, external_dst, file->rel_path);
809
- join_path_components(from_fullpath, external_path, file->rel_path);
810
- }
811
- */
784
+ Assert (file -> external_dir_num == 0 );
785
+ join_path_components (from_fullpath , arguments -> from_root , file -> rel_path );
786
+ join_path_components (to_fullpath , arguments -> to_root , file -> rel_path );
812
787
813
788
/* Encountered some strange beast */
814
789
if (!S_ISREG (file -> mode ))
0 commit comments