1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-16 06:01:02 +03:00

2nd try for the ARC strategy.

I added a couple more Assertions while tracking down the exact
cause of the former bug.

All 93 regression tests pass now.

Jan
This commit is contained in:
Jan Wieck
2003-11-13 14:57:15 +00:00
parent 923e994d79
commit 6b86d62b00
9 changed files with 967 additions and 225 deletions

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.143 2003/11/13 05:34:58 wieck Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.144 2003/11/13 14:57:15 wieck Exp $
*
*-------------------------------------------------------------------------
*/
@ -260,12 +260,8 @@ ReadBufferInternal(Relation reln, BlockNumber blockNum,
if (status == SM_FAIL)
{
/* IO Failed. cleanup the data structures and go home */
StrategyInvalidateBuffer(bufHdr);
if (!BufTableDelete(bufHdr))
{
LWLockRelease(BufMgrLock);
elog(FATAL, "buffer table broken after I/O error");
}
/* remember that BufferAlloc() pinned the buffer */
UnpinBuffer(bufHdr);
@ -318,7 +314,7 @@ BufferAlloc(Relation reln,
INIT_BUFFERTAG(&newTag, reln, blockNum);
/* see if the block is in the buffer pool already */
buf = BufTableLookup(&newTag);
buf = StrategyBufferLookup(&newTag, false);
if (buf != NULL)
{
/*
@ -379,7 +375,7 @@ BufferAlloc(Relation reln,
inProgress = FALSE;
for (buf = (BufferDesc *) NULL; buf == (BufferDesc *) NULL;)
{
buf = GetFreeBuffer();
buf = StrategyGetBuffer();
/* GetFreeBuffer will abort if it can't find a free buffer */
Assert(buf);
@ -492,7 +488,7 @@ BufferAlloc(Relation reln,
* we haven't gotten around to insert the new tag into the
* buffer table. So we need to check here. -ay 3/95
*/
buf2 = BufTableLookup(&newTag);
buf2 = StrategyBufferLookup(&newTag, true);
if (buf2 != NULL)
{
/*
@ -535,29 +531,12 @@ BufferAlloc(Relation reln,
*/
/*
* Change the name of the buffer in the lookup table:
*
* Need to update the lookup table before the read starts. If someone
* comes along looking for the buffer while we are reading it in, we
* don't want them to allocate a new buffer. For the same reason, we
* didn't want to erase the buf table entry for the buffer we were
* writing back until now, either.
* Tell the buffer replacement strategy that we are replacing the
* buffer content. Then rename the buffer.
*/
if (!BufTableDelete(buf))
{
LWLockRelease(BufMgrLock);
elog(FATAL, "buffer wasn't in the buffer hash table");
}
StrategyReplaceBuffer(buf, reln, blockNum);
INIT_BUFFERTAG(&(buf->tag), reln, blockNum);
if (!BufTableInsert(buf))
{
LWLockRelease(BufMgrLock);
elog(FATAL, "buffer in buffer hash table twice");
}
/*
* Buffer contents are currently invalid. Have to mark IO IN PROGRESS
* so no one fiddles with them until the read completes. If this
@ -709,13 +688,28 @@ BufferSync(void)
BufferDesc *bufHdr;
ErrorContextCallback errcontext;
int num_buffer_dirty;
int *buffer_dirty;
/* Setup error traceback support for ereport() */
errcontext.callback = buffer_write_error_callback;
errcontext.arg = NULL;
errcontext.previous = error_context_stack;
error_context_stack = &errcontext;
for (i = 0, bufHdr = BufferDescriptors; i < NBuffers; i++, bufHdr++)
/*
* Get a list of all currently dirty buffers and how many there are.
* We do not flush buffers that get dirtied after we started. They
* have to wait until the next checkpoint.
*/
buffer_dirty = (int *)palloc(NBuffers * sizeof(int));
num_buffer_dirty = 0;
LWLockAcquire(BufMgrLock, LW_EXCLUSIVE);
num_buffer_dirty = StrategyDirtyBufferList(buffer_dirty, NBuffers);
LWLockRelease(BufMgrLock);
for (i = 0; i < num_buffer_dirty; i++)
{
Buffer buffer;
int status;
@ -723,10 +717,11 @@ BufferSync(void)
XLogRecPtr recptr;
Relation reln;
errcontext.arg = bufHdr;
LWLockAcquire(BufMgrLock, LW_EXCLUSIVE);
bufHdr = &BufferDescriptors[buffer_dirty[i]];
errcontext.arg = bufHdr;
if (!(bufHdr->flags & BM_VALID))
{
LWLockRelease(BufMgrLock);
@ -855,6 +850,8 @@ BufferSync(void)
RelationDecrementReferenceCount(reln);
}
pfree(buffer_dirty);
/* Pop the error context stack */
error_context_stack = errcontext.previous;
}
@ -959,9 +956,9 @@ AtEOXact_Buffers(bool isCommit)
if (isCommit)
elog(WARNING,
"buffer refcount leak: [%03d] (freeNext=%d, freePrev=%d, "
"buffer refcount leak: [%03d] (bufNext=%d, "
"rel=%u/%u, blockNum=%u, flags=0x%x, refcount=%d %ld)",
i, buf->freeNext, buf->freePrev,
i, buf->bufNext,
buf->tag.rnode.tblNode, buf->tag.rnode.relNode,
buf->tag.blockNum, buf->flags,
buf->refcount, PrivateRefCount[i]);
@ -1229,7 +1226,7 @@ recheck:
/*
* And mark the buffer as no longer occupied by this rel.
*/
BufTableDelete(bufHdr);
StrategyInvalidateBuffer(bufHdr);
}
}
@ -1295,7 +1292,7 @@ recheck:
/*
* And mark the buffer as no longer occupied by this page.
*/
BufTableDelete(bufHdr);
StrategyInvalidateBuffer(bufHdr);
}
}
@ -1543,7 +1540,7 @@ FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock)
return -2;
}
if (bufHdr->tag.blockNum >= firstDelBlock)
BufTableDelete(bufHdr);
StrategyInvalidateBuffer(bufHdr);
}
}