1
0
mirror of https://github.com/postgres/postgres.git synced 2025-08-06 18:42:54 +03:00

Include RelFileLocator fields individually in BufferTag.

This is preparatory work for a project to increase the number of bits
in a RelFileNumber from 32 to 56.

Along the way, introduce static inline accessor functions for a couple
of BufferTag fields.

Dilip Kumar, reviewed by me. The overall patch series has also had
review at various times from Andres Freund, Ashutosh Sharma, Hannu
Krosing, Vignesh C, Álvaro Herrera, and Tom Lane.

Discussion: http://postgr.es/m/CAFiTN-trubju5YbWAq-BSpZ90-Z6xCVBQE8BVqXqANOZAF1Znw@mail.gmail.com
This commit is contained in:
Robert Haas
2022-08-24 15:50:48 -04:00
parent 396d348b04
commit 82ac34db20
5 changed files with 145 additions and 73 deletions

View File

@@ -153,10 +153,10 @@ pg_buffercache_pages(PG_FUNCTION_ARGS)
buf_state = LockBufHdr(bufHdr); buf_state = LockBufHdr(bufHdr);
fctx->record[i].bufferid = BufferDescriptorGetBuffer(bufHdr); fctx->record[i].bufferid = BufferDescriptorGetBuffer(bufHdr);
fctx->record[i].relfilenumber = bufHdr->tag.rlocator.relNumber; fctx->record[i].relfilenumber = BufTagGetRelNumber(&bufHdr->tag);
fctx->record[i].reltablespace = bufHdr->tag.rlocator.spcOid; fctx->record[i].reltablespace = bufHdr->tag.spcOid;
fctx->record[i].reldatabase = bufHdr->tag.rlocator.dbOid; fctx->record[i].reldatabase = bufHdr->tag.dbOid;
fctx->record[i].forknum = bufHdr->tag.forkNum; fctx->record[i].forknum = BufTagGetForkNum(&bufHdr->tag);
fctx->record[i].blocknum = bufHdr->tag.blockNum; fctx->record[i].blocknum = bufHdr->tag.blockNum;
fctx->record[i].usagecount = BUF_STATE_GET_USAGECOUNT(buf_state); fctx->record[i].usagecount = BUF_STATE_GET_USAGECOUNT(buf_state);
fctx->record[i].pinning_backends = BUF_STATE_GET_REFCOUNT(buf_state); fctx->record[i].pinning_backends = BUF_STATE_GET_REFCOUNT(buf_state);

View File

@@ -630,10 +630,12 @@ apw_dump_now(bool is_bgworker, bool dump_unlogged)
if (buf_state & BM_TAG_VALID && if (buf_state & BM_TAG_VALID &&
((buf_state & BM_PERMANENT) || dump_unlogged)) ((buf_state & BM_PERMANENT) || dump_unlogged))
{ {
block_info_array[num_blocks].database = bufHdr->tag.rlocator.dbOid; block_info_array[num_blocks].database = bufHdr->tag.dbOid;
block_info_array[num_blocks].tablespace = bufHdr->tag.rlocator.spcOid; block_info_array[num_blocks].tablespace = bufHdr->tag.spcOid;
block_info_array[num_blocks].filenumber = bufHdr->tag.rlocator.relNumber; block_info_array[num_blocks].filenumber =
block_info_array[num_blocks].forknum = bufHdr->tag.forkNum; BufTagGetRelNumber(&bufHdr->tag);
block_info_array[num_blocks].forknum =
BufTagGetForkNum(&bufHdr->tag);
block_info_array[num_blocks].blocknum = bufHdr->tag.blockNum; block_info_array[num_blocks].blocknum = bufHdr->tag.blockNum;
++num_blocks; ++num_blocks;
} }

View File

