Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 0c2ce64

Browse files
committed
fix restore of the truncated files
1 parent b81f740 commit 0c2ce64

File tree

2 files changed

+65
-57
lines changed

2 files changed

+65
-57
lines changed

src/backup.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2736,9 +2736,6 @@ pg_ptrack_get_block(Oid dbOid,
27362736

27372737
val = PQgetvalue(res, 0, 0);
27382738

2739-
if (strcmp("x", val+1) == 0)
2740-
return NULL;
2741-
27422739
result = (char *) PQunescapeBytea((unsigned char *) PQgetvalue(res, 0, 0),
27432740
result_size);
27442741

src/data.c

Lines changed: 65 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ typedef struct BackupPageHeader
9999
int32 compressed_size;
100100
} BackupPageHeader;
101101

102+
/* Special value for compressed_size field */
103+
#define PageIsTruncated -1
104+
102105
/* Verify page's header */
103106
static bool
104107
parse_page(Page page, XLogRecPtr *lsn)
@@ -235,6 +238,8 @@ backup_data_page(pgFile *file, XLogRecPtr prev_backup_start_lsn,
235238
bool page_is_valid = false;
236239
BlockNumber absolute_blknum = file->segno * RELSEG_SIZE + blknum;
237240

241+
header.block = blknum;
242+
238243
/*
239244
* Read the page and verify its header and checksum.
240245
* Under high write load it's possible that we've read partly
@@ -248,19 +253,23 @@ backup_data_page(pgFile *file, XLogRecPtr prev_backup_start_lsn,
248253
in, page);
249254

250255
try_again--;
251-
/* This block was truncated.*/
252256
if (result == 0)
253257
{
254-
header.compressed_size = -1;
258+
/* This block was truncated.*/
259+
// header.compressed_size = PageIsTruncated;
260+
// page_is_valid = true;
261+
/* Page is not actually valid, but it is absent
262+
* and we're not going to reread it or validate */
263+
//elog(WARNING, "backup blkno %u. PageIsTruncated", blknum);
255264
}
256265

257266
if (result == 1)
258267
page_is_valid = true;
259268
}
260269
}
261270

