mirror of
https://github.com/postgrespro/pg_probackup.git
synced 2026-06-21 01:34:15 +02:00
read block via pg_ptrack_read_block() for every page in ptrack backups and every invalid page in other backup modes
This commit is contained in:
@@ -2694,3 +2694,45 @@ get_last_ptrack_lsn(void)
|
||||
PQclear(res);
|
||||
return lsn;
|
||||
}
|
||||
|
||||
char *
|
||||
pg_ptrack_get_block(Oid relOid,
|
||||
BlockNumber blknum,
|
||||
size_t *result_size)
|
||||
{
|
||||
PGresult *res;
|
||||
char *params[2];
|
||||
char *result;
|
||||
char *val;
|
||||
|
||||
params[0] = palloc(64);
|
||||
params[1] = palloc(64);
|
||||
|
||||
/*
|
||||
* Use backup_conn, cause we can do it from any database.
|
||||
*/
|
||||
sprintf(params[0], "%i", relOid);
|
||||
sprintf(params[1], "%u", blknum);
|
||||
res = pgut_execute(backup_conn, "SELECT pg_ptrack_get_block($1, $2)",
|
||||
2, (const char **)params, true);
|
||||
|
||||
if (PQnfields(res) != 1)
|
||||
elog(WARNING, "cannot get file block for relation oid %u",
|
||||
relOid);
|
||||
|
||||
val = PQgetvalue(res, 0, 0);
|
||||
|
||||
if (strcmp("x", val+1) == 0)
|
||||
{
|
||||
/* Ptrack file is missing */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = (char *) PQunescapeBytea((unsigned char *) PQgetvalue(res, 0, 0),
|
||||
result_size);
|
||||
PQclear(res);
|
||||
pfree(params[0]);
|
||||
pfree(params[1]);
|
||||
|
||||
return result;
|
||||
}
|
||||
+24
-4
@@ -121,11 +121,13 @@ static void
|
||||
backup_data_page(pgFile *file, XLogRecPtr prev_backup_start_lsn,
|
||||
BlockNumber blknum, BlockNumber nblocks,
|
||||
FILE *in, FILE *out,
|
||||
pg_crc32 *crc, int *n_skipped)
|
||||
pg_crc32 *crc, int *n_skipped,
|
||||
BackupMode backup_mode)
|
||||
{
|
||||
BackupPageHeader header;
|
||||
off_t offset;
|
||||
DataPage page; /* used as read buffer */
|
||||
DataPage *page_ptr = &page; /* used as read buffer */
|
||||
DataPage compressed_page; /* used as read buffer */
|
||||
size_t write_buffer_size;
|
||||
/* maximum size of write buffer */
|
||||
@@ -133,7 +135,7 @@ backup_data_page(pgFile *file, XLogRecPtr prev_backup_start_lsn,
|
||||
size_t read_len = 0;
|
||||
XLogRecPtr page_lsn;
|
||||
int try_checksum = 100;
|
||||
|
||||
bool page_is_invalid = true;
|
||||
header.block = blknum;
|
||||
offset = blknum * BLCKSZ;
|
||||
|
||||
@@ -156,6 +158,7 @@ backup_data_page(pgFile *file, XLogRecPtr prev_backup_start_lsn,
|
||||
{
|
||||
elog(LOG, "File %s, block %u, file was truncated",
|
||||
file->path, blknum);
|
||||
page_is_invalid = false;
|
||||
return;
|
||||
}
|
||||
else if (try_checksum)
|
||||
@@ -187,6 +190,7 @@ backup_data_page(pgFile *file, XLogRecPtr prev_backup_start_lsn,
|
||||
if (i == BLCKSZ)
|
||||
{
|
||||
elog(LOG, "File: %s blknum %u, empty page", file->path, blknum);
|
||||
page_is_invalid = false;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -238,10 +242,24 @@ backup_data_page(pgFile *file, XLogRecPtr prev_backup_start_lsn,
|
||||
file->path, blknum);
|
||||
}
|
||||
else
|
||||
{
|
||||
page_is_invalid = false;
|
||||
break; /* page header and checksum are correct */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
page_is_invalid = false;
|
||||
break; /* page header is correct and checksum check is disabled */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (page_is_invalid ||
|
||||
(backup_mode == BACKUP_MODE_DIFF_PTRACK))
|
||||
{
|
||||
size_t page_size = 0;
|
||||
page_ptr = pg_ptrack_get_block(file->relOid, blknum, &page_size);
|
||||
}
|
||||
|
||||
file->read_size += read_len;
|
||||
@@ -388,7 +406,8 @@ backup_data_file(const char *from_root, const char *to_root,
|
||||
for (blknum = 0; blknum < nblocks; blknum++)
|
||||
{
|
||||
backup_data_page(file, prev_backup_start_lsn, blknum,
|
||||
nblocks, in, out, &(file->crc), &n_blocks_skipped);
|
||||
nblocks, in, out, &(file->crc),
|
||||
&n_blocks_skipped, backup_mode);
|
||||
n_blocks_read++;
|
||||
}
|
||||
}
|
||||
@@ -400,7 +419,8 @@ backup_data_file(const char *from_root, const char *to_root,
|
||||
while (datapagemap_next(iter, &blknum))
|
||||
{
|
||||
backup_data_page(file, prev_backup_start_lsn, blknum,
|
||||
nblocks, in, out, &(file->crc), &n_blocks_skipped);
|
||||
nblocks, in, out, &(file->crc),
|
||||
&n_blocks_skipped, backup_mode);
|
||||
n_blocks_read++;
|
||||
}
|
||||
|
||||
|
||||
@@ -320,6 +320,8 @@ extern bool fileExists(const char *path);
|
||||
extern void process_block_change(ForkNumber forknum, RelFileNode rnode,
|
||||
BlockNumber blkno);
|
||||
|
||||
extern char *pg_ptrack_get_block(Oid relOid, BlockNumber blknum,
|
||||
size_t *result_size);
|
||||
/* in restore.c */
|
||||
extern int do_restore_or_validate(time_t target_backup_id,
|
||||
const char *target_time,
|
||||
|
||||
Reference in New Issue
Block a user