|
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