aboutsummaryrefslogtreecommitdiff
path: root/src/backend/storage/buffer/bufmgr.c
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2008-06-12 09:12:31 +0000
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2008-06-12 09:12:31 +0000
commita213f1ee6c5a1bbe1f074ca201975e76ad2ed50c (patch)
treec5ac3531c006389123da3ba506e5b25eb09ecd02 /src/backend/storage/buffer/bufmgr.c
parentc4f2a0458dc029d1214f013f1434f70f5194e56d (diff)
downloadpostgresql-a213f1ee6c5a1bbe1f074ca201975e76ad2ed50c.tar.gz
postgresql-a213f1ee6c5a1bbe1f074ca201975e76ad2ed50c.zip
Refactor XLogOpenRelation() and XLogReadBuffer() in preparation for relation
forks. XLogOpenRelation() and the associated light-weight relation cache in xlogutils.c is gone, and XLogReadBuffer() now takes a RelFileNode as argument, instead of Relation. For functions that still need a Relation struct during WAL replay, there's a new function called CreateFakeRelcacheEntry() that returns a fake entry like XLogOpenRelation() used to.
Diffstat (limited to 'src/backend/storage/buffer/bufmgr.c')
-rw-r--r--src/backend/storage/buffer/bufmgr.c109
1 files changed, 76 insertions, 33 deletions
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index 7ee888d78d2..a474bd1d3e0 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.231 2008/06/08 22:00:47 alvherre Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.232 2008/06/12 09:12:31 heikki Exp $
*
*-------------------------------------------------------------------------
*/
@@ -76,9 +76,10 @@ static bool IsForInput;
static volatile BufferDesc *PinCountWaitBuf = NULL;
-static Buffer ReadBuffer_common(Relation reln, BlockNumber blockNum,
- bool zeroPage,
- BufferAccessStrategy strategy);
+static Buffer ReadBuffer_relcache(Relation reln, BlockNumber blockNum,
+ bool zeroPage, BufferAccessStrategy strategy);
+static Buffer ReadBuffer_common(SMgrRelation reln, bool isLocalBuf, BlockNumber blockNum,
+ bool zeroPage, BufferAccessStrategy strategy, bool *hit);
static bool PinBuffer(volatile BufferDesc *buf, BufferAccessStrategy strategy);
static void PinBuffer_Locked(volatile BufferDesc *buf);
static void UnpinBuffer(volatile BufferDesc *buf, bool fixOwner);
@@ -89,7 +90,7 @@ static bool StartBufferIO(volatile BufferDesc *buf, bool forInput);
static void TerminateBufferIO(volatile BufferDesc *buf, bool clear_dirty,
int set_flag_bits);
static void buffer_write_error_callback(void *arg);
-static volatile BufferDesc *BufferAlloc(Relation reln, BlockNumber blockNum,
+static volatile BufferDesc *BufferAlloc(SMgrRelation smgr, BlockNumber blockNum,
BufferAccessStrategy strategy,
bool *foundPtr);
static void FlushBuffer(volatile BufferDesc *buf, SMgrRelation reln);
@@ -114,7 +115,7 @@ static void AtProcExit_Buffers(int code, Datum arg);
Buffer
ReadBuffer(Relation reln, BlockNumber blockNum)
{
- return ReadBuffer_common(reln, blockNum, false, NULL);
+ return ReadBuffer_relcache(reln, blockNum, false, NULL);
}
/*
@@ -125,7 +126,7 @@ Buffer
ReadBufferWithStrategy(Relation reln, BlockNumber blockNum,
BufferAccessStrategy strategy)
{
- return ReadBuffer_common(reln, blockNum, false, strategy);
+ return ReadBuffer_relcache(reln, blockNum, false, strategy);
}
/*
@@ -142,41 +143,79 @@ ReadBufferWithStrategy(Relation reln, BlockNumber blockNum,
Buffer
ReadOrZeroBuffer(Relation reln, BlockNumber blockNum)
{
- return ReadBuffer_common(reln, blockNum, true, NULL);
+ return ReadBuffer_relcache(reln, blockNum, true, NULL);
}
/*
- * ReadBuffer_common -- common logic for ReadBuffer variants
+ * ReadBufferWithoutRelcache -- like ReadBuffer, but doesn't require a
+ * relcache entry for the relation. If zeroPage is true, this behaves
+ * like ReadOrZeroBuffer rather than ReadBuffer.
+ */
+Buffer
+ReadBufferWithoutRelcache(RelFileNode rnode, bool isTemp,
+ BlockNumber blockNum, bool zeroPage)
+{
+ bool hit;
+
+ SMgrRelation smgr = smgropen(rnode);
+ return ReadBuffer_common(smgr, isTemp, blockNum, zeroPage, NULL, &hit);
+}
+
+/*
+ * ReadBuffer_relcache -- common logic for ReadBuffer-variants that
+ * operate on a Relation.
+ */
+static Buffer
+ReadBuffer_relcache(Relation reln, BlockNumber blockNum,
+ bool zeroPage, BufferAccessStrategy strategy)
+{
+ bool hit;
+ Buffer buf;
+
+ /* Open it at the smgr level if not already done */
+ RelationOpenSmgr(reln);
+
+ /*
+ * Read the buffer, and update pgstat counters to reflect a cache
+ * hit or miss.
+ */
+ pgstat_count_buffer_read(reln);
+ buf = ReadBuffer_common(reln->rd_smgr, reln->rd_istemp, blockNum,
+ zeroPage, strategy, &hit);
+ if (hit)
+ pgstat_count_buffer_hit(reln);
+ return buf;
+}
+
+/*
+ * ReadBuffer_common -- common logic for all ReadBuffer variants
+ *
+ * *hit is set to true if the request was satisfied from shared buffer cache.
*/
static Buffer
-ReadBuffer_common(Relation reln, BlockNumber blockNum, bool zeroPage,
- BufferAccessStrategy strategy)
+ReadBuffer_common(SMgrRelation smgr, bool isLocalBuf, BlockNumber blockNum,
+ bool zeroPage, BufferAccessStrategy strategy, bool *hit)
{
volatile BufferDesc *bufHdr;
Block bufBlock;
bool found;
bool isExtend;
- bool isLocalBuf;
+
+ *hit = false;
/* Make sure we will have room to remember the buffer pin */
ResourceOwnerEnlargeBuffers(CurrentResourceOwner);
isExtend = (blockNum == P_NEW);
- isLocalBuf = reln->rd_istemp;
-
- /* Open it at the smgr level if not already done */
- RelationOpenSmgr(reln);
/* Substitute proper block number if caller asked for P_NEW */
if (isExtend)
- blockNum = smgrnblocks(reln->rd_smgr);
-
- pgstat_count_buffer_read(reln);
+ blockNum = smgrnblocks(smgr);
if (isLocalBuf)
{
ReadLocalBufferCount++;
- bufHdr = LocalBufferAlloc(reln, blockNum, &found);
+ bufHdr = LocalBufferAlloc(smgr, blockNum, &found);
if (found)
LocalBufferHitCount++;
}
@@ -188,7 +227,7 @@ ReadBuffer_common(Relation reln, BlockNumber blockNum, bool zeroPage,
* lookup the buffer. IO_IN_PROGRESS is set if the requested block is
* not currently in memory.
*/
- bufHdr = BufferAlloc(reln, blockNum, strategy, &found);
+ bufHdr = BufferAlloc(smgr, blockNum, strategy, &found);
if (found)
BufferHitCount++;
}
@@ -201,7 +240,7 @@ ReadBuffer_common(Relation reln, BlockNumber blockNum, bool zeroPage,
if (!isExtend)
{
/* Just need to update stats before we exit */
- pgstat_count_buffer_hit(reln);
+ *hit = true;
if (VacuumCostActive)
VacuumCostBalance += VacuumCostPageHit;
@@ -225,8 +264,8 @@ ReadBuffer_common(Relation reln, BlockNumber blockNum, bool zeroPage,
bufBlock = isLocalBuf ? LocalBufHdrGetBlock(bufHdr) : BufHdrGetBlock(bufHdr);
if (!PageIsNew((PageHeader) bufBlock))
ereport(ERROR,
- (errmsg("unexpected data beyond EOF in block %u of relation \"%s\"",
- blockNum, RelationGetRelationName(reln)),
+ (errmsg("unexpected data beyond EOF in block %u of relation %u/%u/%u",
+ blockNum, smgr->smgr_rnode.spcNode, smgr->smgr_rnode.dbNode, smgr->smgr_rnode.relNode),
errhint("This has been seen to occur with buggy kernels; consider updating your system.")));
/*
@@ -278,8 +317,7 @@ ReadBuffer_common(Relation reln, BlockNumber blockNum, bool zeroPage,
{
/* new buffers are zero-filled */
MemSet((char *) bufBlock, 0, BLCKSZ);
- smgrextend(reln->rd_smgr, blockNum, (char *) bufBlock,
- reln->rd_istemp);
+ smgrextend(smgr, blockNum, (char *) bufBlock, isLocalBuf);
}
else
{
@@ -290,7 +328,7 @@ ReadBuffer_common(Relation reln, BlockNumber blockNum, bool zeroPage,
if (zeroPage)
MemSet((char *) bufBlock, 0, BLCKSZ);
else
- smgrread(reln->rd_smgr, blockNum, (char *) bufBlock);
+ smgrread(smgr, blockNum, (char *) bufBlock);
/* check for garbage data */
if (!PageHeaderIsValid((PageHeader) bufBlock))
{
@@ -298,15 +336,20 @@ ReadBuffer_common(Relation reln, BlockNumber blockNum, bool zeroPage,
{
ereport(WARNING,
(errcode(ERRCODE_DATA_CORRUPTED),
- errmsg("invalid page header in block %u of relation \"%s\"; zeroing out page",
- blockNum, RelationGetRelationName(reln))));
+ errmsg("invalid page header in block %u of relation %u/%u/%u; zeroing out page",
+ blockNum,
+ smgr->smgr_rnode.spcNode,
+ smgr->smgr_rnode.dbNode,
+ smgr->smgr_rnode.relNode)));
MemSet((char *) bufBlock, 0, BLCKSZ);
}
else
ereport(ERROR,
(errcode(ERRCODE_DATA_CORRUPTED),
- errmsg("invalid page header in block %u of relation \"%s\"",
- blockNum, RelationGetRelationName(reln))));
+ errmsg("invalid page header in block %u of relation %u/%u/%u",
+ blockNum, smgr->smgr_rnode.spcNode,
+ smgr->smgr_rnode.dbNode,
+ smgr->smgr_rnode.relNode)));
}
}
@@ -347,7 +390,7 @@ ReadBuffer_common(Relation reln, BlockNumber blockNum, bool zeroPage,
* No locks are held either at entry or exit.
*/
static volatile BufferDesc *
-BufferAlloc(Relation reln,
+BufferAlloc(SMgrRelation smgr,
BlockNumber blockNum,
BufferAccessStrategy strategy,
bool *foundPtr)
@@ -364,7 +407,7 @@ BufferAlloc(Relation reln,
bool valid;
/* create a tag so we can lookup the buffer */
- INIT_BUFFERTAG(newTag, reln, blockNum);
+ INIT_BUFFERTAG(newTag, smgr->smgr_rnode, blockNum);
/* determine its hash code and partition lock ID */
newHash = BufTableHashCode(&newTag);