Skip to content

Commit e0b3e89

Browse files
committed
read block via pg_ptrack_read_block() for every page in ptrack backups and every invalid page in other backup modes
1 parent 39519f7 commit e0b3e89

File tree

3 files changed

+68
-4
lines changed

3 files changed

+68
-4
lines changed

src/backup.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2694,3 +2694,45 @@ get_last_ptrack_lsn(void)
26942694
PQclear(res);
26952695
return lsn;
26962696
}
2697+
2698+
char *
2699+
pg_ptrack_get_block(Oid relOid,
2700+
BlockNumber blknum,
2701+
size_t *result_size)
2702+
{
2703+
PGresult *res;
2704+
char *params[2];
2705+
char *result;
2706+
char *val;
2707+
2708+
params[0] = palloc(64);
2709+
params[1] = palloc(64);
2710+
2711+
/*
2712+
* Use backup_conn, cause we can do it from any database.
2713+
*/
2714+
sprintf(params[0], "%i", relOid);
2715+
sprintf(params[1], "%u", blknum);
2716+
res = pgut_execute(backup_conn, "SELECT pg_ptrack_get_block($1, $2)",
2717+
2, (const char **)params, true);
2718+
2719+
if (PQnfields(res) != 1)
2720+
elog(WARNING, "cannot get file block for relation oid %u",
2721+
relOid);
2722+
2723+
val = PQgetvalue(res, 0, 0);
2724+
2725+
if (strcmp("x", val+1) == 0)
2726+
{
2727+
/* Ptrack file is missing */
2728+
return NULL;
2729+
}
2730+
2731+
result = (char *) PQunescapeBytea((unsigned char *) PQgetvalue(res, 0, 0),
2732+
result_size);
2733+
PQclear(res);
2734+
pfree(params[0]);
2735+
pfree(params[1]);
2736+
2737+
return result;
2738+
}

src/data.c

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,19 +121,21 @@ static void
121121
backup_data_page(pgFile *file, XLogRecPtr prev_backup_start_lsn,
122122
BlockNumber blknum, BlockNumber nblocks,
123123
FILE *in, FILE *out,
124-
pg_crc32 *crc, int *n_skipped)
124+
pg_crc32 *crc, int *n_skipped,
125+
BackupMode backup_mode)
125126
{
126127
BackupPageHeader header;
127128
off_t offset;
128129
DataPage page; /* used as read buffer */
130+
DataPage *page_ptr = &page; /* used as read buffer */
129131
DataPage compressed_page; /* used as read buffer */
130132
size_t write_buffer_size;
131133
/* maximum size of write buffer */
132134
char write_buffer[BLCKSZ+sizeof(header)];
133135
size_t read_len = 0;
134136
XLogRecPtr page_lsn;
135137
int try_checksum = 100;
136-
138+
bool page_is_invalid = true;
137139
header.block = blknum;
138140
offset = blknum * BLCKSZ;
139141

@@ -156,6 +158,7 @@ backup_data_page(pgFile *file, XLogRecPtr prev_backup_start_lsn,
156158
{
157159
elog(LOG, "File %s, block %u, file was truncated",
158160
file->path, blknum);
161+
page_is_invalid = false;
159162
return;
160163
}
161164
else if (try_checksum)
@@ -187,6 +190,7 @@ backup_data_page(pgFile *file, XLogRecPtr prev_backup_start_lsn,
187190
if (i == BLCKSZ)
188191
{
189192
elog(LOG, "File: %s blknum %u, empty page", file->path, blknum);
193+
page_is_invalid = false;
190194
break;
191195
}
192196

@@ -238,10 +242,24 @@ backup_data_page(pgFile *file, XLogRecPtr prev_backup_start_lsn,
238242
file->path, blknum);
239243
}
240244
else
245+
{
246+
page_is_invalid = false;
241247
break; /* page header and checksum are correct */
248+
}
242249
}
243250
else
251+
{
252+
page_is_invalid = false;
244253
break; /* page header is correct and checksum check is disabled */
254+
}
255+
}
256+
257+
258+
if (page_is_invalid ||
259+
(backup_mode == BACKUP_MODE_DIFF_PTRACK))
260+
{
261+
size_t page_size = 0;
262+
page_ptr = pg_ptrack_get_block(file->relOid, blknum, &page_size);
245263
}
246264

247265
file->read_size += read_len;
@@ -388,7 +406,8 @@ backup_data_file(const char *from_root, const char *to_root,
388406
for (blknum = 0; blknum < nblocks; blknum++)
389407
{
390408
backup_data_page(file, prev_backup_start_lsn, blknum,
391-
nblocks, in, out, &(file->crc), &n_blocks_skipped);
409+
nblocks, in, out, &(file->crc),
410+
&n_blocks_skipped, backup_mode);
392411
n_blocks_read++;
393412
}
394413
}
@@ -400,7 +419,8 @@ backup_data_file(const char *from_root, const char *to_root,
400419
while (datapagemap_next(iter, &blknum))
401420
{
402421
backup_data_page(file, prev_backup_start_lsn, blknum,
403-
nblocks, in, out, &(file->crc), &n_blocks_skipped);
422+
nblocks, in, out, &(file->crc),
423+
&n_blocks_skipped, backup_mode);
404424
n_blocks_read++;
405425
}
406426

src/pg_probackup.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,8 @@ extern bool fileExists(const char *path);
320320
extern void process_block_change(ForkNumber forknum, RelFileNode rnode,
321321
BlockNumber blkno);
322322

323+
extern char *pg_ptrack_get_block(Oid relOid, BlockNumber blknum,
324+
size_t *result_size);
323325
/* in restore.c */
324326
extern int do_restore_or_validate(time_t target_backup_id,
325327
const char *target_time,

0 commit comments

Comments
 (0)