Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit d3ca4b4

Browse files
committed
Fix record length computation in pg_waldump/xlogdump.
The current method of computing the record length (excluding the lenght of full-page images) has been wrong since the WAL format has been revamped in 2c03216. Only the main record's length was counted, but that can be significantly too little if there's data associated with further blocks. Fix by computing the record length as total_lenght - fpi_length. Reported-By: Chen Huajun Bug: #14687 Reviewed-By: Heikki Linnakangas Discussion: https://postgr.es/m/20170603165939.1436.58887@wrigleys.postgresql.org Backpatch: 9.5-
1 parent b64ff9c commit d3ca4b4

File tree

1 file changed

+34
-15
lines changed

1 file changed

+34
-15
lines changed

src/bin/pg_xlogdump/pg_xlogdump.c

+34-15
Original file line numberDiff line numberDiff line change
@@ -363,37 +363,52 @@ XLogDumpReadPage(XLogReaderState *state, XLogRecPtr targetPagePtr, int reqLen,
363363
}
364364

365365
/*
366-
* Store per-rmgr and per-record statistics for a given record.
366+
* Calculate the size of a record, split into !FPI and FPI parts.
367367
*/
368368
static void
369-
XLogDumpCountRecord(XLogDumpConfig *config, XLogDumpStats *stats,
370-
XLogReaderState *record)
369+
XLogDumpRecordLen(XLogReaderState *record, uint32 *rec_len, uint32 *fpi_len)
371370
{
372-
RmgrId rmid;
373-
uint8 recid;
374-
uint32 rec_len;
375-
uint32 fpi_len;
376371
int block_id;
377372

378-
stats->count++;
379-
380-
rmid = XLogRecGetRmid(record);
381-
rec_len = XLogRecGetDataLen(record) + SizeOfXLogRecord;
382-
383373
/*
384374
* Calculate the amount of FPI data in the record.
385375
*
386376
* XXX: We peek into xlogreader's private decoded backup blocks for the
387377
* bimg_len indicating the length of FPI data. It doesn't seem worth it to
388378
* add an accessor macro for this.
389379
*/
390-
fpi_len = 0;
380+
*fpi_len = 0;
391381
for (block_id = 0; block_id <= record->max_block_id; block_id++)
392382
{
393383
if (XLogRecHasBlockImage(record, block_id))
394-
fpi_len += record->blocks[block_id].bimg_len;
384+
*fpi_len += record->blocks[block_id].bimg_len;
395385
}
396386

387+
/*
388+
* Calculate the length of the record as the total length - the length of
389+
* all the block images.
390+
*/
391+
*rec_len = XLogRecGetTotalLen(record) - *fpi_len;
392+
}
393+
394+
/*
395+
* Store per-rmgr and per-record statistics for a given record.
396+
*/
397+
static void
398+
XLogDumpCountRecord(XLogDumpConfig *config, XLogDumpStats *stats,
399+
XLogReaderState *record)
400+
{
401+
RmgrId rmid;
402+
uint8 recid;
403+
uint32 rec_len;
404+
uint32 fpi_len;
405+
406+
stats->count++;
407+
408+
rmid = XLogRecGetRmid(record);
409+
410+
XLogDumpRecordLen(record, &rec_len, &fpi_len);
411+
397412
/* Update per-rmgr statistics */
398413

399414
stats->rmgr_stats[rmid].count++;
@@ -422,20 +437,24 @@ XLogDumpDisplayRecord(XLogDumpConfig *config, XLogReaderState *record)
422437
{
423438
const char *id;
424439
const RmgrDescData *desc = &RmgrDescTable[XLogRecGetRmid(record)];
440+
uint32 rec_len;
441+
uint32 fpi_len;
425442
RelFileNode rnode;
426443
ForkNumber forknum;
427444
BlockNumber blk;
428445
int block_id;
429446
uint8 info = XLogRecGetInfo(record);
430447
XLogRecPtr xl_prev = XLogRecGetPrev(record);
431448

449+
XLogDumpRecordLen(record, &rec_len, &fpi_len);
450+
432451
id = desc->rm_identify(info);
433452
if (id == NULL)
434453
id = psprintf("UNKNOWN (%x)", info & ~XLR_INFO_MASK);
435454

436455
printf("rmgr: %-11s len (rec/tot): %6u/%6u, tx: %10u, lsn: %X/%08X, prev %X/%08X, ",
437456
desc->rm_name,
438-
XLogRecGetDataLen(record), XLogRecGetTotalLen(record),
457+
rec_len, XLogRecGetTotalLen(record),
439458
XLogRecGetXid(record),
440459
(uint32) (record->ReadRecPtr >> 32), (uint32) record->ReadRecPtr,
441460
(uint32) (xl_prev >> 32), (uint32) xl_prev);

0 commit comments

Comments
 (0)