1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-12 05:01:15 +03:00
Files
postgres/src/backend/storage/buffer/buf_table.c
Tom Lane f923260ec8 Revise FlushRelationBuffers/ReleaseRelationBuffers per discussion with
Hiroshi.  ReleaseRelationBuffers now removes rel's buffers from pool,
instead of merely marking them nondirty.  The old code would leave valid
buffers for a deleted relation, which didn't cause any known problems
but can't possibly be a good idea.  There were several places which called
ReleaseRelationBuffers *and* FlushRelationBuffers, which is now
unnecessary; but there were others that did not.  FlushRelationBuffers
no longer emits a warning notice if it finds dirty buffers to flush,
because with the current bufmgr behavior that's not an unexpected
condition.  Also, FlushRelationBuffers will flush out all dirty buffers
for the relation regardless of block number.  This ensures that
pg_upgrade's expectations are met about tuple on-row status bits being
up-to-date on disk.  Lastly, tweak BufTableDelete() to clear the
buffer's tag so that no one can mistake it for being a still-valid
buffer for the page it once held.  Formerly, the buffer would not be
found by buffer hashtable searches after BufTableDelete(), but it would
still be thought to belong to its old relation by the routines that
sequentially scan the shared-buffer array.  Again I know of no bugs
caused by that, but it still can't be a good idea.
2000-05-19 03:22:31 +00:00

176 lines
3.4 KiB
C

/*-------------------------------------------------------------------------
*
* buf_table.c
* routines for finding buffers in the buffer pool.
*
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/buf_table.c,v 1.17 2000/05/19 03:22:28 tgl Exp $
*
*-------------------------------------------------------------------------
*/
/*
* OLD COMMENTS
*
* Data Structures:
*
* Buffers are identified by their BufferTag (buf.h). This
* file contains routines for allocating a shmem hash table to
* map buffer tags to buffer descriptors.
*
* Synchronization:
*
* All routines in this file assume buffer manager spinlock is
* held by their caller.
*/
#include "postgres.h"
#include "storage/bufmgr.h"
static HTAB *SharedBufHash;
typedef struct lookup
{
BufferTag key;
Buffer id;
} LookupEnt;
/*
* Initialize shmem hash table for mapping buffers
*/
void
InitBufTable()
{
HASHCTL info;
int hash_flags;
/* assume lock is held */
/* BufferTag maps to Buffer */
info.keysize = sizeof(BufferTag);
info.datasize = sizeof(Buffer);
info.hash = tag_hash;
hash_flags = (HASH_ELEM | HASH_FUNCTION);
SharedBufHash = (HTAB *) ShmemInitHash("Shared Buffer Lookup Table",
NBuffers, NBuffers,
&info, hash_flags);
if (!SharedBufHash)
{
elog(FATAL, "couldn't initialize shared buffer pool Hash Tbl");
exit(1);
}
}
BufferDesc *
BufTableLookup(BufferTag *tagPtr)
{
LookupEnt *result;
bool found;
if (tagPtr->blockNum == P_NEW)
return NULL;
result = (LookupEnt *)
hash_search(SharedBufHash, (char *) tagPtr, HASH_FIND, &found);
if (!result)
{
elog(ERROR, "BufTableLookup: BufferLookup table corrupted");
return NULL;
}
if (!found)
return NULL;
return &(BufferDescriptors[result->id]);
}
/*
* BufTableDelete
*/
bool
BufTableDelete(BufferDesc *buf)
{
LookupEnt *result;
bool found;
/*
* buffer not initialized or has been removed from table already.
* BM_DELETED keeps us from removing buffer twice.
*/
if (buf->flags & BM_DELETED)
return TRUE;
buf->flags |= BM_DELETED;
result = (LookupEnt *)
hash_search(SharedBufHash, (char *) &(buf->tag), HASH_REMOVE, &found);
if (!(result && found))
{
elog(ERROR, "BufTableDelete: BufferLookup table corrupted");
return FALSE;
}
/*
* Clear the buffer's tag. This doesn't matter for the hash table,
* since the buffer is already removed from it, but it ensures that
* sequential searches through the buffer table won't think the
* buffer is still valid for its old page.
*/
buf->tag.relId.relId = InvalidOid;
buf->tag.relId.dbId = InvalidOid;
return TRUE;
}
bool
BufTableInsert(BufferDesc *buf)
{
LookupEnt *result;
bool found;
/* cannot insert it twice */
Assert(buf->flags & BM_DELETED);
buf->flags &= ~(BM_DELETED);
result = (LookupEnt *)
hash_search(SharedBufHash, (char *) &(buf->tag), HASH_ENTER, &found);
if (!result)
{
Assert(0);
elog(ERROR, "BufTableInsert: BufferLookup table corrupted");
return FALSE;
}
/* found something else in the table ! */
if (found)
{
Assert(0);
elog(ERROR, "BufTableInsert: BufferLookup table corrupted");
return FALSE;
}
result->id = buf->buf_id;
return TRUE;
}
/* prints out collision stats for the buf table */
#ifdef NOT_USED
void
DBG_LookupListCheck(int nlookup)
{
nlookup = 10;
hash_stats("Shared", SharedBufHash);
}
#endif