@@ -317,17 +317,22 @@ backup_data_page(backup_files_args *arguments,
317317 ((PageHeader ) page )-> pd_checksum = pg_checksum_page (page , absolute_blknum );
318318 }
319319 /* get lsn from page */
320- if (!parse_page (page , & page_lsn ))
320+ if (backup_mode == BACKUP_MODE_DIFF_DELTA &&
321+ file -> exists_in_prev &&
322+ header .compressed_size != PageIsTruncated &&
323+ !parse_page (page , & page_lsn ))
321324 elog (ERROR , "Cannot parse page after pg_ptrack_get_block. "
322325 "Possible risk of a memory corruption" );
323326
324327 }
325328
326329 if (backup_mode == BACKUP_MODE_DIFF_DELTA &&
330+ file -> exists_in_prev &&
327331 header .compressed_size != PageIsTruncated &&
328- page_lsn < prev_backup_start_lsn )
332+ page_lsn < prev_backup_start_lsn )
329333 {
330334 elog (VERBOSE , "Skipping blknum: %u in file: %s" , blknum , file -> path );
335+ (* n_skipped )++ ;
331336 free (page );
332337 return ;
333338 }
@@ -557,18 +562,22 @@ restore_data_file(const char *from_root,
557562 pgBackup * backup )
558563{
559564 char to_path [MAXPGPATH ];
560- FILE * in ;
561- FILE * out ;
565+ FILE * in = NULL ;
566+ FILE * out = NULL ;
562567 BackupPageHeader header ;
563568 BlockNumber blknum ;
564569 size_t file_size ;
565570
566- /* open backup mode file for read */
567- in = fopen (file -> path , "r" );
568- if (in == NULL )
571+ /* BYTES_INVALID allowed only in case of restoring file from DELTA backup */
572+ if (file -> write_size != BYTES_INVALID )
569573 {
570- elog (ERROR , "cannot open backup file \"%s\": %s" , file -> path ,
571- strerror (errno ));
574+ /* open backup mode file for read */
575+ in = fopen (file -> path , "r" );
576+ if (in == NULL )
577+ {
578+ elog (ERROR , "cannot open backup file \"%s\": %s" , file -> path ,
579+ strerror (errno ));
580+ }
572581 }
573582
574583 /*
@@ -594,6 +603,10 @@ restore_data_file(const char *from_root,
594603 DataPage compressed_page ; /* used as read buffer */
595604 DataPage page ;
596605
606+ /* File didn`t changed. Nothig to copy */
607+ if (file -> write_size == BYTES_INVALID )
608+ break ;
609+
597610 /* read BackupPageHeader */
598611 read_len = fread (& header , 1 , sizeof (header ), in );
599612 if (read_len != sizeof (header ))
@@ -670,9 +683,10 @@ restore_data_file(const char *from_root,
670683 }
671684
672685 /*
673- * DELTA backup has no knowledge about truncated blocks as PAGE or PTRACK do
674- * but knows file size at the time of backup.
675- * So when restoring file from delta backup we, knowning it`s size at
686+ * DELTA backup have no knowledge about truncated blocks as PAGE or PTRACK do
687+ * But during DELTA backup we read every file in PGDATA and thus DELTA backup
688+ * knows exact size of every file at the time of backup.
689+ * So when restoring file from DELTA backup we, knowning it`s size at
676690 * a time of a backup, can truncate file to this size.
677691 */
678692
@@ -681,7 +695,6 @@ restore_data_file(const char *from_root,
681695 /* get file current size */
682696 fseek (out , 0 , SEEK_END );
683697 file_size = ftell (out );
684-
685698 if (file_size > file -> n_blocks * BLCKSZ )
686699 {
687700 /*
@@ -699,7 +712,8 @@ restore_data_file(const char *from_root,
699712 {
700713 int errno_tmp = errno ;
701714
702- fclose (in );
715+ if (in )
716+ fclose (in );
703717 fclose (out );
704718 elog (ERROR , "cannot change mode of \"%s\": %s" , to_path ,
705719 strerror (errno_tmp ));
@@ -709,7 +723,8 @@ restore_data_file(const char *from_root,
709723 fsync (fileno (out )) != 0 ||
710724 fclose (out ))
711725 elog (ERROR , "cannot write \"%s\": %s" , to_path , strerror (errno ));
712- fclose (in );
726+ if (in )
727+ fclose (in );
713728}
714729
715730/*
0 commit comments