@@ -861,14 +861,25 @@ backup_non_data_file(pgFile *file, pgFile *prev_file,
861861 * Apply changed blocks to destination file from every backup in parent chain.
862862 */
863863size_t
864- restore_data_file (parray * parent_chain , pgFile * dest_file , FILE * out , const char * to_fullpath )
864+ restore_data_file (parray * parent_chain , pgFile * dest_file , FILE * out ,
865+ const char * to_fullpath , bool use_bitmap )
865866{
866- int i ;
867867 size_t total_write_len = 0 ;
868868 char * in_buf = pgut_malloc (STDIO_BUFSIZE );
869+ int backup_seq = 0 ;
870+
871+ // FULL -> INCR -> DEST
872+ // 2 1 0
873+ if (use_bitmap )
874+ /* start with dest backup */
875+ backup_seq = 0 ;
876+ else
877+ /* start with full backup */
878+ backup_seq = parray_num (parent_chain ) - 1 ;
869879
870880// for (i = parray_num(parent_chain) - 1; i >= 0; i--)
871- for (i = 0 ; i < parray_num (parent_chain ); i ++ )
881+ // for (i = 0; i < parray_num(parent_chain); i++)
882+ while (backup_seq >= 0 && backup_seq < parray_num (parent_chain ))
872883 {
873884 char from_root [MAXPGPATH ];
874885 char from_fullpath [MAXPGPATH ];
@@ -877,7 +888,12 @@ restore_data_file(parray *parent_chain, pgFile *dest_file, FILE *out, const char
877888 pgFile * * res_file = NULL ;
878889 pgFile * tmp_file = NULL ;
879890
880- pgBackup * backup = (pgBackup * ) parray_get (parent_chain , i );
891+ pgBackup * backup = (pgBackup * ) parray_get (parent_chain , backup_seq );
892+
893+ if (use_bitmap )
894+ backup_seq ++ ;
895+ else
896+ backup_seq -- ;
881897
882898 /* lookup file in intermediate backup */
883899 res_file = parray_bsearch (backup -> files , dest_file , pgFileCompareRelPathWithExternal );
@@ -925,7 +941,7 @@ restore_data_file(parray *parent_chain, pgFile *dest_file, FILE *out, const char
925941 total_write_len += restore_data_file_internal (in , out , tmp_file ,
926942 parse_program_version (backup -> program_version ),
927943 from_fullpath , to_fullpath , dest_file -> n_blocks ,
928- & (dest_file )-> pagemap );
944+ use_bitmap ? & (dest_file )-> pagemap : NULL );
929945
930946 if (fclose (in ) != 0 )
931947 elog (ERROR , "Cannot close file \"%s\": %s" , from_fullpath ,
@@ -938,6 +954,11 @@ restore_data_file(parray *parent_chain, pgFile *dest_file, FILE *out, const char
938954 return total_write_len ;
939955}
940956
957+ /* Restore block from "in" file to "out" file.
958+ * If "nblocks" is greater than zero, then skip restoring blocks,
959+ * whose position if greater than "nblocks".
960+ * If map is NULL, then page bitmap cannot be used for restore optimization
961+ */
941962size_t
942963restore_data_file_internal (FILE * in , FILE * out , pgFile * file , uint32 backup_version ,
943964 const char * from_fullpath , const char * to_fullpath , int nblocks ,
@@ -1050,7 +1071,7 @@ restore_data_file_internal(FILE *in, FILE *out, pgFile *file, uint32 backup_vers
10501071 elog (ERROR , "Size of a blknum %i exceed BLCKSZ" , blknum );
10511072
10521073 /* if this page is marked as already restored, then skip it */
1053- if (datapagemap_is_set (map , blknum ))
1074+ if (map && datapagemap_is_set (map , blknum ))
10541075 {
10551076 /* skip to the next page */
10561077 if (fseek (in , MAXALIGN (compressed_size ), SEEK_CUR ) != 0 )
@@ -1115,7 +1136,8 @@ restore_data_file_internal(FILE *in, FILE *out, pgFile *file, uint32 backup_vers
11151136 write_len += BLCKSZ ;
11161137 cur_pos = write_pos + BLCKSZ ; /* update current write position */
11171138
1118- datapagemap_add (map , blknum );
1139+ if (map )
1140+ datapagemap_add (map , blknum );
11191141 }
11201142
11211143 elog (VERBOSE , "Copied file \"%s\": %lu bytes" , from_fullpath , write_len );
@@ -1191,6 +1213,7 @@ restore_non_data_file(parray *parent_chain, pgBackup *dest_backup,
11911213 * full copy of destination file.
11921214 * Full copy is latest possible destination file with size equal or
11931215 * greater than zero.
1216+ * TODO: rewrite to use parent_link of dest backup.
11941217 */
11951218 for (i = 1 ; i < parray_num (parent_chain ); i ++ )
11961219 {
0 commit comments