v3-0002-Preliminary-refactoring-for-storing-fork-number-i.patch
text/x-patch
Filename: v3-0002-Preliminary-refactoring-for-storing-fork-number-i.patch
Type: text/x-patch
Part: 2
Patch
Format: format-patch
Series: patch v3-0002
Subject: Preliminary refactoring for storing fork number in RelFileNode
| File | + | − |
|---|---|---|
| contrib/pg_buffercache/pg_buffercache_pages.c | 1 | 1 |
| contrib/pg_prewarm/autoprewarm.c | 2 | 1 |
| src/backend/storage/buffer/bufmgr.c | 19 | 18 |
| src/backend/storage/buffer/localbuf.c | 4 | 4 |
| src/include/storage/buf_internals.h | 4 | 0 |
From cace365aa078cbf68514fa7ca36eac7c0ff58cb9 Mon Sep 17 00:00:00 2001
From: Dilip Kumar <dilipkumar@localhost.localdomain>
Date: Sat, 5 Feb 2022 15:54:36 +0530
Subject: [PATCH v3 2/4] Preliminary refactoring for storing fork number in
RelFileNode
As described in the previous patch that we are planning to make
relNode as 64 bit but that will increase the size of the buffer
tag. So in order to avoid that we are planning to store the
fork number in the first 8 bits of the relNode and the remaining
56 bits will be for the actual relNode. So this is refactoring
for the same and as part of this patch we just avoid accessing
the fork number directly from the buffer tag and instead it will
be accessed using macro and the later patche will change the
macro definition such that it will access from the first 8 bits
of the relNode.
---
contrib/pg_buffercache/pg_buffercache_pages.c | 2 +-
contrib/pg_prewarm/autoprewarm.c | 3 ++-
src/backend/storage/buffer/bufmgr.c | 37 ++++++++++++++-------------
src/backend/storage/buffer/localbuf.c | 8 +++---
src/include/storage/buf_internals.h | 4 +++
5 files changed, 30 insertions(+), 24 deletions(-)
diff --git a/contrib/pg_buffercache/pg_buffercache_pages.c b/contrib/pg_buffercache/pg_buffercache_pages.c
index 737e9b4..e181d66 100644
--- a/contrib/pg_buffercache/pg_buffercache_pages.c
+++ b/contrib/pg_buffercache/pg_buffercache_pages.c
@@ -156,7 +156,7 @@ pg_buffercache_pages(PG_FUNCTION_ARGS)
fctx->record[i].relfilenode = RelFileNodeGetRel(bufHdr->tag.rnode);
fctx->record[i].reltablespace = bufHdr->tag.rnode.spcNode;
fctx->record[i].reldatabase = bufHdr->tag.rnode.dbNode;
- fctx->record[i].forknum = bufHdr->tag.forkNum;
+ fctx->record[i].forknum = BUFFERTAG_GETFORK(bufHdr->tag);
fctx->record[i].blocknum = bufHdr->tag.blockNum;
fctx->record[i].usagecount = BUF_STATE_GET_USAGECOUNT(buf_state);
fctx->record[i].pinning_backends = BUF_STATE_GET_REFCOUNT(buf_state);
diff --git a/contrib/pg_prewarm/autoprewarm.c b/contrib/pg_prewarm/autoprewarm.c
index 91dc4d4..f62aea4 100644
--- a/contrib/pg_prewarm/autoprewarm.c
+++ b/contrib/pg_prewarm/autoprewarm.c
@@ -619,7 +619,8 @@ apw_dump_now(bool is_bgworker, bool dump_unlogged)
block_info_array[num_blocks].tablespace = bufHdr->tag.rnode.spcNode;
block_info_array[num_blocks].filenode =
RelFileNodeGetRel(bufHdr->tag.rnode);
- block_info_array[num_blocks].forknum = bufHdr->tag.forkNum;
+ block_info_array[num_blocks].forknum =
+ BUFFERTAG_GETFORK(bufHdr->tag);
block_info_array[num_blocks].blocknum = bufHdr->tag.blockNum;
++num_blocks;
}
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index 68e16c7..4cf74aa 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -1641,7 +1641,7 @@ ReleaseAndReadBuffer(Buffer buffer,
bufHdr = GetLocalBufferDescriptor(-buffer - 1);
if (bufHdr->tag.blockNum == blockNum &&
RelFileNodeEquals(bufHdr->tag.rnode, relation->rd_node) &&
- bufHdr->tag.forkNum == forkNum)
+ BUFFERTAG_GETFORK(bufHdr->tag) == forkNum)
return buffer;
ResourceOwnerForgetBuffer(CurrentResourceOwner, buffer);
LocalRefCount[-buffer - 1]--;
@@ -1652,7 +1652,7 @@ ReleaseAndReadBuffer(Buffer buffer,
/* we have pin, so it's ok to examine tag without spinlock */
if (bufHdr->tag.blockNum == blockNum &&
RelFileNodeEquals(bufHdr->tag.rnode, relation->rd_node) &&
- bufHdr->tag.forkNum == forkNum)
+ BUFFERTAG_GETFORK(bufHdr->tag) == forkNum)
return buffer;
UnpinBuffer(bufHdr, true);
}
@@ -1995,7 +1995,7 @@ BufferSync(int flags)
item->buf_id = buf_id;
item->tsId = bufHdr->tag.rnode.spcNode;
item->relNode = RelFileNodeGetRel(bufHdr->tag.rnode);
- item->forkNum = bufHdr->tag.forkNum;
+ item->forkNum = BUFFERTAG_GETFORK(bufHdr->tag);
item->blockNum = bufHdr->tag.blockNum;
}
@@ -2702,7 +2702,7 @@ PrintBufferLeakWarning(Buffer buffer)
}
/* theoretically we should lock the bufhdr here */
- path = relpathbackend(buf->tag.rnode, backend, buf->tag.forkNum);
+ path = relpathbackend(buf->tag.rnode, backend, BUFFERTAG_GETFORK(buf->tag));
buf_state = pg_atomic_read_u32(&buf->state);
elog(WARNING,
"buffer refcount leak: [%03d] "
@@ -2782,7 +2782,7 @@ BufferGetTag(Buffer buffer, RelFileNode *rnode, ForkNumber *forknum,
/* pinned, so OK to read tag without spinlock */
*rnode = bufHdr->tag.rnode;
- *forknum = bufHdr->tag.forkNum;
+ *forknum = BUFFERTAG_GETFORK(bufHdr->tag);
*blknum = bufHdr->tag.blockNum;
}
@@ -2834,7 +2834,7 @@ FlushBuffer(BufferDesc *buf, SMgrRelation reln)
if (reln == NULL)
reln = smgropen(buf->tag.rnode, InvalidBackendId);
- TRACE_POSTGRESQL_BUFFER_FLUSH_START(buf->tag.forkNum,
+ TRACE_POSTGRESQL_BUFFER_FLUSH_START(BUFFERTAG_GETFORK(buf->tag),
buf->tag.blockNum,
reln->smgr_rnode.node.spcNode,
reln->smgr_rnode.node.dbNode,
@@ -2893,7 +2893,7 @@ FlushBuffer(BufferDesc *buf, SMgrRelation reln)
* bufToWrite is either the shared buffer or a copy, as appropriate.
*/
smgrwrite(reln,
- buf->tag.forkNum,
+ BUFFERTAG_GETFORK(buf->tag),
buf->tag.blockNum,
bufToWrite,
false);
@@ -2914,7 +2914,7 @@ FlushBuffer(BufferDesc *buf, SMgrRelation reln)
*/
TerminateBufferIO(buf, true, 0);
- TRACE_POSTGRESQL_BUFFER_FLUSH_DONE(buf->tag.forkNum,
+ TRACE_POSTGRESQL_BUFFER_FLUSH_DONE(BUFFERTAG_GETFORK(buf->tag),
buf->tag.blockNum,
reln->smgr_rnode.node.spcNode,
reln->smgr_rnode.node.dbNode,
@@ -3143,7 +3143,7 @@ DropRelFileNodeBuffers(SMgrRelation smgr_reln, ForkNumber *forkNum,
for (j = 0; j < nforks; j++)
{
if (RelFileNodeEquals(bufHdr->tag.rnode, rnode.node) &&
- bufHdr->tag.forkNum == forkNum[j] &&
+ BUFFERTAG_GETFORK(bufHdr->tag) == forkNum[j] &&
bufHdr->tag.blockNum >= firstDelBlock[j])
{
InvalidateBuffer(bufHdr); /* releases spinlock */
@@ -3375,7 +3375,7 @@ FindAndDropRelFileNodeBuffers(RelFileNode rnode, ForkNumber forkNum,
buf_state = LockBufHdr(bufHdr);
if (RelFileNodeEquals(bufHdr->tag.rnode, rnode) &&
- bufHdr->tag.forkNum == forkNum &&
+ BUFFERTAG_GETFORK(bufHdr->tag) == forkNum &&
bufHdr->tag.blockNum >= firstDelBlock)
InvalidateBuffer(bufHdr); /* releases spinlock */
else
@@ -3529,7 +3529,7 @@ FlushRelationBuffers(Relation rel)
PageSetChecksumInplace(localpage, bufHdr->tag.blockNum);
smgrwrite(RelationGetSmgr(rel),
- bufHdr->tag.forkNum,
+ BUFFERTAG_GETFORK(bufHdr->tag),
bufHdr->tag.blockNum,
localpage,
false);
@@ -4492,7 +4492,7 @@ AbortBufferIO(void)
/* Buffer is pinned, so we can read tag without spinlock */
char *path;
- path = relpathperm(buf->tag.rnode, buf->tag.forkNum);
+ path = relpathperm(buf->tag.rnode, BUFFERTAG_GETFORK(buf->tag));
ereport(WARNING,
(errcode(ERRCODE_IO_ERROR),
errmsg("could not write block %u of %s",
@@ -4516,7 +4516,8 @@ shared_buffer_write_error_callback(void *arg)
/* Buffer is pinned, so we can read the tag without locking the spinlock */
if (bufHdr != NULL)
{
- char *path = relpathperm(bufHdr->tag.rnode, bufHdr->tag.forkNum);
+ char *path = relpathperm(bufHdr->tag.rnode,
+ BUFFERTAG_GETFORK(bufHdr->tag));
errcontext("writing block %u of relation %s",
bufHdr->tag.blockNum, path);
@@ -4535,7 +4536,7 @@ local_buffer_write_error_callback(void *arg)
if (bufHdr != NULL)
{
char *path = relpathbackend(bufHdr->tag.rnode, MyBackendId,
- bufHdr->tag.forkNum);
+ BUFFERTAG_GETFORK(bufHdr->tag));
errcontext("writing block %u of relation %s",
bufHdr->tag.blockNum, path);
@@ -4635,9 +4636,9 @@ buffertag_comparator(const BufferTag *ba, const BufferTag *bb)
if (ret != 0)
return ret;
- if (ba->forkNum < bb->forkNum)
+ if (BUFFERTAG_GETFORK(*ba) < BUFFERTAG_GETFORK(*bb))
return -1;
- if (ba->forkNum > bb->forkNum)
+ if (BUFFERTAG_GETFORK(*ba) > BUFFERTAG_GETFORK(*bb))
return 1;
if (ba->blockNum < bb->blockNum)
@@ -4802,7 +4803,7 @@ IssuePendingWritebacks(WritebackContext *context)
/* different file, stop */
if (!RelFileNodeEquals(cur->tag.rnode, next->tag.rnode) ||
- cur->tag.forkNum != next->tag.forkNum)
+ BUFFERTAG_GETFORK(cur->tag) != BUFFERTAG_GETFORK(next->tag))
break;
/* ok, block queued twice, skip */
@@ -4821,7 +4822,7 @@ IssuePendingWritebacks(WritebackContext *context)
/* and finally tell the kernel to write the data to storage */
reln = smgropen(tag.rnode, InvalidBackendId);
- smgrwriteback(reln, tag.forkNum, tag.blockNum, nblocks);
+ smgrwriteback(reln, BUFFERTAG_GETFORK(tag), tag.blockNum, nblocks);
}
context->nr_pending = 0;
diff --git a/src/backend/storage/buffer/localbuf.c b/src/backend/storage/buffer/localbuf.c
index dbb52a9..2dda7ba 100644
--- a/src/backend/storage/buffer/localbuf.c
+++ b/src/backend/storage/buffer/localbuf.c
@@ -222,7 +222,7 @@ LocalBufferAlloc(SMgrRelation smgr, ForkNumber forkNum, BlockNumber blockNum,
/* And write... */
smgrwrite(oreln,
- bufHdr->tag.forkNum,
+ BUFFERTAG_GETFORK(bufHdr->tag),
bufHdr->tag.blockNum,
localpage,
false);
@@ -339,14 +339,14 @@ DropRelFileNodeLocalBuffers(RelFileNode rnode, ForkNumber forkNum,
if ((buf_state & BM_TAG_VALID) &&
RelFileNodeEquals(bufHdr->tag.rnode, rnode) &&
- bufHdr->tag.forkNum == forkNum &&
+ BUFFERTAG_GETFORK(bufHdr->tag) == forkNum &&
bufHdr->tag.blockNum >= firstDelBlock)
{
if (LocalRefCount[i] != 0)
elog(ERROR, "block %u of %s is still referenced (local %u)",
bufHdr->tag.blockNum,
relpathbackend(bufHdr->tag.rnode, MyBackendId,
- bufHdr->tag.forkNum),
+ BUFFERTAG_GETFORK(bufHdr->tag)),
LocalRefCount[i]);
/* Remove entry from hashtable */
hresult = (LocalBufferLookupEnt *)
@@ -390,7 +390,7 @@ DropRelFileNodeAllLocalBuffers(RelFileNode rnode)
elog(ERROR, "block %u of %s is still referenced (local %u)",
bufHdr->tag.blockNum,
relpathbackend(bufHdr->tag.rnode, MyBackendId,
- bufHdr->tag.forkNum),
+ BUFFERTAG_GETFORK(bufHdr->tag)),
LocalRefCount[i]);
/* Remove entry from hashtable */
hresult = (LocalBufferLookupEnt *)
diff --git a/src/include/storage/buf_internals.h b/src/include/storage/buf_internals.h
index 8397a1d..38ac9ea 100644
--- a/src/include/storage/buf_internals.h
+++ b/src/include/storage/buf_internals.h
@@ -118,6 +118,10 @@ typedef struct buftag
(a).forkNum == (b).forkNum \
)
+/* Macro to get the fork number from the buffer tag. */
+#define BUFFERTAG_GETFORK(a) \
+ ((a).forkNum)
+
/*
* The shared buffer mapping table is partitioned to reduce contention.
* To determine which partition lock a given tag requires, compute the tag's
--
1.8.3.1