Skip to content

Commit 46c7f92

Browse files
committed
[Issue #201] WIP
1 parent 596d08b commit 46c7f92

File tree

3 files changed

+84
-7
lines changed

3 files changed

+84
-7
lines changed

src/data.c

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -860,7 +860,8 @@ restore_data_file(parray *parent_chain, pgFile *dest_file, FILE *out, const char
860860
size_t total_write_len = 0;
861861
char *in_buf = pgut_malloc(STDIO_BUFSIZE);
862862

863-
for (i = parray_num(parent_chain) - 1; i >= 0; i--)
863+
// for (i = parray_num(parent_chain) - 1; i >= 0; i--)
864+
for (i = 0; i < parray_num(parent_chain); i++)
864865
{
865866
char from_root[MAXPGPATH];
866867
char from_fullpath[MAXPGPATH];
@@ -916,11 +917,14 @@ restore_data_file(parray *parent_chain, pgFile *dest_file, FILE *out, const char
916917
*/
917918
total_write_len += restore_data_file_internal(in, out, tmp_file,
918919
parse_program_version(backup->program_version),
919-
from_fullpath, to_fullpath, dest_file->n_blocks);
920+
from_fullpath, to_fullpath, dest_file->n_blocks,
921+
&(dest_file)->pagemap);
920922

921923
if (fclose(in) != 0)
922924
elog(ERROR, "Cannot close file \"%s\": %s", from_fullpath,
923925
strerror(errno));
926+
927+
// datapagemap_print_debug(&(dest_file)->pagemap);
924928
}
925929
pg_free(in_buf);
926930

@@ -929,7 +933,8 @@ restore_data_file(parray *parent_chain, pgFile *dest_file, FILE *out, const char
929933

930934
size_t
931935
restore_data_file_internal(FILE *in, FILE *out, pgFile *file, uint32 backup_version,
932-
const char *from_fullpath, const char *to_fullpath, int nblocks)
936+
const char *from_fullpath, const char *to_fullpath, int nblocks,
937+
datapagemap_t *map)
933938
{
934939
BackupPageHeader header;
935940
BlockNumber blknum = 0;
@@ -987,9 +992,9 @@ restore_data_file_internal(FILE *in, FILE *out, pgFile *file, uint32 backup_vers
987992
}
988993

989994
/* sanity? */
990-
if (header.block < blknum)
991-
elog(ERROR, "Backup is broken at block %u of \"%s\"",
992-
blknum, from_fullpath);
995+
// if (header.block < blknum)
996+
// elog(ERROR, "Backup is broken at block %u of \"%s\"",
997+
// blknum, from_fullpath);
993998

994999
blknum = header.block;
9951000

@@ -1037,6 +1042,15 @@ restore_data_file_internal(FILE *in, FILE *out, pgFile *file, uint32 backup_vers
10371042
if (compressed_size > BLCKSZ)
10381043
elog(ERROR, "Size of a blknum %i exceed BLCKSZ", blknum);
10391044

1045+
/* if this page was already restored, then skip it */
1046+
if (datapagemap_is_set(map, blknum))
1047+
{
1048+
elog(WARNING, "Skipping block %u because is was already restored", blknum);
1049+
/* TODO: check error */
1050+
fseek(in, compressed_size, SEEK_CUR);
1051+
continue;
1052+
}
1053+
10401054
/* read a page from file */
10411055
read_len = fread(page.data, 1, MAXALIGN(compressed_size), in);
10421056

@@ -1092,6 +1106,8 @@ restore_data_file_internal(FILE *in, FILE *out, pgFile *file, uint32 backup_vers
10921106

10931107
write_len += BLCKSZ;
10941108
cur_pos = write_pos + BLCKSZ; /* update current write position */
1109+
1110+
datapagemap_add(map, blknum);
10951111
}
10961112

10971113
elog(VERBOSE, "Copied file \"%s\": %lu bytes", from_fullpath, write_len);

src/pg_probackup.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -925,7 +925,8 @@ extern void backup_non_data_file_internal(const char *from_fullpath,
925925
extern size_t restore_data_file(parray *parent_chain, pgFile *dest_file,
926926
FILE *out, const char *to_fullpath);
927927
extern size_t restore_data_file_internal(FILE *in, FILE *out, pgFile *file, uint32 backup_version,
928-
const char *from_fullpath, const char *to_fullpath, int nblocks);
928+
const char *from_fullpath, const char *to_fullpath, int nblocks,
929+
datapagemap_t *map);
929930
extern size_t restore_non_data_file(parray *parent_chain, pgBackup *dest_backup,
930931
pgFile *dest_file, FILE *out, const char *to_fullpath);
931932
extern void restore_non_data_file_internal(FILE *in, FILE *out, pgFile *file,
@@ -1037,4 +1038,10 @@ extern void get_header_errormsg(Page page, char **errormsg);
10371038
extern void get_checksum_errormsg(Page page, char **errormsg,
10381039
BlockNumber absolute_blkno);
10391040

1041+
extern bool
1042+
datapagemap_is_set(datapagemap_t *map, BlockNumber blkno);
1043+
1044+
extern void
1045+
datapagemap_print_debug(datapagemap_t *map);
1046+
10401047
#endif /* PG_PROBACKUP_H */

src/util.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,3 +495,57 @@ str2status(const char *status)
495495

496496
return BACKUP_STATUS_INVALID;
497497
}
498+
499+
bool
500+
datapagemap_is_set(datapagemap_t *map, BlockNumber blkno)
501+
{
502+
int offset;
503+
int bitno;
504+
505+
offset = blkno / 8;
506+
bitno = blkno % 8;
507+
508+
/* enlarge or create bitmap if needed */
509+
if (map->bitmapsize <= offset)
510+
{
511+
int oldsize = map->bitmapsize;
512+
int newsize;
513+
514+
/*
515+
* The minimum to hold the new bit is offset + 1. But add some
516+
* headroom, so that we don't need to repeatedly enlarge the bitmap in
517+
* the common case that blocks are modified in order, from beginning
518+
* of a relation to the end.
519+
*/
520+
newsize = offset + 1;
521+
newsize += 10;
522+
523+
map->bitmap = pg_realloc(map->bitmap, newsize);
524+
525+
/* zero out the newly allocated region */
526+
memset(&map->bitmap[oldsize], 0, newsize - oldsize);
527+
528+
map->bitmapsize = newsize;
529+
}
530+
531+
//datapagemap_print(map);
532+
533+
/* check the bit */
534+
return map->bitmap[offset] & (1 << bitno);
535+
}
536+
537+
/*
538+
* A debugging aid. Prints out the contents of the page map.
539+
*/
540+
void
541+
datapagemap_print_debug(datapagemap_t *map)
542+
{
543+
datapagemap_iterator_t *iter;
544+
BlockNumber blocknum;
545+
546+
iter = datapagemap_iterate(map);
547+
while (datapagemap_next(iter, &blocknum))
548+
elog(INFO, " block %u", blocknum);
549+
550+
pg_free(iter);
551+
}

0 commit comments

Comments
 (0)