aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/transam/xlogreader.c
diff options
context:
space:
mode:
authorMichael Paquier <michael@paquier.xyz>2022-09-09 10:00:40 +0900
committerMichael Paquier <michael@paquier.xyz>2022-09-09 10:00:40 +0900
commitdf4a056619a7e9868ec43a15e2088ff8ccf94471 (patch)
tree89ee318b5d63a27bb2d13475678f398d5dd2103a /src/backend/access/transam/xlogreader.c
parentd977ffd923d207164eef78ed107d5293aee6c660 (diff)
downloadpostgresql-df4a056619a7e9868ec43a15e2088ff8ccf94471.tar.gz
postgresql-df4a056619a7e9868ec43a15e2088ff8ccf94471.zip
Add more error context to RestoreBlockImage() and consume it
On failure in restoring a block image, no details were provided, while it is possible to see failure with an inconsistent record state, a failure in processing decompression or a failure in decompression because a build does not support this option. RestoreBlockImage() is used in two code paths in the backend code, during recovery and when checking a page consistency after applying masking, and both places are changed to consume the error message produced by the internal routine when it returns a false status. All the error messages are reported under ERRCODE_INTERNAL_ERROR, that gets used also when attempting to access a page compressed by a method not supported by the build attempting the decompression. This is something that can happen in core when doing physical replication with primary and standby using inconsistent build options, for example. This routine is available since 2c03216d and it has never provided any context about the error happening when it failed. This change is justified even more after 57aa5b2, that introduced compression of FPWs in WAL. Reported-by: Justin Prysby Author: Michael Paquier Discussion: https://postgr.es/m/20220905002320.GD31833@telsasoft.com Backpatch-through: 15
Diffstat (limited to 'src/backend/access/transam/xlogreader.c')
-rw-r--r--src/backend/access/transam/xlogreader.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c
index cd3dd8cc5c0..c4fbc37c74b 100644
--- a/src/backend/access/transam/xlogreader.c
+++ b/src/backend/access/transam/xlogreader.c
@@ -2036,7 +2036,8 @@ XLogRecGetBlockData(XLogReaderState *record, uint8 block_id, Size *len)
/*
* Restore a full-page image from a backup block attached to an XLOG record.
*
- * Returns true if a full-page image is restored.
+ * Returns true if a full-page image is restored, and false on failure with
+ * an error to be consumed by the caller.
*/
bool
RestoreBlockImage(XLogReaderState *record, uint8 block_id, char *page)
@@ -2047,9 +2048,20 @@ RestoreBlockImage(XLogReaderState *record, uint8 block_id, char *page)
if (block_id > record->record->max_block_id ||
!record->record->blocks[block_id].in_use)
+ {
+ report_invalid_record(record,
+ "could not restore image at %X/%X with invalid block %d specified",
+ LSN_FORMAT_ARGS(record->ReadRecPtr),
+ block_id);
return false;
+ }
if (!record->record->blocks[block_id].has_image)
+ {
+ report_invalid_record(record, "could not restore image at %X/%X with invalid state, block %d",
+ LSN_FORMAT_ARGS(record->ReadRecPtr),
+ block_id);
return false;
+ }
bkpb = &record->record->blocks[block_id];
ptr = bkpb->bkp_image;
@@ -2072,7 +2084,7 @@ RestoreBlockImage(XLogReaderState *record, uint8 block_id, char *page)
bkpb->bimg_len, BLCKSZ - bkpb->hole_length) <= 0)
decomp_success = false;
#else
- report_invalid_record(record, "image at %X/%X compressed with %s not supported by build, block %d",
+ report_invalid_record(record, "could not restore image at %X/%X compressed with %s not supported by build, block %d",
LSN_FORMAT_ARGS(record->ReadRecPtr),
"LZ4",
block_id);
@@ -2089,7 +2101,7 @@ RestoreBlockImage(XLogReaderState *record, uint8 block_id, char *page)
if (ZSTD_isError(decomp_result))
decomp_success = false;
#else
- report_invalid_record(record, "image at %X/%X compressed with %s not supported by build, block %d",
+ report_invalid_record(record, "could not restore image at %X/%X compressed with %s not supported by build, block %d",
LSN_FORMAT_ARGS(record->ReadRecPtr),
"zstd",
block_id);
@@ -2098,7 +2110,7 @@ RestoreBlockImage(XLogReaderState *record, uint8 block_id, char *page)
}
else
{
- report_invalid_record(record, "image at %X/%X compressed with unknown method, block %d",
+ report_invalid_record(record, "could not restore image at %X/%X compressed with unknown method, block %d",
LSN_FORMAT_ARGS(record->ReadRecPtr),
block_id);
return false;
@@ -2106,7 +2118,7 @@ RestoreBlockImage(XLogReaderState *record, uint8 block_id, char *page)
if (!decomp_success)
{
- report_invalid_record(record, "invalid compressed image at %X/%X, block %d",
+ report_invalid_record(record, "could not decompress image at %X/%X, block %d",
LSN_FORMAT_ARGS(record->ReadRecPtr),
block_id);
return false;