|
18 | 18 | #include "postgres.h"
|
19 | 19 |
|
20 | 20 | #include <unistd.h>
|
| 21 | +#ifdef USE_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 | (unsigned int) blk->bimg_len,
|
1347 | 1349 | LSN_FORMAT_ARGS(state->ReadRecPtr));
|
1348 | 1350 | goto err;
|
1349 | 1351 | }
|
1350 | 1352 |
|
1351 | 1353 | /*
|
1352 |
| - * cross-check that bimg_len = BLCKSZ if neither HAS_HOLE nor |
1353 |
| - * IS_COMPRESSED flag is set. |
| 1354 | + * cross-check that bimg_len = BLCKSZ if neither HAS_HOLE is |
| 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 nor BKPIMAGE_IS_COMPRESSED set, but block image length is %u at %X/%X", |
| 1362 | + "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_COMPRESSED set, but block image length is %u at %X/%X", |
1361 | 1363 | (unsigned int) blk->data_len,
|
1362 | 1364 | LSN_FORMAT_ARGS(state->ReadRecPtr));
|
1363 | 1365 | goto err;
|
@@ -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 | + bool decomp_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 | + else if ((bkpb->bimg_info & BKPIMAGE_COMPRESS_LZ4) != 0) |
| 1572 | + { |
| 1573 | +#ifdef USE_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 |
|
|
0 commit comments