mirror of
https://github.com/postgres/postgres.git
synced 2025-06-16 06:01:02 +03:00
Another round of code cleanup on bufmgr. Use BM_VALID flag to keep track
of whether we have successfully read data into a buffer; this makes the error behavior a bit more transparent (IMHO anyway), and also makes it work correctly for local buffers which don't use Start/TerminateBufferIO. Collapse three separate functions for writing a shared buffer into one. This overlaps a bit with cleanups that Neil proposed awhile back, but seems not to have committed yet.
This commit is contained in:
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/storage/buffer/buf_init.c,v 1.63 2004/04/19 23:27:17 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/storage/buffer/buf_init.c,v 1.64 2004/04/21 18:06:30 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -133,11 +133,11 @@ InitBufferPool(void)
|
|||||||
|
|
||||||
buf->bufNext = i + 1;
|
buf->bufNext = i + 1;
|
||||||
|
|
||||||
CLEAR_BUFFERTAG(&(buf->tag));
|
CLEAR_BUFFERTAG(buf->tag);
|
||||||
buf->buf_id = i;
|
buf->buf_id = i;
|
||||||
|
|
||||||
buf->data = MAKE_OFFSET(block);
|
buf->data = MAKE_OFFSET(block);
|
||||||
buf->flags = (BM_DELETED | BM_VALID);
|
buf->flags = 0;
|
||||||
buf->refcount = 0;
|
buf->refcount = 0;
|
||||||
buf->io_in_progress_lock = LWLockAssign();
|
buf->io_in_progress_lock = LWLockAssign();
|
||||||
buf->cntx_lock = LWLockAssign();
|
buf->cntx_lock = LWLockAssign();
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -12,7 +12,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/storage/buffer/freelist.c,v 1.42 2004/04/19 23:27:17 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/storage/buffer/freelist.c,v 1.43 2004/04/21 18:06:30 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -501,7 +501,7 @@ StrategyReplaceBuffer(BufferDesc *buf, BufferTag *newTag,
|
|||||||
|
|
||||||
/* Assert that the buffer remembered in cdb_found is the one */
|
/* Assert that the buffer remembered in cdb_found is the one */
|
||||||
/* the buffer manager is currently faulting in */
|
/* the buffer manager is currently faulting in */
|
||||||
Assert(BUFFERTAGS_EQUAL(&(cdb_found->buf_tag), newTag));
|
Assert(BUFFERTAGS_EQUAL(cdb_found->buf_tag, *newTag));
|
||||||
|
|
||||||
if (cdb_replace_index >= 0)
|
if (cdb_replace_index >= 0)
|
||||||
{
|
{
|
||||||
@ -513,7 +513,7 @@ StrategyReplaceBuffer(BufferDesc *buf, BufferTag *newTag,
|
|||||||
Assert(cdb_replace->list == STRAT_LIST_T1 ||
|
Assert(cdb_replace->list == STRAT_LIST_T1 ||
|
||||||
cdb_replace->list == STRAT_LIST_T2);
|
cdb_replace->list == STRAT_LIST_T2);
|
||||||
Assert(cdb_replace->buf_id == buf->buf_id);
|
Assert(cdb_replace->buf_id == buf->buf_id);
|
||||||
Assert(BUFFERTAGS_EQUAL(&(cdb_replace->buf_tag), &(buf->tag)));
|
Assert(BUFFERTAGS_EQUAL(cdb_replace->buf_tag, buf->tag));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Under normal circumstances we move the evicted T list entry to
|
* Under normal circumstances we move the evicted T list entry to
|
||||||
@ -606,7 +606,7 @@ StrategyReplaceBuffer(BufferDesc *buf, BufferTag *newTag,
|
|||||||
Assert(cdb_replace->list == STRAT_LIST_T1 ||
|
Assert(cdb_replace->list == STRAT_LIST_T1 ||
|
||||||
cdb_replace->list == STRAT_LIST_T2);
|
cdb_replace->list == STRAT_LIST_T2);
|
||||||
Assert(cdb_replace->buf_id == buf->buf_id);
|
Assert(cdb_replace->buf_id == buf->buf_id);
|
||||||
Assert(BUFFERTAGS_EQUAL(&(cdb_replace->buf_tag), &(buf->tag)));
|
Assert(BUFFERTAGS_EQUAL(cdb_replace->buf_tag, buf->tag));
|
||||||
|
|
||||||
if (cdb_replace->list == STRAT_LIST_T1)
|
if (cdb_replace->list == STRAT_LIST_T1)
|
||||||
{
|
{
|
||||||
@ -673,7 +673,7 @@ StrategyInvalidateBuffer(BufferDesc *buf)
|
|||||||
BufferStrategyCDB *cdb;
|
BufferStrategyCDB *cdb;
|
||||||
|
|
||||||
/* The buffer cannot be dirty or pinned */
|
/* The buffer cannot be dirty or pinned */
|
||||||
Assert(!(buf->flags & BM_DIRTY));
|
Assert(!(buf->flags & BM_DIRTY) || !(buf->flags & BM_VALID));
|
||||||
Assert(buf->refcount == 0);
|
Assert(buf->refcount == 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -695,16 +695,18 @@ StrategyInvalidateBuffer(BufferDesc *buf)
|
|||||||
* Clear out the CDB's buffer tag and association with the buffer
|
* Clear out the CDB's buffer tag and association with the buffer
|
||||||
* and add it to the list of unused CDB's
|
* and add it to the list of unused CDB's
|
||||||
*/
|
*/
|
||||||
CLEAR_BUFFERTAG(&(cdb->buf_tag));
|
CLEAR_BUFFERTAG(cdb->buf_tag);
|
||||||
cdb->buf_id = -1;
|
cdb->buf_id = -1;
|
||||||
cdb->next = StrategyControl->listUnusedCDB;
|
cdb->next = StrategyControl->listUnusedCDB;
|
||||||
StrategyControl->listUnusedCDB = cdb_id;
|
StrategyControl->listUnusedCDB = cdb_id;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clear out the buffer's tag and add it to the list of
|
* Clear out the buffer's tag and add it to the list of
|
||||||
* currently unused buffers.
|
* currently unused buffers. We must do this to ensure that linear
|
||||||
|
* scans of the buffer array don't think the buffer is valid.
|
||||||
*/
|
*/
|
||||||
CLEAR_BUFFERTAG(&(buf->tag));
|
CLEAR_BUFFERTAG(buf->tag);
|
||||||
|
buf->flags &= ~(BM_VALID | BM_DIRTY);
|
||||||
buf->bufNext = StrategyControl->listFreeBuffers;
|
buf->bufNext = StrategyControl->listFreeBuffers;
|
||||||
StrategyControl->listFreeBuffers = buf->buf_id;
|
StrategyControl->listFreeBuffers = buf->buf_id;
|
||||||
}
|
}
|
||||||
@ -864,7 +866,7 @@ StrategyInitialize(bool init)
|
|||||||
{
|
{
|
||||||
StrategyCDB[i].next = i + 1;
|
StrategyCDB[i].next = i + 1;
|
||||||
StrategyCDB[i].list = STRAT_LIST_UNUSED;
|
StrategyCDB[i].list = STRAT_LIST_UNUSED;
|
||||||
CLEAR_BUFFERTAG(&(StrategyCDB[i].buf_tag));
|
CLEAR_BUFFERTAG(StrategyCDB[i].buf_tag);
|
||||||
StrategyCDB[i].buf_id = -1;
|
StrategyCDB[i].buf_id = -1;
|
||||||
}
|
}
|
||||||
StrategyCDB[NBuffers * 2 - 1].next = -1;
|
StrategyCDB[NBuffers * 2 - 1].next = -1;
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/storage/buffer/localbuf.c,v 1.52 2004/02/10 01:55:25 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/storage/buffer/localbuf.c,v 1.53 2004/04/21 18:06:30 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -36,19 +36,25 @@ static int nextFreeLocalBuf = 0;
|
|||||||
/*
|
/*
|
||||||
* LocalBufferAlloc -
|
* LocalBufferAlloc -
|
||||||
* allocate a local buffer. We do round robin allocation for now.
|
* allocate a local buffer. We do round robin allocation for now.
|
||||||
|
*
|
||||||
|
* API is similar to bufmgr.c's BufferAlloc, except that we do not need
|
||||||
|
* to have the BufMgrLock since this is all local. Also, IO_IN_PROGRESS
|
||||||
|
* does not get set.
|
||||||
*/
|
*/
|
||||||
BufferDesc *
|
BufferDesc *
|
||||||
LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr)
|
LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr)
|
||||||
{
|
{
|
||||||
|
BufferTag newTag; /* identity of requested block */
|
||||||
int i;
|
int i;
|
||||||
BufferDesc *bufHdr = NULL;
|
BufferDesc *bufHdr;
|
||||||
|
|
||||||
|
INIT_BUFFERTAG(newTag, reln, blockNum);
|
||||||
|
|
||||||
/* a low tech search for now -- not optimized for scans */
|
/* a low tech search for now -- not optimized for scans */
|
||||||
for (i = 0; i < NLocBuffer; i++)
|
for (i = 0; i < NLocBuffer; i++)
|
||||||
{
|
{
|
||||||
if (LocalBufferDescriptors[i].tag.rnode.relNode ==
|
bufHdr = &LocalBufferDescriptors[i];
|
||||||
reln->rd_node.relNode &&
|
if (BUFFERTAGS_EQUAL(bufHdr->tag, newTag))
|
||||||
LocalBufferDescriptors[i].tag.blockNum == blockNum)
|
|
||||||
{
|
{
|
||||||
#ifdef LBDEBUG
|
#ifdef LBDEBUG
|
||||||
fprintf(stderr, "LB ALLOC (%u,%d) %d\n",
|
fprintf(stderr, "LB ALLOC (%u,%d) %d\n",
|
||||||
@ -56,8 +62,14 @@ LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
LocalRefCount[i]++;
|
LocalRefCount[i]++;
|
||||||
*foundPtr = TRUE;
|
if (bufHdr->flags & BM_VALID)
|
||||||
return &LocalBufferDescriptors[i];
|
*foundPtr = TRUE;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Previous read attempt must have failed; try again */
|
||||||
|
*foundPtr = FALSE;
|
||||||
|
}
|
||||||
|
return bufHdr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,6 +79,7 @@ LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* need to get a new buffer (round robin for now) */
|
/* need to get a new buffer (round robin for now) */
|
||||||
|
bufHdr = NULL;
|
||||||
for (i = 0; i < NLocBuffer; i++)
|
for (i = 0; i < NLocBuffer; i++)
|
||||||
{
|
{
|
||||||
int b = (nextFreeLocalBuf + i) % NLocBuffer;
|
int b = (nextFreeLocalBuf + i) % NLocBuffer;
|
||||||
@ -108,7 +121,7 @@ LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr)
|
|||||||
*
|
*
|
||||||
* Note this path cannot be taken for a buffer that was previously in
|
* Note this path cannot be taken for a buffer that was previously in
|
||||||
* use, so it's okay to do it (and possibly error out) before marking
|
* use, so it's okay to do it (and possibly error out) before marking
|
||||||
* the buffer as valid.
|
* the buffer as not dirty.
|
||||||
*/
|
*/
|
||||||
if (bufHdr->data == (SHMEM_OFFSET) 0)
|
if (bufHdr->data == (SHMEM_OFFSET) 0)
|
||||||
{
|
{
|
||||||
@ -135,9 +148,8 @@ LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr)
|
|||||||
/*
|
/*
|
||||||
* it's all ours now.
|
* it's all ours now.
|
||||||
*/
|
*/
|
||||||
bufHdr->tag.rnode = reln->rd_node;
|
bufHdr->tag = newTag;
|
||||||
bufHdr->tag.blockNum = blockNum;
|
bufHdr->flags &= ~(BM_VALID | BM_DIRTY | BM_JUST_DIRTIED | BM_IO_ERROR);
|
||||||
bufHdr->flags &= ~BM_DIRTY;
|
|
||||||
bufHdr->cntxDirty = false;
|
bufHdr->cntxDirty = false;
|
||||||
|
|
||||||
*foundPtr = FALSE;
|
*foundPtr = FALSE;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/storage/buf_internals.h,v 1.69 2004/04/19 23:27:17 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/storage/buf_internals.h,v 1.70 2004/04/21 18:06:29 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -24,13 +24,12 @@
|
|||||||
/*
|
/*
|
||||||
* Flags for buffer descriptors
|
* Flags for buffer descriptors
|
||||||
*/
|
*/
|
||||||
#define BM_DIRTY (1 << 0)
|
#define BM_DIRTY (1 << 0) /* data needs writing */
|
||||||
#define BM_VALID (1 << 1)
|
#define BM_VALID (1 << 1) /* data is valid */
|
||||||
#define BM_DELETED (1 << 2)
|
#define BM_IO_IN_PROGRESS (1 << 2) /* read or write in progress */
|
||||||
#define BM_IO_IN_PROGRESS (1 << 3)
|
#define BM_IO_ERROR (1 << 3) /* previous I/O failed */
|
||||||
#define BM_IO_ERROR (1 << 4)
|
#define BM_JUST_DIRTIED (1 << 4) /* dirtied since write started */
|
||||||
#define BM_JUST_DIRTIED (1 << 5)
|
#define BM_PIN_COUNT_WAITER (1 << 5) /* have waiter for sole pin */
|
||||||
#define BM_PIN_COUNT_WAITER (1 << 6)
|
|
||||||
|
|
||||||
typedef bits16 BufFlags;
|
typedef bits16 BufFlags;
|
||||||
|
|
||||||
@ -54,22 +53,21 @@ typedef struct buftag
|
|||||||
|
|
||||||
#define CLEAR_BUFFERTAG(a) \
|
#define CLEAR_BUFFERTAG(a) \
|
||||||
( \
|
( \
|
||||||
(a)->rnode.tblNode = InvalidOid, \
|
(a).rnode.tblNode = InvalidOid, \
|
||||||
(a)->rnode.relNode = InvalidOid, \
|
(a).rnode.relNode = InvalidOid, \
|
||||||
(a)->blockNum = InvalidBlockNumber \
|
(a).blockNum = InvalidBlockNumber \
|
||||||
)
|
)
|
||||||
|
|
||||||
#define INIT_BUFFERTAG(a,xx_reln,xx_blockNum) \
|
#define INIT_BUFFERTAG(a,xx_reln,xx_blockNum) \
|
||||||
( \
|
( \
|
||||||
(a)->blockNum = (xx_blockNum), \
|
(a).rnode = (xx_reln)->rd_node, \
|
||||||
(a)->rnode = (xx_reln)->rd_node \
|
(a).blockNum = (xx_blockNum) \
|
||||||
)
|
)
|
||||||
|
|
||||||
#define BUFFERTAGS_EQUAL(a,b) \
|
#define BUFFERTAGS_EQUAL(a,b) \
|
||||||
( \
|
( \
|
||||||
(a)->rnode.tblNode == (b)->rnode.tblNode && \
|
RelFileNodeEquals((a).rnode, (b).rnode) && \
|
||||||
(a)->rnode.relNode == (b)->rnode.relNode && \
|
(a).blockNum == (b).blockNum \
|
||||||
(a)->blockNum == (b)->blockNum \
|
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/storage/bufmgr.h,v 1.75 2004/02/04 01:24:53 wieck Exp $
|
* $PostgreSQL: pgsql/src/include/storage/bufmgr.h,v 1.76 2004/04/21 18:06:30 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -142,7 +142,7 @@ extern long *LocalRefCount;
|
|||||||
* prototypes for functions in bufmgr.c
|
* prototypes for functions in bufmgr.c
|
||||||
*/
|
*/
|
||||||
extern Buffer ReadBuffer(Relation reln, BlockNumber blockNum);
|
extern Buffer ReadBuffer(Relation reln, BlockNumber blockNum);
|
||||||
extern int ReleaseBuffer(Buffer buffer);
|
extern void ReleaseBuffer(Buffer buffer);
|
||||||
extern void WriteBuffer(Buffer buffer);
|
extern void WriteBuffer(Buffer buffer);
|
||||||
extern void WriteNoReleaseBuffer(Buffer buffer);
|
extern void WriteNoReleaseBuffer(Buffer buffer);
|
||||||
extern Buffer ReleaseAndReadBuffer(Buffer buffer, Relation relation,
|
extern Buffer ReleaseAndReadBuffer(Buffer buffer, Relation relation,
|
||||||
|
Reference in New Issue
Block a user