@@ -99,6 +99,9 @@ typedef struct BackupPageHeader
99
99
int32 compressed_size ;
100
100
} BackupPageHeader ;
101
101
102
+ /* Special value for compressed_size field */
103
+ #define PageIsTruncated -1
104
+
102
105
/* Verify page's header */
103
106
static bool
104
107
parse_page (Page page , XLogRecPtr * lsn )
@@ -235,6 +238,8 @@ backup_data_page(pgFile *file, XLogRecPtr prev_backup_start_lsn,
235
238
bool page_is_valid = false;
236
239
BlockNumber absolute_blknum = file -> segno * RELSEG_SIZE + blknum ;
237
240
241
+ header .block = blknum ;
242
+
238
243
/*
239
244
* Read the page and verify its header and checksum.
240
245
* 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,
248
253
in , page );
249
254
250
255
try_again -- ;
251
- /* This block was truncated.*/
252
256
if (result == 0 )
253
257
{
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);
255
264
}
256
265
257
266
if (result == 1 )
258
267
page_is_valid = true;
259
268
}
260
269
}
261
270
262
- if (!page_is_valid ||
263
- (backup_mode == BACKUP_MODE_DIFF_PTRACK ))
271
+ if (( !page_is_valid )
272
+ || (backup_mode == BACKUP_MODE_DIFF_PTRACK ))
264
273
{
265
274
size_t page_size = 0 ;
266
275
PageHeader phdr = (PageHeader ) page ;
@@ -273,7 +282,8 @@ backup_data_page(pgFile *file, XLogRecPtr prev_backup_start_lsn,
273
282
if (page == NULL )
274
283
{
275
284
/* This block was truncated.*/
276
- header .compressed_size = -1 ;
285
+ header .compressed_size = PageIsTruncated ;
286
+ elog (WARNING , "backup blkno %u. reread PageIsTruncated" , blknum );
277
287
}
278
288
else if (page_size != BLCKSZ )
279
289
{
@@ -283,46 +293,58 @@ backup_data_page(pgFile *file, XLogRecPtr prev_backup_start_lsn,
283
293
}
284
294
else
285
295
{
296
+ /*
297
+ * We must set checksum here, because it is outdated
298
+ * in the block recieved from shared buffers.
299
+ */
286
300
((PageHeader ) page )-> pd_checksum = pg_checksum_page (page , absolute_blknum );
287
301
}
288
302
}
289
303
290
- if (header .compressed_size != -1 )
304
+ if (header .compressed_size != PageIsTruncated )
291
305
{
292
306
file -> read_size += BLCKSZ ;
293
307
294
308
compressed_page = malloc (BLCKSZ );
295
- header .block = blknum ;
296
309
header .compressed_size = do_compress (compressed_page , BLCKSZ ,
297
310
page , BLCKSZ , compress_alg );
298
311
299
312
file -> compress_alg = compress_alg ;
300
313
314
+ /* if compression failed, reset size of the block */
315
+ if (header .compressed_size == -1 )
316
+ header .compressed_size = BLCKSZ ;
317
+
318
+
301
319
Assert (header .compressed_size <= BLCKSZ );
302
- write_buffer_size = sizeof (header );
303
320
}
304
321
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 )
307
327
{
308
328
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 );
311
329
}
312
330
/* 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 )
314
332
{
315
- header .compressed_size = BLCKSZ ;
316
333
memcpy (write_buffer , & header , sizeof (header ));
317
334
memcpy (write_buffer + sizeof (header ), page , BLCKSZ );
318
335
write_buffer_size += header .compressed_size ;
319
336
}
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 )
322
339
{
323
340
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 );
324
343
}
325
344
345
+ // elog(WARNING, "backup blkno %u, compressed_size %d write_buffer_size %ld",
346
+ // blknum, header.compressed_size, write_buffer_size);
347
+
326
348
/* Update CRC */
327
349
COMP_CRC32C (* crc , & write_buffer , write_buffer_size );
328
350
@@ -377,16 +399,6 @@ backup_data_file(const char *from_root, const char *to_root,
377
399
return false;
378
400
}
379
401
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
-
390
402
/* reset size summary */
391
403
file -> read_size = 0 ;
392
404
file -> write_size = 0 ;
@@ -566,30 +578,38 @@ restore_data_file(const char *from_root,
566
578
}
567
579
568
580
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 );
570
582
571
- if (header .compressed_size != -1 )
583
+ if (header .compressed_size == PageIsTruncated )
572
584
{
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
+ }
575
593
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 );
581
596
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 ;
585
606
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 );
589
610
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 );
593
613
}
594
614
595
615
/*
@@ -600,16 +620,7 @@ restore_data_file(const char *from_root,
600
620
elog (ERROR , "cannot seek block %u of \"%s\": %s" ,
601
621
blknum , to_path , strerror (errno ));
602
622
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 )
613
624
{
614
625
if (fwrite (page .data , 1 , BLCKSZ , out ) != BLCKSZ )
615
626
elog (ERROR , "cannot write block %u of \"%s\": %s" ,
0 commit comments