diff --git a/src/bin/pg_probackup/data.cpp b/src/bin/pg_probackup/data.cpp index cade2fabad524e77bb62e237aa1843905b21ad77..3fc60972d3dc9238e70f7221569962faa9328a21 100644 --- a/src/bin/pg_probackup/data.cpp +++ b/src/bin/pg_probackup/data.cpp @@ -2036,13 +2036,14 @@ send_pages(ConnectionArgs* conn_arg, const char *to_fullpath, const char *from_f { FILE *in = NULL; FILE *out = NULL; - int hdr_num = -1; off_t cur_pos_out = 0; char curr_page[BLCKSZ]; int n_blocks_read = 0; BlockNumber blknum = 0; datapagemap_iterator_t *iter = NULL; int compressed_size = 0; + BackupPageHeader2 *header = NULL; + parray *harray = NULL; /* stdio buffers */ char *in_buf = NULL; @@ -2081,6 +2082,8 @@ send_pages(ConnectionArgs* conn_arg, const char *to_fullpath, const char *from_f setvbuf(in, in_buf, _IOFBF, STDIO_BUFSIZE); } + harray = parray_new(); + while (blknum < (BlockNumber)file->n_blocks) { PageState page_st; @@ -2097,19 +2100,12 @@ send_pages(ConnectionArgs* conn_arg, const char *to_fullpath, const char *from_f if (!out) out = open_local_file_rw(to_fullpath, &out_buf, STDIO_BUFSIZE); - hdr_num++; - - if (!*headers) - *headers = (BackupPageHeader2 *) pgut_malloc(sizeof(BackupPageHeader2)); - else - *headers = (BackupPageHeader2 *) pgut_realloc(*headers, - (hdr_num) * sizeof(BackupPageHeader2), - (hdr_num + 1) * sizeof(BackupPageHeader2)); - - (*headers)[hdr_num].block = blknum; - (*headers)[hdr_num].pos = cur_pos_out; - (*headers)[hdr_num].lsn = page_st.lsn; - (*headers)[hdr_num].checksum = page_st.checksum; + header = pgut_new0(BackupPageHeader2); + header->block = blknum; + header->pos = cur_pos_out; + header->lsn = page_st.lsn; + header->checksum = page_st.checksum; + parray_append(harray, header); compressed_size = compress_and_backup_page(file, blknum, in, out, &(file->crc), rc, curr_page, calg, clevel, @@ -2134,14 +2130,21 @@ send_pages(ConnectionArgs* conn_arg, const char *to_fullpath, const char *from_f * Add dummy header, so we can later extract the length of last header * as difference between their offsets. */ - if (*headers) + if (parray_num(harray) > 0) { - file->n_headers = hdr_num +1; - *headers = (BackupPageHeader2 *) pgut_realloc(*headers, - (hdr_num + 1) * sizeof(BackupPageHeader2), - (hdr_num + 2) * sizeof(BackupPageHeader2)); - (*headers)[hdr_num+1].pos = cur_pos_out; + size_t hdr_num = parray_num(harray); + size_t i; + file->n_headers = (int) hdr_num; /* is it valid? */ + *headers = (BackupPageHeader2 *) pgut_malloc0((hdr_num + 1) * sizeof(BackupPageHeader2)); + for (i = 0; i < hdr_num; i++) + { + header = (BackupPageHeader2 *)parray_get(harray, i); + (*headers)[i] = *header; + pg_free(header); + } + (*headers)[hdr_num].pos =cur_pos_out; } + parray_free(harray); /* cleanup */ if (in && fclose(in)) diff --git a/src/bin/pg_probackup/pgut.cpp b/src/bin/pg_probackup/pgut.cpp index b513c97cfd8fa4be6e3f1bbf40787578faa794c6..14426b2163083cfa70c7b8abb88c00ca3f896456 100644 --- a/src/bin/pg_probackup/pgut.cpp +++ b/src/bin/pg_probackup/pgut.cpp @@ -1230,6 +1230,14 @@ pgut_malloc(size_t size) return ret; } +void * pgut_malloc0(size_t size) +{ + char *ret; + ret = (char *)pgut_malloc(size); + memset(ret, 0, size); + return ret; +} + void * pgut_realloc(void *p, size_t oldSize, size_t size) { diff --git a/src/bin/pg_probackup/pgut.h b/src/bin/pg_probackup/pgut.h index daab52390c73a0a2c4e83b0f63e671fe07180e64..af080cc2c641bdf97c72dfa9eb0cb66b43a5d689 100644 --- a/src/bin/pg_probackup/pgut.h +++ b/src/bin/pg_probackup/pgut.h @@ -58,10 +58,12 @@ extern int pgut_wait(int num, PGconn *connections[], struct timeval *timeout); * memory allocators */ extern void *pgut_malloc(size_t size); +extern void *pgut_malloc0(size_t size); extern void *pgut_realloc(void *p, size_t oldSize, size_t size); extern char *pgut_strdup(const char *str); #define pgut_new(type) ((type *) pgut_malloc(sizeof(type))) +#define pgut_new0(type) ((type *) pgut_malloc0(sizeof(type))) #define pgut_newarray(type, n) ((type *) pgut_malloc(sizeof(type) * (n))) /* diff --git a/src/bin/pg_probackup/restore.cpp b/src/bin/pg_probackup/restore.cpp index 6b0aa5b1260b25bfb3be033beb1b8d639a6bfc16..f2fc36b5c1175d55a8d7235a6124b35815f87997 100644 --- a/src/bin/pg_probackup/restore.cpp +++ b/src/bin/pg_probackup/restore.cpp @@ -290,6 +290,7 @@ do_restore_or_validate(time_t target_backup_id, pgRecoveryTarget *rt, * We must be able to differentiate the scenario A and scenario B. * */ + params->shift_lsn = InvalidXLogRecPtr; if (params->is_restore && params->incremental_mode == INCR_LSN) { params->shift_lsn = determine_shift_lsn(dest_backup); diff --git a/src/bin/pg_probackup/util.cpp b/src/bin/pg_probackup/util.cpp index 64528b2cac6f6eef0c7b73ff474f594fd0a5104d..538463d9b378f82087ce61205d1aed526c3ec22e 100644 --- a/src/bin/pg_probackup/util.cpp +++ b/src/bin/pg_probackup/util.cpp @@ -130,7 +130,7 @@ writeControlFile(ControlFileData *ControlFile, const char *path, fio_location lo int fd; char *buffer = NULL; - buffer = (char *)pg_malloc(PG_CONTROL_SIZE); + buffer = (char *)pg_malloc0(PG_CONTROL_SIZE); errno_t rc = memcpy_s(buffer, sizeof(ControlFileData), ControlFile, sizeof(ControlFileData)); securec_check_c(rc, "\0", "\0"); /* Write pg_control */