|
18 | 18 | #include"postgres.h"
|
19 | 19 |
|
20 | 20 | #include<unistd.h>
|
| 21 | +#ifdefUSE_LZ4 |
| 22 | +#include<lz4.h> |
| 23 | +#endif |
21 | 24 |
|
22 | 25 | #include"access/transam.h"
|
23 | 26 | #include"access/xlog_internal.h"
|
@@ -1290,7 +1293,7 @@ DecodeXLogRecord(XLogReaderState *state, XLogRecord *record, char **errormsg)
|
1290 | 1293 |
|
1291 | 1294 | blk->apply_image= ((blk->bimg_info&BKPIMAGE_APPLY)!=0);
|
1292 | 1295 |
|
1293 |
| -if (blk->bimg_info&BKPIMAGE_IS_COMPRESSED) |
| 1296 | +if (BKPIMAGE_COMPRESSED(blk->bimg_info)) |
1294 | 1297 | {
|
1295 | 1298 | if (blk->bimg_info&BKPIMAGE_HAS_HOLE)
|
1296 | 1299 | COPY_HEADER_FIELD(&blk->hole_length,sizeof(uint16));
|
@@ -1335,29 +1338,28 @@ DecodeXLogRecord(XLogReaderState *state, XLogRecord *record, char **errormsg)
|
1335 | 1338 | }
|
1336 | 1339 |
|
1337 | 1340 | /*
|
1338 |
| - * cross-check that bimg_len < BLCKSZ if the IS_COMPRESSED |
1339 |
| - * flag is set. |
| 1341 | + * Cross-check that bimg_len < BLCKSZ if it is compressed. |
1340 | 1342 | */
|
1341 |
| -if ((blk->bimg_info&BKPIMAGE_IS_COMPRESSED)&& |
| 1343 | +if (BKPIMAGE_COMPRESSED(blk->bimg_info)&& |
1342 | 1344 | blk->bimg_len==BLCKSZ)
|
1343 | 1345 | {
|
1344 | 1346 | report_invalid_record(state,
|
1345 |
| -"BKPIMAGE_IS_COMPRESSED set, but block image length %u at %X/%X", |
| 1347 | +"BKPIMAGE_COMPRESSED set, but block image length %u at %X/%X", |
1346 | 1348 | (unsignedint)blk->bimg_len,
|
1347 | 1349 | LSN_FORMAT_ARGS(state->ReadRecPtr));
|
1348 | 1350 | gotoerr;
|
1349 | 1351 | }
|
1350 | 1352 |
|
1351 | 1353 | /*
|
1352 |
| - * cross-check that bimg_len = BLCKSZ if neither HAS_HOLEnor |
1353 |
| - *IS_COMPRESSED flag is set. |
| 1354 | + * cross-check that bimg_len = BLCKSZ if neither HAS_HOLEis |
| 1355 | + *set nor COMPRESSED(). |
1354 | 1356 | */
|
1355 | 1357 | if (!(blk->bimg_info&BKPIMAGE_HAS_HOLE)&&
|
1356 |
| -!(blk->bimg_info&BKPIMAGE_IS_COMPRESSED)&& |
| 1358 | +!BKPIMAGE_COMPRESSED(blk->bimg_info)&& |
1357 | 1359 | blk->bimg_len!=BLCKSZ)
|
1358 | 1360 | {
|
1359 | 1361 | report_invalid_record(state,
|
1360 |
| -"neither BKPIMAGE_HAS_HOLE norBKPIMAGE_IS_COMPRESSED set, but block image length is %u at %X/%X", |
| 1362 | +"neither BKPIMAGE_HAS_HOLE norBKPIMAGE_COMPRESSED set, but block image length is %u at %X/%X", |
1361 | 1363 | (unsignedint)blk->data_len,
|
1362 | 1364 | LSN_FORMAT_ARGS(state->ReadRecPtr));
|
1363 | 1365 | gotoerr;
|
@@ -1555,17 +1557,49 @@ RestoreBlockImage(XLogReaderState *record, uint8 block_id, char *page)
|
1555 | 1557 | bkpb=&record->blocks[block_id];
|
1556 | 1558 | ptr=bkpb->bkp_image;
|
1557 | 1559 |
|
1558 |
| -if (bkpb->bimg_info&BKPIMAGE_IS_COMPRESSED) |
| 1560 | +if (BKPIMAGE_COMPRESSED(bkpb->bimg_info)) |
1559 | 1561 | {
|
1560 | 1562 | /* If a backup block image is compressed, decompress it */
|
1561 |
| -if (pglz_decompress(ptr,bkpb->bimg_len,tmp.data, |
1562 |
| -BLCKSZ-bkpb->hole_length, true)<0) |
| 1563 | +booldecomp_success= true; |
| 1564 | + |
| 1565 | +if ((bkpb->bimg_info&BKPIMAGE_COMPRESS_PGLZ)!=0) |
| 1566 | +{ |
| 1567 | +if (pglz_decompress(ptr,bkpb->bimg_len,tmp.data, |
| 1568 | +BLCKSZ-bkpb->hole_length, true)<0) |
| 1569 | +decomp_success= false; |
| 1570 | +} |
| 1571 | +elseif ((bkpb->bimg_info&BKPIMAGE_COMPRESS_LZ4)!=0) |
| 1572 | +{ |
| 1573 | +#ifdefUSE_LZ4 |
| 1574 | +if (LZ4_decompress_safe(ptr,tmp.data, |
| 1575 | +bkpb->bimg_len,BLCKSZ-bkpb->hole_length) <=0) |
| 1576 | +decomp_success= false; |
| 1577 | +#else |
| 1578 | +report_invalid_record(record,"image at %X/%X compressed with %s not supported by build, block %d", |
| 1579 | + (uint32) (record->ReadRecPtr >>32), |
| 1580 | + (uint32)record->ReadRecPtr, |
| 1581 | +"LZ4", |
| 1582 | +block_id); |
| 1583 | +return false; |
| 1584 | +#endif |
| 1585 | +} |
| 1586 | +else |
| 1587 | +{ |
| 1588 | +report_invalid_record(record,"image at %X/%X compressed with unknown method, block %d", |
| 1589 | + (uint32) (record->ReadRecPtr >>32), |
| 1590 | + (uint32)record->ReadRecPtr, |
| 1591 | +block_id); |
| 1592 | +return false; |
| 1593 | +} |
| 1594 | + |
| 1595 | +if (!decomp_success) |
1563 | 1596 | {
|
1564 | 1597 | report_invalid_record(record,"invalid compressed image at %X/%X, block %d",
|
1565 | 1598 | LSN_FORMAT_ARGS(record->ReadRecPtr),
|
1566 | 1599 | block_id);
|
1567 | 1600 | return false;
|
1568 | 1601 | }
|
| 1602 | + |
1569 | 1603 | ptr=tmp.data;
|
1570 | 1604 | }
|
1571 | 1605 |
|
|