@@ -1657,8 +1657,8 @@ ReleaseAndReadBuffer(Buffer buffer,
{ {
bufHdr = GetLocalBufferDescriptor(-buffer - 1); bufHdr = GetLocalBufferDescriptor(-buffer - 1);
if (bufHdr->tag.blockNum == blockNum && if (bufHdr->tag.blockNum == blockNum &&
RelFileLocatorEquals(bufHdr->tag.rlocator, relation->rd_locator) && BufTagMatchesRelFileLocator(&bufHdr->tag, &relation->rd_locator) &&
bufHdr->tag.forkNum == forkNum) BufTagGetForkNum(&bufHdr->tag) == forkNum)
return buffer; return buffer;
ResourceOwnerForgetBuffer(CurrentResourceOwner, buffer); ResourceOwnerForgetBuffer(CurrentResourceOwner, buffer);
LocalRefCount[-buffer - 1]--; LocalRefCount[-buffer - 1]--;
@@ -1668,8 +1668,8 @@ ReleaseAndReadBuffer(Buffer buffer,
bufHdr = GetBufferDescriptor(buffer - 1); bufHdr = GetBufferDescriptor(buffer - 1);
/* we have pin, so it's ok to examine tag without spinlock */ /* we have pin, so it's ok to examine tag without spinlock */
if (bufHdr->tag.blockNum == blockNum && if (bufHdr->tag.blockNum == blockNum &&
RelFileLocatorEquals(bufHdr->tag.rlocator, relation->rd_locator) && BufTagMatchesRelFileLocator(&bufHdr->tag, &relation->rd_locator) &&
bufHdr->tag.forkNum == forkNum) BufTagGetForkNum(&bufHdr->tag) == forkNum)
return buffer; return buffer;
UnpinBuffer(bufHdr, true); UnpinBuffer(bufHdr, true);
} }
@@ -2010,9 +2010,9 @@ BufferSync(int flags)
item = &CkptBufferIds[num_to_scan++]; item = &CkptBufferIds[num_to_scan++];
item->buf_id = buf_id; item->buf_id = buf_id;
item->tsId = bufHdr->tag.rlocator.spcOid; item->tsId = bufHdr->tag.spcOid;
item->relNumber = bufHdr->tag.rlocator.relNumber; item->relNumber = BufTagGetRelNumber(&bufHdr->tag);
item->forkNum = bufHdr->tag.forkNum; item->forkNum = BufTagGetForkNum(&bufHdr->tag);
item->blockNum = bufHdr->tag.blockNum; item->blockNum = bufHdr->tag.blockNum;
} }
@@ -2718,7 +2718,8 @@ PrintBufferLeakWarning(Buffer buffer)
} }
/* theoretically we should lock the bufhdr here */ /* theoretically we should lock the bufhdr here */
path = relpathbackend(buf->tag.rlocator, backend, buf->tag.forkNum); path = relpathbackend(BufTagGetRelFileLocator(&buf->tag), backend,
BufTagGetForkNum(&buf->tag));
buf_state = pg_atomic_read_u32(&buf->state); buf_state = pg_atomic_read_u32(&buf->state);
elog(WARNING, elog(WARNING,
"buffer refcount leak: [%03d] " "buffer refcount leak: [%03d] "
@@ -2797,8 +2798,8 @@ BufferGetTag(Buffer buffer, RelFileLocator *rlocator, ForkNumber *forknum,
bufHdr = GetBufferDescriptor(buffer - 1); bufHdr = GetBufferDescriptor(buffer - 1);
/* pinned, so OK to read tag without spinlock */ /* pinned, so OK to read tag without spinlock */
*rlocator = bufHdr->tag.rlocator; *rlocator = BufTagGetRelFileLocator(&bufHdr->tag);
*forknum = bufHdr->tag.forkNum; *forknum = BufTagGetForkNum(&bufHdr->tag);
*blknum = bufHdr->tag.blockNum; *blknum = bufHdr->tag.blockNum;
} }
@@ -2848,9 +2849,9 @@ FlushBuffer(BufferDesc *buf, SMgrRelation reln)
/* Find smgr relation for buffer */ /* Find smgr relation for buffer */
if (reln == NULL) if (reln == NULL)
reln = smgropen(buf->tag.rlocator, InvalidBackendId); reln = smgropen(BufTagGetRelFileLocator(&buf->tag), InvalidBackendId);
TRACE_POSTGRESQL_BUFFER_FLUSH_START(buf->tag.forkNum, TRACE_POSTGRESQL_BUFFER_FLUSH_START(BufTagGetForkNum(&buf->tag),
buf->tag.blockNum, buf->tag.blockNum,
reln->smgr_rlocator.locator.spcOid, reln->smgr_rlocator.locator.spcOid,
reln->smgr_rlocator.locator.dbOid, reln->smgr_rlocator.locator.dbOid,
@@ -2909,7 +2910,7 @@ FlushBuffer(BufferDesc *buf, SMgrRelation reln)
* bufToWrite is either the shared buffer or a copy, as appropriate. * bufToWrite is either the shared buffer or a copy, as appropriate.
*/ */
smgrwrite(reln, smgrwrite(reln,
buf->tag.forkNum, BufTagGetForkNum(&buf->tag),
buf->tag.blockNum, buf->tag.blockNum,
bufToWrite, bufToWrite,
false); false);
@@ -2930,7 +2931,7 @@ FlushBuffer(BufferDesc *buf, SMgrRelation reln)
*/ */
TerminateBufferIO(buf, true, 0); TerminateBufferIO(buf, true, 0);
TRACE_POSTGRESQL_BUFFER_FLUSH_DONE(buf->tag.forkNum, TRACE_POSTGRESQL_BUFFER_FLUSH_DONE(BufTagGetForkNum(&buf->tag),
buf->tag.blockNum, buf->tag.blockNum,
reln->smgr_rlocator.locator.spcOid, reln->smgr_rlocator.locator.spcOid,
reln->smgr_rlocator.locator.dbOid, reln->smgr_rlocator.locator.dbOid,
@@ -3151,15 +3152,15 @@ DropRelationBuffers(SMgrRelation smgr_reln, ForkNumber *forkNum,
* We could check forkNum and blockNum as well as the rlocator, but * We could check forkNum and blockNum as well as the rlocator, but
* the incremental win from doing so seems small. * the incremental win from doing so seems small.
*/ */
if (!RelFileLocatorEquals(bufHdr->tag.rlocator, rlocator.locator)) if (!BufTagMatchesRelFileLocator(&bufHdr->tag, &rlocator.locator))
continue; continue;
buf_state = LockBufHdr(bufHdr); buf_state = LockBufHdr(bufHdr);
for (j = 0; j < nforks; j++) for (j = 0; j < nforks; j++)
{ {
if (RelFileLocatorEquals(bufHdr->tag.rlocator, rlocator.locator) && if (BufTagMatchesRelFileLocator(&bufHdr->tag, &rlocator.locator) &&
bufHdr->tag.forkNum == forkNum[j] && BufTagGetForkNum(&bufHdr->tag) == forkNum[j] &&
bufHdr->tag.blockNum >= firstDelBlock[j]) bufHdr->tag.blockNum >= firstDelBlock[j])
{ {
InvalidateBuffer(bufHdr); /* releases spinlock */ InvalidateBuffer(bufHdr); /* releases spinlock */
@@ -3309,7 +3310,7 @@ DropRelationsAllBuffers(SMgrRelation *smgr_reln, int nlocators)
for (j = 0; j < n; j++) for (j = 0; j < n; j++)
{ {
if (RelFileLocatorEquals(bufHdr->tag.rlocator, locators[j])) if (BufTagMatchesRelFileLocator(&bufHdr->tag, &locators[j]))
{ {
rlocator = &locators[j]; rlocator = &locators[j];
break; break;
@@ -3318,7 +3319,10 @@ DropRelationsAllBuffers(SMgrRelation *smgr_reln, int nlocators)
} }
else else
{ {
rlocator = bsearch((const void *) &(bufHdr->tag.rlocator), RelFileLocator locator;
locator = BufTagGetRelFileLocator(&bufHdr->tag);
rlocator = bsearch((const void *) &(locator),
locators, n, sizeof(RelFileLocator), locators, n, sizeof(RelFileLocator),
rlocator_comparator); rlocator_comparator);
} }
@@ -3328,7 +3332,7 @@ DropRelationsAllBuffers(SMgrRelation *smgr_reln, int nlocators)
continue; continue;
buf_state = LockBufHdr(bufHdr); buf_state = LockBufHdr(bufHdr);
if (RelFileLocatorEquals(bufHdr->tag.rlocator, (*rlocator))) if (BufTagMatchesRelFileLocator(&bufHdr->tag, rlocator))
InvalidateBuffer(bufHdr); /* releases spinlock */ InvalidateBuffer(bufHdr); /* releases spinlock */
else else
UnlockBufHdr(bufHdr, buf_state); UnlockBufHdr(bufHdr, buf_state);
@@ -3388,8 +3392,8 @@ FindAndDropRelationBuffers(RelFileLocator rlocator, ForkNumber forkNum,
*/ */
buf_state = LockBufHdr(bufHdr); buf_state = LockBufHdr(bufHdr);
if (RelFileLocatorEquals(bufHdr->tag.rlocator, rlocator) && if (BufTagMatchesRelFileLocator(&bufHdr->tag, &rlocator) &&
bufHdr->tag.forkNum == forkNum && BufTagGetForkNum(&bufHdr->tag) == forkNum &&
bufHdr->tag.blockNum >= firstDelBlock) bufHdr->tag.blockNum >= firstDelBlock)
InvalidateBuffer(bufHdr); /* releases spinlock */ InvalidateBuffer(bufHdr); /* releases spinlock */
else else
@@ -3427,11 +3431,11 @@ DropDatabaseBuffers(Oid dbid)
* As in DropRelationBuffers, an unlocked precheck should be * As in DropRelationBuffers, an unlocked precheck should be
* safe and saves some cycles. * safe and saves some cycles.
*/ */
if (bufHdr->tag.rlocator.dbOid != dbid) if (bufHdr->tag.dbOid != dbid)
continue; continue;
buf_state = LockBufHdr(bufHdr); buf_state = LockBufHdr(bufHdr);
if (bufHdr->tag.rlocator.dbOid == dbid) if (bufHdr->tag.dbOid == dbid)
InvalidateBuffer(bufHdr); /* releases spinlock */ InvalidateBuffer(bufHdr); /* releases spinlock */
else else
UnlockBufHdr(bufHdr, buf_state); UnlockBufHdr(bufHdr, buf_state);
@@ -3461,7 +3465,8 @@ PrintBufferDescs(void)
"[%02d] (freeNext=%d, rel=%s, " "[%02d] (freeNext=%d, rel=%s, "
"blockNum=%u, flags=0x%x, refcount=%u %d)", "blockNum=%u, flags=0x%x, refcount=%u %d)",
i, buf->freeNext, i, buf->freeNext,
relpathbackend(buf->tag.rlocator, InvalidBackendId, buf->tag.forkNum), relpathbackend(BufTagGetRelFileLocator(&buf->tag),
InvalidBackendId, BufTagGetForkNum(&buf->tag)),
buf->tag.blockNum, buf->flags, buf->tag.blockNum, buf->flags,
buf->refcount, GetPrivateRefCount(b)); buf->refcount, GetPrivateRefCount(b));
} }
@@ -3486,7 +3491,8 @@ PrintPinnedBufs(void)
"[%02d] (freeNext=%d, rel=%s, " "[%02d] (freeNext=%d, rel=%s, "
"blockNum=%u, flags=0x%x, refcount=%u %d)", "blockNum=%u, flags=0x%x, refcount=%u %d)",
i, buf->freeNext, i, buf->freeNext,
relpathperm(buf->tag.rlocator, buf->tag.forkNum), relpathperm(BufTagGetRelFileLocator(&buf->tag),
BufTagGetForkNum(&buf->tag)),
buf->tag.blockNum, buf->flags, buf->tag.blockNum, buf->flags,
buf->refcount, GetPrivateRefCount(b)); buf->refcount, GetPrivateRefCount(b));
} }
@@ -3525,7 +3531,7 @@ FlushRelationBuffers(Relation rel)
uint32 buf_state; uint32 buf_state;
bufHdr = GetLocalBufferDescriptor(i); bufHdr = GetLocalBufferDescriptor(i);
if (RelFileLocatorEquals(bufHdr->tag.rlocator, rel->rd_locator) && if (BufTagMatchesRelFileLocator(&bufHdr->tag, &rel->rd_locator) &&
((buf_state = pg_atomic_read_u32(&bufHdr->state)) & ((buf_state = pg_atomic_read_u32(&bufHdr->state)) &
(BM_VALID | BM_DIRTY)) == (BM_VALID | BM_DIRTY)) (BM_VALID | BM_DIRTY)) == (BM_VALID | BM_DIRTY))
{ {
@@ -3543,7 +3549,7 @@ FlushRelationBuffers(Relation rel)
PageSetChecksumInplace(localpage, bufHdr->tag.blockNum); PageSetChecksumInplace(localpage, bufHdr->tag.blockNum);
smgrwrite(RelationGetSmgr(rel), smgrwrite(RelationGetSmgr(rel),
bufHdr->tag.forkNum, BufTagGetForkNum(&bufHdr->tag),
bufHdr->tag.blockNum, bufHdr->tag.blockNum,
localpage, localpage,
false); false);
@@ -3572,13 +3578,13 @@ FlushRelationBuffers(Relation rel)
* As in DropRelationBuffers, an unlocked precheck should be * As in DropRelationBuffers, an unlocked precheck should be
* safe and saves some cycles. * safe and saves some cycles.
*/ */
if (!RelFileLocatorEquals(bufHdr->tag.rlocator, rel->rd_locator)) if (!BufTagMatchesRelFileLocator(&bufHdr->tag, &rel->rd_locator))
continue; continue;
ReservePrivateRefCountEntry(); ReservePrivateRefCountEntry();
buf_state = LockBufHdr(bufHdr); buf_state = LockBufHdr(bufHdr);
if (RelFileLocatorEquals(bufHdr->tag.rlocator, rel->rd_locator) && if (BufTagMatchesRelFileLocator(&bufHdr->tag, &rel->rd_locator) &&
(buf_state & (BM_VALID | BM_DIRTY)) == (BM_VALID | BM_DIRTY)) (buf_state & (BM_VALID | BM_DIRTY)) == (BM_VALID | BM_DIRTY))
{ {
PinBuffer_Locked(bufHdr); PinBuffer_Locked(bufHdr);
@@ -3652,7 +3658,7 @@ FlushRelationsAllBuffers(SMgrRelation *smgrs, int nrels)
for (j = 0; j < nrels; j++) for (j = 0; j < nrels; j++)
{ {
if (RelFileLocatorEquals(bufHdr->tag.rlocator, srels[j].rlocator)) if (BufTagMatchesRelFileLocator(&bufHdr->tag, &srels[j].rlocator))
{ {
srelent = &srels[j]; srelent = &srels[j];
break; break;
@@ -3661,7 +3667,10 @@ FlushRelationsAllBuffers(SMgrRelation *smgrs, int nrels)
} }
else else
{ {
srelent = bsearch((const void *) &(bufHdr->tag.rlocator), RelFileLocator rlocator;
rlocator = BufTagGetRelFileLocator(&bufHdr->tag);
srelent = bsearch((const void *) &(rlocator),
srels, nrels, sizeof(SMgrSortArray), srels, nrels, sizeof(SMgrSortArray),
rlocator_comparator); rlocator_comparator);
} }
@@ -3673,7 +3682,7 @@ FlushRelationsAllBuffers(SMgrRelation *smgrs, int nrels)
ReservePrivateRefCountEntry(); ReservePrivateRefCountEntry();
buf_state = LockBufHdr(bufHdr); buf_state = LockBufHdr(bufHdr);
if (RelFileLocatorEquals(bufHdr->tag.rlocator, srelent->rlocator) && if (BufTagMatchesRelFileLocator(&bufHdr->tag, &srelent->rlocator) &&
(buf_state & (BM_VALID | BM_DIRTY)) == (BM_VALID | BM_DIRTY)) (buf_state & (BM_VALID | BM_DIRTY)) == (BM_VALID | BM_DIRTY))
{ {
PinBuffer_Locked(bufHdr); PinBuffer_Locked(bufHdr);
@@ -3877,13 +3886,13 @@ FlushDatabaseBuffers(Oid dbid)
* As in DropRelationBuffers, an unlocked precheck should be * As in DropRelationBuffers, an unlocked precheck should be
* safe and saves some cycles. * safe and saves some cycles.
*/ */
if (bufHdr->tag.rlocator.dbOid != dbid) if (bufHdr->tag.dbOid != dbid)
continue; continue;
ReservePrivateRefCountEntry(); ReservePrivateRefCountEntry();
buf_state = LockBufHdr(bufHdr); buf_state = LockBufHdr(bufHdr);
if (bufHdr->tag.rlocator.dbOid == dbid && if (bufHdr->tag.dbOid == dbid &&
(buf_state & (BM_VALID | BM_DIRTY)) == (BM_VALID | BM_DIRTY)) (buf_state & (BM_VALID | BM_DIRTY)) == (BM_VALID | BM_DIRTY))
{ {
PinBuffer_Locked(bufHdr); PinBuffer_Locked(bufHdr);
@@ -4052,7 +4061,7 @@ MarkBufferDirtyHint(Buffer buffer, bool buffer_std)
* See src/backend/storage/page/README for longer discussion. * See src/backend/storage/page/README for longer discussion.
*/ */
if (RecoveryInProgress() || if (RecoveryInProgress() ||
RelFileLocatorSkippingWAL(bufHdr->tag.rlocator)) RelFileLocatorSkippingWAL(BufTagGetRelFileLocator(&bufHdr->tag)))
return; return;
/* /*
@@ -4661,7 +4670,8 @@ AbortBufferIO(void)
/* Buffer is pinned, so we can read tag without spinlock */ /* Buffer is pinned, so we can read tag without spinlock */
char *path; char *path;
path = relpathperm(buf->tag.rlocator, buf->tag.forkNum); path = relpathperm(BufTagGetRelFileLocator(&buf->tag),
BufTagGetForkNum(&buf->tag));
ereport(WARNING, ereport(WARNING,
(errcode(ERRCODE_IO_ERROR), (errcode(ERRCODE_IO_ERROR),
errmsg("could not write block %u of %s", errmsg("could not write block %u of %s",
@@ -4685,7 +4695,8 @@ shared_buffer_write_error_callback(void *arg)
/* Buffer is pinned, so we can read the tag without locking the spinlock */ /* Buffer is pinned, so we can read the tag without locking the spinlock */
if (bufHdr != NULL) if (bufHdr != NULL)
{ {
char *path = relpathperm(bufHdr->tag.rlocator, bufHdr->tag.forkNum); char *path = relpathperm(BufTagGetRelFileLocator(&bufHdr->tag),
BufTagGetForkNum(&bufHdr->tag));
errcontext("writing block %u of relation %s", errcontext("writing block %u of relation %s",
bufHdr->tag.blockNum, path); bufHdr->tag.blockNum, path);
@@ -4703,8 +4714,9 @@ local_buffer_write_error_callback(void *arg)
if (bufHdr != NULL) if (bufHdr != NULL)
{ {
char *path = relpathbackend(bufHdr->tag.rlocator, MyBackendId, char *path = relpathbackend(BufTagGetRelFileLocator(&bufHdr->tag),
bufHdr->tag.forkNum); MyBackendId,
BufTagGetForkNum(&bufHdr->tag));
errcontext("writing block %u of relation %s", errcontext("writing block %u of relation %s",
bufHdr->tag.blockNum, path); bufHdr->tag.blockNum, path);
@@ -4798,15 +4810,20 @@ static inline int
buffertag_comparator(const BufferTag *ba, const BufferTag *bb) buffertag_comparator(const BufferTag *ba, const BufferTag *bb)
{ {
int ret; int ret;
RelFileLocator rlocatora;
RelFileLocator rlocatorb;
ret = rlocator_comparator(&ba->rlocator, &bb->rlocator); rlocatora = BufTagGetRelFileLocator(ba);
rlocatorb = BufTagGetRelFileLocator(bb);
ret = rlocator_comparator(&rlocatora, &rlocatorb);
if (ret != 0) if (ret != 0)
return ret; return ret;
if (ba->forkNum < bb->forkNum) if (BufTagGetForkNum(ba) < BufTagGetForkNum(bb))
return -1; return -1;
if (ba->forkNum > bb->forkNum) if (BufTagGetForkNum(ba) > BufTagGetForkNum(bb))
return 1; return 1;
if (ba->blockNum < bb->blockNum) if (ba->blockNum < bb->blockNum)
@@ -4956,10 +4973,12 @@ IssuePendingWritebacks(WritebackContext *context)
SMgrRelation reln; SMgrRelation reln;
int ahead; int ahead;
BufferTag tag; BufferTag tag;
RelFileLocator currlocator;
Size nblocks = 1; Size nblocks = 1;
cur = &context->pending_writebacks[i]; cur = &context->pending_writebacks[i];
tag = cur->tag; tag = cur->tag;
currlocator = BufTagGetRelFileLocator(&tag);
/* /*
* Peek ahead, into following writeback requests, to see if they can * Peek ahead, into following writeback requests, to see if they can
@@ -4967,11 +4986,13 @@ IssuePendingWritebacks(WritebackContext *context)
*/ */
for (ahead = 0; i + ahead + 1 < context->nr_pending; ahead++) for (ahead = 0; i + ahead + 1 < context->nr_pending; ahead++)
{ {
next = &context->pending_writebacks[i + ahead + 1]; next = &context->pending_writebacks[i + ahead + 1];
/* different file, stop */ /* different file, stop */
if (!RelFileLocatorEquals(cur->tag.rlocator, next->tag.rlocator) || if (!RelFileLocatorEquals(currlocator,
cur->tag.forkNum != next->tag.forkNum) BufTagGetRelFileLocator(&next->tag)) ||
BufTagGetForkNum(&cur->tag) != BufTagGetForkNum(&next->tag))
break; break;
/* ok, block queued twice, skip */ /* ok, block queued twice, skip */
@@ -4989,8 +5010,8 @@ IssuePendingWritebacks(WritebackContext *context)
i += ahead; i += ahead;
/* and finally tell the kernel to write the data to storage */ /* and finally tell the kernel to write the data to storage */
reln = smgropen(tag.rlocator, InvalidBackendId); reln = smgropen(currlocator, InvalidBackendId);
smgrwriteback(reln, tag.forkNum, tag.blockNum, nblocks); smgrwriteback(reln, BufTagGetForkNum(&tag), tag.blockNum, nblocks);
} }
context->nr_pending = 0; context->nr_pending = 0;

View File

@@ -215,13 +215,13 @@ LocalBufferAlloc(SMgrRelation smgr, ForkNumber forkNum, BlockNumber blockNum,
Page localpage = (char *) LocalBufHdrGetBlock(bufHdr); Page localpage = (char *) LocalBufHdrGetBlock(bufHdr);
/* Find smgr relation for buffer */ /* Find smgr relation for buffer */
oreln = smgropen(bufHdr->tag.rlocator, MyBackendId); oreln = smgropen(BufTagGetRelFileLocator(&bufHdr->tag), MyBackendId);
PageSetChecksumInplace(localpage, bufHdr->tag.blockNum); PageSetChecksumInplace(localpage, bufHdr->tag.blockNum);
/* And write... */ /* And write... */
smgrwrite(oreln, smgrwrite(oreln,
bufHdr->tag.forkNum, BufTagGetForkNum(&bufHdr->tag),
bufHdr->tag.blockNum, bufHdr->tag.blockNum,
localpage, localpage,
false); false);
@@ -337,16 +337,18 @@ DropRelationLocalBuffers(RelFileLocator rlocator, ForkNumber forkNum,
buf_state = pg_atomic_read_u32(&bufHdr->state); buf_state = pg_atomic_read_u32(&bufHdr->state);
if ((buf_state & BM_TAG_VALID) && if ((buf_state & BM_TAG_VALID) &&
RelFileLocatorEquals(bufHdr->tag.rlocator, rlocator) && BufTagMatchesRelFileLocator(&bufHdr->tag, &rlocator) &&
bufHdr->tag.forkNum == forkNum && BufTagGetForkNum(&bufHdr->tag) == forkNum &&
bufHdr->tag.blockNum >= firstDelBlock) bufHdr->tag.blockNum >= firstDelBlock)
{ {
if (LocalRefCount[i] != 0) if (LocalRefCount[i] != 0)
elog(ERROR, "block %u of %s is still referenced (local %u)", elog(ERROR, "block %u of %s is still referenced (local %u)",
bufHdr->tag.blockNum, bufHdr->tag.blockNum,
relpathbackend(bufHdr->tag.rlocator, MyBackendId, relpathbackend(BufTagGetRelFileLocator(&bufHdr->tag),
bufHdr->tag.forkNum), MyBackendId,
BufTagGetForkNum(&bufHdr->tag)),
LocalRefCount[i]); LocalRefCount[i]);
/* Remove entry from hashtable */ /* Remove entry from hashtable */
hresult = (LocalBufferLookupEnt *) hresult = (LocalBufferLookupEnt *)
hash_search(LocalBufHash, (void *) &bufHdr->tag, hash_search(LocalBufHash, (void *) &bufHdr->tag,
@@ -383,13 +385,14 @@ DropRelationAllLocalBuffers(RelFileLocator rlocator)
buf_state = pg_atomic_read_u32(&bufHdr->state); buf_state = pg_atomic_read_u32(&bufHdr->state);
if ((buf_state & BM_TAG_VALID) && if ((buf_state & BM_TAG_VALID) &&
RelFileLocatorEquals(bufHdr->tag.rlocator, rlocator)) BufTagMatchesRelFileLocator(&bufHdr->tag, &rlocator))
{ {
if (LocalRefCount[i] != 0) if (LocalRefCount[i] != 0)
elog(ERROR, "block %u of %s is still referenced (local %u)", elog(ERROR, "block %u of %s is still referenced (local %u)",
bufHdr->tag.blockNum, bufHdr->tag.blockNum,
relpathbackend(bufHdr->tag.rlocator, MyBackendId, relpathbackend(BufTagGetRelFileLocator(&bufHdr->tag),
bufHdr->tag.forkNum), MyBackendId,
BufTagGetForkNum(&bufHdr->tag)),
LocalRefCount[i]); LocalRefCount[i]);
/* Remove entry from hashtable */ /* Remove entry from hashtable */
hresult = (LocalBufferLookupEnt *) hresult = (LocalBufferLookupEnt *)

View File

@@ -90,18 +90,51 @@
*/ */
typedef struct buftag typedef struct buftag
{ {
RelFileLocator rlocator; /* physical relation identifier */ Oid spcOid; /* tablespace oid */
ForkNumber forkNum; Oid dbOid; /* database oid */
RelFileNumber relNumber; /* relation file number */
ForkNumber forkNum; /* fork number */
BlockNumber blockNum; /* blknum relative to begin of reln */ BlockNumber blockNum; /* blknum relative to begin of reln */
} BufferTag; } BufferTag;
static inline RelFileNumber
BufTagGetRelNumber(const BufferTag *tag)
{
return tag->relNumber;
}
static inline ForkNumber
BufTagGetForkNum(const BufferTag *tag)
{
return tag->forkNum;
}
static inline void
BufTagSetRelForkDetails(BufferTag *tag, RelFileNumber relnumber,
ForkNumber forknum)
{
tag->relNumber = relnumber;
tag->forkNum = forknum;
}
static inline RelFileLocator
BufTagGetRelFileLocator(const BufferTag *tag)
{
RelFileLocator rlocator;
rlocator.spcOid = tag->spcOid;
rlocator.dbOid = tag->dbOid;
rlocator.relNumber = BufTagGetRelNumber(tag);
return rlocator;
}
static inline void static inline void
ClearBufferTag(BufferTag *tag) ClearBufferTag(BufferTag *tag)
{ {
tag->rlocator.spcOid = InvalidOid; tag->spcOid = InvalidOid;
tag->rlocator.dbOid = InvalidOid; tag->dbOid = InvalidOid;
tag->rlocator.relNumber = InvalidRelFileNumber; BufTagSetRelForkDetails(tag, InvalidRelFileNumber, InvalidForkNumber);
tag->forkNum = InvalidForkNumber;
tag->blockNum = InvalidBlockNumber; tag->blockNum = InvalidBlockNumber;
} }
@@ -109,19 +142,32 @@ static inline void
InitBufferTag(BufferTag *tag, const RelFileLocator *rlocator, InitBufferTag(BufferTag *tag, const RelFileLocator *rlocator,
ForkNumber forkNum, BlockNumber blockNum) ForkNumber forkNum, BlockNumber blockNum)
{ {
tag->rlocator = *rlocator; tag->spcOid = rlocator->spcOid;
tag->forkNum = forkNum; tag->dbOid = rlocator->dbOid;
BufTagSetRelForkDetails(tag, rlocator->relNumber, forkNum);
tag->blockNum = blockNum; tag->blockNum = blockNum;
} }
static inline bool static inline bool
BufferTagsEqual(const BufferTag *tag1, const BufferTag *tag2) BufferTagsEqual(const BufferTag *tag1, const BufferTag *tag2)
{ {
return RelFileLocatorEquals(tag1->rlocator, tag2->rlocator) && return (tag1->spcOid == tag2->spcOid) &&
(tag1->dbOid == tag2->dbOid) &&
(tag1->relNumber == tag2->relNumber) &&
(tag1->blockNum == tag2->blockNum) && (tag1->blockNum == tag2->blockNum) &&
(tag1->forkNum == tag2->forkNum); (tag1->forkNum == tag2->forkNum);
} }
static inline bool
BufTagMatchesRelFileLocator(const BufferTag *tag,
const RelFileLocator *rlocator)
{
return (tag->spcOid == rlocator->spcOid) &&
(tag->dbOid == rlocator->dbOid) &&
(BufTagGetRelNumber(tag) == rlocator->relNumber);
}
/* /*
* The shared buffer mapping table is partitioned to reduce contention. * The shared buffer mapping table is partitioned to reduce contention.
* To determine which partition lock a given tag requires, compute the tag's * To determine which partition lock a given tag requires, compute the tag's