From 785ebf3b029b7b79a90eb15ae2ddb9e984389fd7 Mon Sep 17 00:00:00 2001 From: Hubert Zhang Date: Mon, 10 Feb 2020 07:54:51 +0000 Subject: [PATCH] Print physical file path when checksum check fails --- src/backend/storage/buffer/bufmgr.c | 11 +++++++---- src/common/relpath.c | 27 +++++++++++++++++++++++++++ src/include/common/relpath.h | 21 +++++++++++++++++++++ 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index aba3960481..84308bd7a4 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -912,17 +912,20 @@ ReadBuffer_common(SMgrRelation smgr, char relpersistence, ForkNumber forkNum, { ereport(WARNING, (errcode(ERRCODE_DATA_CORRUPTED), - errmsg("invalid page in block %u of relation %s; zeroing out page", + errmsg("invalid page in block %u of relation %s, " + "file path %s; zeroing out page", blockNum, - relpath(smgr->smgr_rnode, forkNum)))); + relpath(smgr->smgr_rnode, forkNum), + relfilepath(smgr->smgr_rnode, forkNum, blockNum)))); MemSet((char *) bufBlock, 0, BLCKSZ); } else ereport(ERROR, (errcode(ERRCODE_DATA_CORRUPTED), - errmsg("invalid page in block %u of relation %s", + errmsg("invalid page in block %u of relation %s, file path %s", blockNum, - relpath(smgr->smgr_rnode, forkNum)))); + relpath(smgr->smgr_rnode, forkNum), + relfilepath(smgr->smgr_rnode, forkNum, blockNum)))); } } } diff --git a/src/common/relpath.c b/src/common/relpath.c index ad733d1363..8b39c4ac4f 100644 --- a/src/common/relpath.c +++ b/src/common/relpath.c @@ -208,3 +208,30 @@ GetRelationPath(Oid dbNode, Oid spcNode, Oid relNode, } return path; } + +/* + * GetRelationFilePath - construct path to a relation's physical file + * given its block number. + */ + char * +GetRelationFilePath(Oid dbNode, Oid spcNode, Oid relNode, + int backendId, ForkNumber forkNumber, BlockNumber blkno) +{ + char *path; + char *fullpath; + BlockNumber segno; + + path = GetRelationPath(dbNode, spcNode, relNode, backendId, forkNumber); + + segno = blkno / ((BlockNumber) RELSEG_SIZE); + + if (segno > 0) + { + fullpath = psprintf("%s.%u", path, segno); + pfree(path); + } + else + fullpath = path; + + return fullpath; +} diff --git a/src/include/common/relpath.h b/src/include/common/relpath.h index 869cabcc0d..7e036f4086 100644 --- a/src/include/common/relpath.h +++ b/src/include/common/relpath.h @@ -13,6 +13,8 @@ #ifndef RELPATH_H #define RELPATH_H +#include "storage/block.h" + /* * 'pgrminclude ignore' needed here because CppAsString2() does not throw * an error if the symbol is not defined. @@ -69,6 +71,9 @@ extern char *GetDatabasePath(Oid dbNode, Oid spcNode); extern char *GetRelationPath(Oid dbNode, Oid spcNode, Oid relNode, int backendId, ForkNumber forkNumber); +extern char *GetRelationFilePath(Oid dbNode, Oid spcNode, Oid relNode, + int backendId, ForkNumber forkNumber, BlockNumber blkno); + /* * Wrapper macros for GetRelationPath. Beware of multiple * evaluation of the RelFileNode or RelFileNodeBackend argument! @@ -87,4 +92,20 @@ extern char *GetRelationPath(Oid dbNode, Oid spcNode, Oid relNode, #define relpath(rnode, forknum) \ relpathbackend((rnode).node, (rnode).backend, forknum) +/* + * File path of a relation given the block number. + * Note that a file can contain at most RELSEG_SIZE number + * of blocks. We supply relfilepath macro to display the + * physical file name for a relation given the block number. + */ + +/* First argument is a RelFileNode */ +#define relfilepathbackend(rnode, backend, forknum, blkno) \ + GetRelationFilePath((rnode).dbNode, (rnode).spcNode, (rnode).relNode, \ + backend, forknum, blkno) + +/* First argument is a RelFileNodeBackend */ +#define relfilepath(rnode, forknum, blkno) \ + relfilepathbackend((rnode).node, (rnode).backend, forknum, blkno) + #endif /* RELPATH_H */ -- 2.16.6