@@ -489,7 +489,20 @@ do_restore_or_validate(InstanceState *instanceState, time_t target_backup_id, pg
489489{
490490RedoParams redo ;
491491parray * 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+ }
493506
494507if (redo .checksum_version == 0 )
495508elog (ERROR ,"Incremental restore in 'lsn' mode require "
@@ -714,6 +727,7 @@ restore_chain(pgBackup *dest_backup, parray *parent_chain,
714727parray * external_dirs = NULL ;
715728pgFile * dest_pg_control_file = NULL ;
716729char dest_pg_control_fullpath [MAXPGPATH ];
730+ char dest_pg_control_bak_fullpath [MAXPGPATH ];
717731/* arrays with meta info for multi threaded backup */
718732pthread_t * threads ;
719733restore_files_arg * threads_args ;
@@ -794,12 +808,7 @@ restore_chain(pgBackup *dest_backup, parray *parent_chain,
794808 * unless we are running incremental-lsn restore, then bitmap is mandatory.
795809 */
796810if (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 ;
803812
804813/*
805814 * Restore dest_backup internal directories.
@@ -917,6 +926,11 @@ restore_chain(pgBackup *dest_backup, parray *parent_chain,
917926pg_strcasecmp (file -> name ,RELMAPPER_FILENAME )== 0 )
918927redundant = true;
919928
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+
920934/* do not delete the useful internal directories */
921935if (S_ISDIR (file -> mode )&& !redundant )
922936continue ;
@@ -988,13 +1002,16 @@ restore_chain(pgBackup *dest_backup, parray *parent_chain,
9881002elog (ERROR ,"File \"%s\" not found in backup %s" ,XLOG_CONTROL_FILE ,base36enc (dest_backup -> start_time ));
9891003dest_pg_control_file = parray_remove (dest_files ,control_file_elem_index );
9901004
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 );
9981015}
9991016
10001017elog (INFO ,"Start restoring backup files. PGDATA size: %s" ,pretty_dest_bytes );
@@ -1042,7 +1059,8 @@ restore_chain(pgBackup *dest_backup, parray *parent_chain,
10421059{
10431060total_bytes += restore_file (dest_pg_control_file ,dest_pg_control_fullpath , false,NULL ,
10441061dest_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 );
10461064}
10471065
10481066time (& end_time );