262-
if (!page_is_valid ||
263-
(backup_mode == BACKUP_MODE_DIFF_PTRACK))
271+
if ((!page_is_valid)
272+
|| (backup_mode == BACKUP_MODE_DIFF_PTRACK))
264273
{
265274
size_t page_size = 0;
266275
PageHeader phdr = (PageHeader) page;
@@ -273,7 +282,8 @@ backup_data_page(pgFile *file, XLogRecPtr prev_backup_start_lsn,
273282
if (page == NULL)
274283
{
275284
/* This block was truncated.*/
276-
header.compressed_size = -1;
285+
header.compressed_size = PageIsTruncated;
286+
elog(WARNING, "backup blkno %u. reread PageIsTruncated", blknum);
277287
}
278288
else if (page_size != BLCKSZ)
279289
{
@@ -283,46 +293,58 @@ backup_data_page(pgFile *file, XLogRecPtr prev_backup_start_lsn,
283293
}
284294
else
285295
{
296+
/*
297+
* We must set checksum here, because it is outdated
298+
* in the block recieved from shared buffers.
299+
*/
286300
((PageHeader) page)->pd_checksum = pg_checksum_page(page, absolute_blknum);
287301
}
288302
}
289303

290-
if (header.compressed_size != -1)
304+
if (header.compressed_size != PageIsTruncated)
291305
{
292306
file->read_size += BLCKSZ;
293307

294308
compressed_page = malloc(BLCKSZ);
295-
header.block = blknum;
296309
header.compressed_size = do_compress(compressed_page, BLCKSZ,
297310
page, BLCKSZ, compress_alg);
298311

299312
file->compress_alg = compress_alg;
300313

314+
/* if compression failed, reset size of the block */
315+
if (header.compressed_size == -1)
316+
header.compressed_size = BLCKSZ;
317+
318+
301319
Assert (header.compressed_size <= BLCKSZ);
302-
write_buffer_size = sizeof(header);
303320
}
304321

305-
/* The page was successfully compressed */
306-
if (header.compressed_size > 0)
322+
write_buffer_size = sizeof(header);
323+
324+
/* The page was truncated. Write only header
325+
/* to know that we must truncate restored file */
326+
if (header.compressed_size == PageIsTruncated)
307327
{
308328
memcpy(write_buffer, &header, sizeof(header));
309-
memcpy(write_buffer + sizeof(header), compressed_page, header.compressed_size);
310-
write_buffer_size += MAXALIGN(header.compressed_size);
311329
}
312330
/* The page compression failed. Write it as is. */
313-
else if (header.compressed_size == 0)
331+
else if (header.compressed_size == BLCKSZ || header.compressed_size == 0)
314332
{
315-
header.compressed_size = BLCKSZ;
316333
memcpy(write_buffer, &header, sizeof(header));
317334
memcpy(write_buffer + sizeof(header), page, BLCKSZ);
318335
write_buffer_size += header.compressed_size;
319336
}
320-
/* The page is not found, it mean that it was truncated. */
321-
else if (header.compressed_size == -1)
337+
/* The page was successfully compressed */
338+
else if (header.compressed_size > 0)
322339
{
323340
memcpy(write_buffer, &header, sizeof(header));
341+
memcpy(write_buffer + sizeof(header), compressed_page, header.compressed_size);
342+
write_buffer_size += MAXALIGN(header.compressed_size);
324343
}
325344

345+
// elog(WARNING, "backup blkno %u, compressed_size %d write_buffer_size %ld",
346+
// blknum, header.compressed_size, write_buffer_size);
347+
326348
/* Update CRC */
327349
COMP_CRC32C(*crc, &write_buffer, write_buffer_size);
328350

@@ -377,16 +399,6 @@ backup_data_file(const char *from_root, const char *to_root,
377399
return false;
378400
}
379401

380-
if ((backup_mode == BACKUP_MODE_DIFF_PAGE ||
381-
backup_mode == BACKUP_MODE_DIFF_PTRACK) &&
382-
file->pagemap.bitmapsize == PageBitmapIsAbsent)
383-
{
384-
/*
385-
* TODO COMPARE FILE CHECKSUMM to this file version from previous backup
386-
* if they are equal, skip this file
387-
*/
388-
}
389-
390402
/* reset size summary */
391403
file->read_size = 0;
392404
file->write_size = 0;
@@ -566,30 +578,38 @@ restore_data_file(const char *from_root,
566578
}
567579

568580
if (header.block < blknum)
569-
elog(ERROR, "backup is broken at block %u", blknum);
581+
elog(ERROR, "backup is broken at file->path %s block %u",file->path, blknum);
570582

571-
if (header.compressed_size != -1)
583+
if (header.compressed_size == PageIsTruncated)
572584
{
573-
//elog(VERBOSE, "file %s, header compressed size %d", file->path, header.compressed_size);
574-
Assert(header.compressed_size <= BLCKSZ);
585+
/*
586+
* Backup contains information that this block was truncated.
587+
* Truncate file to this length.
588+
*/
589+
ftruncate(fileno(out), header.block * BLCKSZ);
590+
elog(WARNING, "truncate file %s to block %u", file->path, header.block);
591+
break;
592+
}
575593

576-
read_len = fread(compressed_page.data, 1,
577-
MAXALIGN(header.compressed_size), in);
578-
if (read_len != MAXALIGN(header.compressed_size))
579-
elog(ERROR, "cannot read block %u of \"%s\" read %lu of %d",
580-
blknum, file->path, read_len, header.compressed_size);
594+
//elog(VERBOSE, "file %s, header compressed size %d", file->path, header.compressed_size);
595+
Assert(header.compressed_size <= BLCKSZ);
581596

582-
if (header.compressed_size != BLCKSZ)
583-
{
584-
size_t uncompressed_size = 0;
597+
read_len = fread(compressed_page.data, 1,
598+
MAXALIGN(header.compressed_size), in);
599+
if (read_len != MAXALIGN(header.compressed_size))
600+
elog(ERROR, "cannot read block %u of \"%s\" read %lu of %d",
601+
blknum, file->path, read_len, header.compressed_size);
602+
603+
if (header.compressed_size != BLCKSZ)
604+
{
605+
size_t uncompressed_size = 0;
585606

586-
uncompressed_size = do_decompress(page.data, BLCKSZ,
587-
compressed_page.data,
588-
header.compressed_size, file->compress_alg);
607+
uncompressed_size = do_decompress(page.data, BLCKSZ,
608+
compressed_page.data,
609+
header.compressed_size, file->compress_alg);
589610

590-
if (uncompressed_size != BLCKSZ)
591-
elog(ERROR, "page uncompressed to %ld bytes. != BLCKSZ", uncompressed_size);
592-
}
611+
if (uncompressed_size != BLCKSZ)
612+
elog(ERROR, "page uncompressed to %ld bytes. != BLCKSZ", uncompressed_size);
593613
}
594614

595615
/*
@@ -600,16 +620,7 @@ restore_data_file(const char *from_root,
600620
elog(ERROR, "cannot seek block %u of \"%s\": %s",
601621
blknum, to_path, strerror(errno));
602622

603-
if (header.compressed_size == -1)
604-
{
605-
/*
606-
* Backup contains information that this block was truncated.
607-
* Truncate file to this length.
608-
*/
609-
ftruncate(fileno(out), blknum * BLCKSZ);
610-
break;
611-
}
612-
else if (header.compressed_size < BLCKSZ)
623+
if (header.compressed_size < BLCKSZ)
613624
{
614625
if (fwrite(page.data, 1, BLCKSZ, out) != BLCKSZ)
615626
elog(ERROR, "cannot write block %u of \"%s\": %s",

0 commit comments

Comments
 (0)