1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-09 06:21:09 +03:00

Add contrib/pg_walinspect.

Provides similar functionality to pg_waldump, but from a SQL interface
rather than a separate utility.

Author: Bharath Rupireddy
Reviewed-by: Greg Stark, Kyotaro Horiguchi, Andres Freund, Ashutosh Sharma, Nitin Jadhav, RKN Sai Krishna
Discussion: https://postgr.es/m/CALj2ACUGUYXsEQdKhEdsBzhGEyF3xggvLdD8C0VT72TNEfOiog%40mail.gmail.com
This commit is contained in:
Jeff Davis
2022-04-08 00:02:10 -07:00
parent 708007dced
commit 2258e76f90
25 changed files with 1675 additions and 204 deletions

View File

@@ -200,3 +200,133 @@ xlog_identify(uint8 info)
return id;
}
/*
* Returns a string giving information about all the blocks in an
* XLogRecord.
*/
void
XLogRecGetBlockRefInfo(XLogReaderState *record, bool pretty,
bool detailed_format, StringInfo buf,
uint32 *fpi_len)
{
int block_id;
Assert(record != NULL);
if (detailed_format && pretty)
appendStringInfoChar(buf, '\n');
for (block_id = 0; block_id <= XLogRecMaxBlockId(record); block_id++)
{
RelFileNode rnode = {InvalidOid, InvalidOid, InvalidOid};
ForkNumber forknum = InvalidForkNumber;
BlockNumber blk = InvalidBlockNumber;
if (!XLogRecHasBlockRef(record, block_id))
continue;
XLogRecGetBlockTag(record, block_id, &rnode, &forknum, &blk);
if (detailed_format)
{
/* Get block references in detailed format. */
if (pretty)
appendStringInfoChar(buf, '\t');
else if (block_id > 0)
appendStringInfoChar(buf, ' ');
appendStringInfo(buf,
"blkref #%d: rel %u/%u/%u fork %s blk %u",
block_id,
rnode.spcNode, rnode.dbNode, rnode.relNode,
forkNames[forknum],
blk);
if (XLogRecHasBlockImage(record, block_id))
{
uint8 bimg_info = XLogRecGetBlock(record, block_id)->bimg_info;
/* Calculate the amount of FPI data in the record. */
if (fpi_len)
*fpi_len += XLogRecGetBlock(record, block_id)->bimg_len;
if (BKPIMAGE_COMPRESSED(bimg_info))
{
const char *method;
if ((bimg_info & BKPIMAGE_COMPRESS_PGLZ) != 0)
method = "pglz";
else if ((bimg_info & BKPIMAGE_COMPRESS_LZ4) != 0)
method = "lz4";
else if ((bimg_info & BKPIMAGE_COMPRESS_ZSTD) != 0)
method = "zstd";
else
method = "unknown";
appendStringInfo(buf,
" (FPW%s); hole: offset: %u, length: %u, "
"compression saved: %u, method: %s",
XLogRecBlockImageApply(record, block_id) ?
"" : " for WAL verification",
XLogRecGetBlock(record, block_id)->hole_offset,
XLogRecGetBlock(record, block_id)->hole_length,
BLCKSZ -
XLogRecGetBlock(record, block_id)->hole_length -
XLogRecGetBlock(record, block_id)->bimg_len,
method);
}
else
{
appendStringInfo(buf,
" (FPW%s); hole: offset: %u, length: %u",
XLogRecBlockImageApply(record, block_id) ?
"" : " for WAL verification",
XLogRecGetBlock(record, block_id)->hole_offset,
XLogRecGetBlock(record, block_id)->hole_length);
}
}
if (pretty)
appendStringInfoChar(buf, '\n');
}
else
{
/* Get block references in short format. */
if (forknum != MAIN_FORKNUM)
{
appendStringInfo(buf,
", blkref #%d: rel %u/%u/%u fork %s blk %u",
block_id,
rnode.spcNode, rnode.dbNode, rnode.relNode,
forkNames[forknum],
blk);
}
else
{
appendStringInfo(buf,
", blkref #%d: rel %u/%u/%u blk %u",
block_id,
rnode.spcNode, rnode.dbNode, rnode.relNode,
blk);
}
if (XLogRecHasBlockImage(record, block_id))
{
/* Calculate the amount of FPI data in the record. */
if (fpi_len)
*fpi_len += XLogRecGetBlock(record, block_id)->bimg_len;
if (XLogRecBlockImageApply(record, block_id))
appendStringInfo(buf, " FPW");
else
appendStringInfo(buf, " FPW for WAL verification");
}
}
}
if (!detailed_format && pretty)
appendStringInfoChar(buf, '\n');
}