@@ -489,7 +489,20 @@ do_restore_or_validate(InstanceState *instanceState, time_t target_backup_id, pg
489
489
{
490
490
RedoParams redo ;
491
491
parray * timelines = NULL ;
492
- get_redo (instance_config .pgdata , & redo );
492
+
493
+ /* [Issue #313] check for previous failed incremental restore */
494
+ {
495
+ char filename [MAXPGPATH ];
496
+
497
+ join_path_components (filename , instance_config .pgdata , XLOG_CONTROL_BAK_FILE );
498
+ if (fio_access (filename , F_OK , FIO_DB_HOST ) == 0 )
499
+ {
500
+ elog (WARNING , "\"%s\" found, using incremental restore parameters from it" , filename );
501
+ get_redo (instance_config .pgdata , XLOG_CONTROL_BAK_FILE , & redo );
502
+ }
503
+ else
504
+ get_redo (instance_config .pgdata , XLOG_CONTROL_FILE , & redo );
505
+ }
493
506
494
507
if (redo .checksum_version == 0 )
495
508
elog (ERROR , "Incremental restore in 'lsn' mode require "
@@ -714,6 +727,7 @@ restore_chain(pgBackup *dest_backup, parray *parent_chain,
714
727
parray * external_dirs = NULL ;
715
728
pgFile * dest_pg_control_file = NULL ;
716
729
char dest_pg_control_fullpath [MAXPGPATH ];
730
+ char dest_pg_control_bak_fullpath [MAXPGPATH ];
717
731
/* arrays with meta info for multi threaded backup */
718
732
pthread_t * threads ;
719
733
restore_files_arg * threads_args ;
@@ -794,12 +808,7 @@ restore_chain(pgBackup *dest_backup, parray *parent_chain,
794
808
* unless we are running incremental-lsn restore, then bitmap is mandatory.
795
809
*/
796
810
if (use_bitmap && parray_num (parent_chain ) == 1 )
797
- {
798
- if (params -> incremental_mode == INCR_NONE )
799
- use_bitmap = false;
800
- else
801
- use_bitmap = true;
802
- }
811
+ use_bitmap = params -> incremental_mode != INCR_NONE ;
803
812
804
813
/*
805
814
* Restore dest_backup internal directories.
@@ -917,6 +926,11 @@ restore_chain(pgBackup *dest_backup, parray *parent_chain,
917
926
pg_strcasecmp (file -> name , RELMAPPER_FILENAME ) == 0 )
918
927
redundant = true;
919
928
929
+ /* global/pg_control.pbk.bak are always keeped, because it's needed for restart failed incremental restore */
930
+ if (file -> external_dir_num == 0 &&
931
+ pg_strcasecmp (file -> rel_path , XLOG_CONTROL_BAK_FILE ) == 0 )
932
+ redundant = false;
933
+
920
934
/* do not delete the useful internal directories */
921
935
if (S_ISDIR (file -> mode ) && !redundant )
922
936
continue ;
@@ -988,13 +1002,16 @@ restore_chain(pgBackup *dest_backup, parray *parent_chain,
988
1002
elog (ERROR , "File \"%s\" not found in backup %s" , XLOG_CONTROL_FILE , base36enc (dest_backup -> start_time ));
989
1003
dest_pg_control_file = parray_remove (dest_files , control_file_elem_index );
990
1004
991
- join_path_components (dest_pg_control_fullpath , pgdata_path , dest_pg_control_file -> rel_path );
992
- /* remove dest control file before restoring */
993
- if (params -> incremental_mode != INCR_NONE )
994
- fio_unlink (dest_pg_control_fullpath , FIO_DB_HOST );
995
-
996
- // TODO: maybe we should rename "pg_control" into something like "pg_control.pbk" to
997
- // keep the ability to rerun failed incremental restore ?
1005
+ join_path_components (dest_pg_control_fullpath , pgdata_path , XLOG_CONTROL_FILE );
1006
+ join_path_components (dest_pg_control_bak_fullpath , pgdata_path , XLOG_CONTROL_BAK_FILE );
1007
+ /*
1008
+ * rename (if it exist) dest control file before restoring
1009
+ * if it doesn't exist, that mean, that we already restoring in a previously failed
1010
+ * pgdata, where XLOG_CONTROL_BAK_FILE exist
1011
+ */
1012
+ if (params -> incremental_mode != INCR_NONE
1013
+ && fio_access (dest_pg_control_fullpath , F_OK , FIO_DB_HOST ) == 0 )
1014
+ fio_rename (dest_pg_control_fullpath , dest_pg_control_bak_fullpath , FIO_DB_HOST );
998
1015
}
999
1016
1000
1017
elog (INFO , "Start restoring backup files. PGDATA size: %s" , pretty_dest_bytes );
@@ -1042,7 +1059,8 @@ restore_chain(pgBackup *dest_backup, parray *parent_chain,
1042
1059
{
1043
1060
total_bytes += restore_file (dest_pg_control_file , dest_pg_control_fullpath , false, NULL ,
1044
1061
dest_backup , parent_chain , use_bitmap , params -> incremental_mode , params -> shift_lsn );
1045
- fio_disconnect ();
1062
+ if (params -> incremental_mode != INCR_NONE )
1063
+ fio_unlink (dest_pg_control_bak_fullpath , FIO_DB_HOST );
1046
1064
}
1047
1065
1048
1066
time (& end_time );
0 commit comments