|
17 | 17 |
|
18 | 18 | #include "access/xlogreader.h"
|
19 | 19 | #include "access/xlogrecord.h"
|
| 20 | +#include "access/xlog_internal.h" |
20 | 21 | #include "access/transam.h"
|
21 | 22 | #include "common/fe_memutils.h"
|
22 | 23 | #include "getopt_long.h"
|
@@ -343,90 +344,117 @@ XLogDumpReadPage(XLogReaderState *state, XLogRecPtr targetPagePtr, int reqLen,
|
343 | 344 | * Store per-rmgr and per-record statistics for a given record.
|
344 | 345 | */
|
345 | 346 | static void
|
346 |
| -XLogDumpCountRecord(XLogDumpConfig *config, XLogDumpStats *stats, XLogRecPtr ReadRecPtr, XLogRecord *record) |
| 347 | +XLogDumpCountRecord(XLogDumpConfig *config, XLogDumpStats *stats, |
| 348 | + XLogReaderState *record) |
347 | 349 | {
|
348 | 350 | RmgrId rmid;
|
349 | 351 | uint8 recid;
|
| 352 | + uint32 rec_len; |
| 353 | + uint32 fpi_len; |
350 | 354 |
|
351 | 355 | stats->count++;
|
352 | 356 |
|
353 | 357 | /* Update per-rmgr statistics */
|
354 | 358 |
|
355 |
| - rmid = record->xl_rmid; |
| 359 | + rmid = XLogRecGetRmid(record); |
| 360 | + rec_len = XLogRecGetDataLen(record) + SizeOfXLogRecord; |
| 361 | + fpi_len = record->decoded_record->xl_tot_len - rec_len; |
356 | 362 |
|
357 | 363 | stats->rmgr_stats[rmid].count++;
|
358 |
| - stats->rmgr_stats[rmid].rec_len += |
359 |
| - record->xl_len + SizeOfXLogRecord; |
360 |
| - stats->rmgr_stats[rmid].fpi_len += |
361 |
| - record->xl_tot_len - (record->xl_len + SizeOfXLogRecord); |
| 364 | + stats->rmgr_stats[rmid].rec_len += rec_len; |
| 365 | + stats->rmgr_stats[rmid].fpi_len += fpi_len; |
362 | 366 |
|
363 | 367 | /*
|
364 | 368 | * Update per-record statistics, where the record is identified by a
|
365 |
| - * combination of the RmgrId and the four bits of the xl_info field |
366 |
| - * that are the rmgr's domain (resulting in sixteen possible entries |
367 |
| - * per RmgrId). |
| 369 | + * combination of the RmgrId and the four bits of the xl_info field that |
| 370 | + * are the rmgr's domain (resulting in sixteen possible entries per |
| 371 | + * RmgrId). |
368 | 372 | */
|
369 | 373 |
|
370 |
| - recid = record->xl_info >> 4; |
| 374 | + recid = XLogRecGetInfo(record) >> 4; |
371 | 375 |
|
372 | 376 | stats->record_stats[rmid][recid].count++;
|
373 |
| - stats->record_stats[rmid][recid].rec_len += |
374 |
| - record->xl_len + SizeOfXLogRecord; |
375 |
| - stats->record_stats[rmid][recid].fpi_len += |
376 |
| - record->xl_tot_len - (record->xl_len + SizeOfXLogRecord); |
| 377 | + stats->record_stats[rmid][recid].rec_len += rec_len; |
| 378 | + stats->record_stats[rmid][recid].fpi_len += fpi_len; |
377 | 379 | }
|
378 | 380 |
|
379 | 381 | /*
|
380 | 382 | * Print a record to stdout
|
381 | 383 | */
|
382 | 384 | static void
|
383 |
| -XLogDumpDisplayRecord(XLogDumpConfig *config, XLogRecPtr ReadRecPtr, XLogRecord *record) |
| 385 | +XLogDumpDisplayRecord(XLogDumpConfig *config, XLogReaderState *record) |
384 | 386 | {
|
385 |
| - const char *id; |
386 |
| - const RmgrDescData *desc = &RmgrDescTable[record->xl_rmid]; |
387 |
| - |
388 |
| - id = desc->rm_identify(record->xl_info); |
| 387 | + const char *id; |
| 388 | + const RmgrDescData *desc = &RmgrDescTable[XLogRecGetRmid(record)]; |
| 389 | + RelFileNode rnode; |
| 390 | + ForkNumber forknum; |
| 391 | + BlockNumber blk; |
| 392 | + int block_id; |
| 393 | + uint8 info = XLogRecGetInfo(record); |
| 394 | + XLogRecPtr xl_prev = XLogRecGetPrev(record); |
| 395 | + |
| 396 | + id = desc->rm_identify(info); |
389 | 397 | if (id == NULL)
|
390 |
| - id = psprintf("UNKNOWN (%x)", record->xl_info & ~XLR_INFO_MASK); |
| 398 | + id = psprintf("UNKNOWN (%x)", info & ~XLR_INFO_MASK); |
391 | 399 |
|
392 |
| - printf("rmgr: %-11s len (rec/tot): %6u/%6u, tx: %10u, lsn: %X/%08X, prev %X/%08X, bkp: %u%u%u%u, desc: %s ", |
| 400 | + printf("rmgr: %-11s len (rec/tot): %6u/%6u, tx: %10u, lsn: %X/%08X, prev %X/%08X, ", |
393 | 401 | desc->rm_name,
|
394 |
| - record->xl_len, record->xl_tot_len, |
395 |
| - record->xl_xid, |
396 |
| - (uint32) (ReadRecPtr >> 32), (uint32) ReadRecPtr, |
397 |
| - (uint32) (record->xl_prev >> 32), (uint32) record->xl_prev, |
398 |
| - !!(XLR_BKP_BLOCK(0) & record->xl_info), |
399 |
| - !!(XLR_BKP_BLOCK(1) & record->xl_info), |
400 |
| - !!(XLR_BKP_BLOCK(2) & record->xl_info), |
401 |
| - !!(XLR_BKP_BLOCK(3) & record->xl_info), |
402 |
| - id); |
| 402 | + XLogRecGetDataLen(record), XLogRecGetTotalLen(record), |
| 403 | + XLogRecGetXid(record), |
| 404 | + (uint32) (record->ReadRecPtr >> 32), (uint32) record->ReadRecPtr, |
| 405 | + (uint32) (xl_prev >> 32), (uint32) xl_prev); |
| 406 | + printf("desc: %s ", id); |
403 | 407 |
|
404 | 408 | /* the desc routine will printf the description directly to stdout */
|
405 | 409 | desc->rm_desc(NULL, record);
|
406 | 410 |
|
407 |
| - putchar('\n'); |
408 |
| - |
409 |
| - if (config->bkp_details) |
| 411 | + if (!config->bkp_details) |
410 | 412 | {
|
411 |
| - int bkpnum; |
412 |
| - char *blk = (char *) XLogRecGetData(record) + record->xl_len; |
413 |
| - |
414 |
| - for (bkpnum = 0; bkpnum < XLR_MAX_BKP_BLOCKS; bkpnum++) |
| 413 | + /* print block references (short format) */ |
| 414 | + for (block_id = 0; block_id <= record->max_block_id; block_id++) |
415 | 415 | {
|
416 |
| - BkpBlock bkpb; |
417 |
| - |
418 |
| - if (!(XLR_BKP_BLOCK(bkpnum) & record->xl_info)) |
| 416 | + if (!XLogRecHasBlockRef(record, block_id)) |
419 | 417 | continue;
|
420 | 418 |
|
421 |
| - memcpy(&bkpb, blk, sizeof(BkpBlock)); |
422 |
| - blk += sizeof(BkpBlock); |
423 |
| - blk += BLCKSZ - bkpb.hole_length; |
| 419 | + XLogRecGetBlockTag(record, block_id, &rnode, &forknum, &blk); |
| 420 | + if (forknum != MAIN_FORKNUM) |
| 421 | + printf(", blkref #%u: rel %u/%u/%u fork %s blk %u", |
| 422 | + block_id, |
| 423 | + rnode.spcNode, rnode.dbNode, rnode.relNode, |
| 424 | + forkNames[forknum], |
| 425 | + blk); |
| 426 | + else |
| 427 | + printf(", blkref #%u: rel %u/%u/%u blk %u", |
| 428 | + block_id, |
| 429 | + rnode.spcNode, rnode.dbNode, rnode.relNode, |
| 430 | + blk); |
| 431 | + if (XLogRecHasBlockImage(record, block_id)) |
| 432 | + printf(" FPW"); |
| 433 | + } |
| 434 | + putchar('\n'); |
| 435 | + } |
| 436 | + else |
| 437 | + { |
| 438 | + /* print block references (detailed format) */ |
| 439 | + putchar('\n'); |
| 440 | + for (block_id = 0; block_id <= record->max_block_id; block_id++) |
| 441 | + { |
| 442 | + if (!XLogRecHasBlockRef(record, block_id)) |
| 443 | + continue; |
424 | 444 |
|
425 |
| - printf("\tbackup bkp #%u; rel %u/%u/%u; fork: %s; block: %u; hole: offset: %u, length: %u\n", |
426 |
| - bkpnum, |
427 |
| - bkpb.node.spcNode, bkpb.node.dbNode, bkpb.node.relNode, |
428 |
| - forkNames[bkpb.fork], |
429 |
| - bkpb.block, bkpb.hole_offset, bkpb.hole_length); |
| 445 | + XLogRecGetBlockTag(record, block_id, &rnode, &forknum, &blk); |
| 446 | + printf("\tblkref #%u: rel %u/%u/%u fork %s blk %u", |
| 447 | + block_id, |
| 448 | + rnode.spcNode, rnode.dbNode, rnode.relNode, |
| 449 | + forkNames[forknum], |
| 450 | + blk); |
| 451 | + if (XLogRecHasBlockImage(record, block_id)) |
| 452 | + { |
| 453 | + printf(" (FPW); hole: offset: %u, length: %u\n", |
| 454 | + record->blocks[block_id].hole_offset, |
| 455 | + record->blocks[block_id].hole_length); |
| 456 | + } |
| 457 | + putchar('\n'); |
430 | 458 | }
|
431 | 459 | }
|
432 | 460 | }
|
@@ -924,9 +952,9 @@ main(int argc, char **argv)
|
924 | 952 |
|
925 | 953 | /* process the record */
|
926 | 954 | if (config.stats == true)
|
927 |
| - XLogDumpCountRecord(&config, &stats, xlogreader_state->ReadRecPtr, record); |
| 955 | + XLogDumpCountRecord(&config, &stats, xlogreader_state); |
928 | 956 | else
|
929 |
| - XLogDumpDisplayRecord(&config, xlogreader_state->ReadRecPtr, record); |
| 957 | + XLogDumpDisplayRecord(&config, xlogreader_state); |
930 | 958 |
|
931 | 959 | /* check whether we printed enough */
|
932 | 960 | config.already_displayed_records++;
|
|
0 commit comments