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