Commit 4b65a284 authored by Vadim B. Mikheev's avatar Vadim B. Mikheev

New relcache hash table with RelFileNode as key to be used

from bufmgr - it would be nice to have separate hash in smgr
for node <--> fd mappings, but for the moment it's easy to
add new hash to relcache.
Fixed small bug in xlog.c:ReadRecord.
parent c82c9559
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.74 2000/10/21 15:43:22 vadim Exp $ * $Header: /cvsroot/pgsql/src/backend/access/transam/xact.c,v 1.75 2000/10/23 04:10:05 vadim Exp $
* *
* NOTES * NOTES
* Transaction aborts can now occur two ways: * Transaction aborts can now occur two ways:
...@@ -676,6 +676,7 @@ RecordTransactionCommit() ...@@ -676,6 +676,7 @@ RecordTransactionCommit()
*/ */
leak = BufferPoolCheckLeak(); leak = BufferPoolCheckLeak();
#ifndef XLOG
/* /*
* If no one shared buffer was changed by this transaction then we * If no one shared buffer was changed by this transaction then we
* don't flush shared buffers and don't record commit status. * don't flush shared buffers and don't record commit status.
...@@ -686,6 +687,7 @@ RecordTransactionCommit() ...@@ -686,6 +687,7 @@ RecordTransactionCommit()
if (leak) if (leak)
ResetBufferPool(true); ResetBufferPool(true);
#endif
/* /*
* have the transaction access methods record the status of this * have the transaction access methods record the status of this
* transaction id in the pg_log relation. * transaction id in the pg_log relation.
...@@ -717,13 +719,14 @@ RecordTransactionCommit() ...@@ -717,13 +719,14 @@ RecordTransactionCommit()
MyLastRecPtr.xlogid = 0; MyLastRecPtr.xlogid = 0;
MyLastRecPtr.xrecoff = 0; MyLastRecPtr.xrecoff = 0;
} }
#endif #else
/* /*
* Now write the log info to the disk too. * Now write the log info to the disk too.
*/ */
leak = BufferPoolCheckLeak(); leak = BufferPoolCheckLeak();
FlushBufferPool(); FlushBufferPool();
} }
#endif
if (leak) if (leak)
ResetBufferPool(true); ResetBufferPool(true);
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.19 2000/10/21 15:43:22 vadim Exp $ * $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.20 2000/10/23 04:10:05 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -991,6 +991,7 @@ got_record:; ...@@ -991,6 +991,7 @@ got_record:;
nextRecord = (XLogRecord *) ((char *) subrecord + nextRecord = (XLogRecord *) ((char *) subrecord +
MAXALIGN(subrecord->xl_len) + SizeOfXLogSubRecord); MAXALIGN(subrecord->xl_len) + SizeOfXLogSubRecord);
} }
record->xl_len = len;
EndRecPtr.xlogid = readId; EndRecPtr.xlogid = readId;
EndRecPtr.xrecoff = readSeg * XLogSegSize + readOff * BLCKSZ + EndRecPtr.xrecoff = readSeg * XLogSegSize + readOff * BLCKSZ +
SizeOfXLogPHD + SizeOfXLogSubRecord + SizeOfXLogPHD + SizeOfXLogSubRecord +
...@@ -1412,7 +1413,9 @@ StartupXLOG() ...@@ -1412,7 +1413,9 @@ StartupXLOG()
{ {
char buf[8192]; char buf[8192];
sprintf(buf, "REDO @ %u/%u: ", ReadRecPtr.xlogid, ReadRecPtr.xrecoff); sprintf(buf, "REDO @ %u/%u; LSN %u/%u: ",
ReadRecPtr.xlogid, ReadRecPtr.xrecoff,
EndRecPtr.xlogid, EndRecPtr.xrecoff);
xlog_outrec(buf, record); xlog_outrec(buf, record);
strcat(buf, " - "); strcat(buf, " - ");
RmgrTable[record->xl_rmid].rm_desc(buf, RmgrTable[record->xl_rmid].rm_desc(buf,
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/buf_init.c,v 1.36 2000/10/18 05:50:15 vadim Exp $ * $Header: /cvsroot/pgsql/src/backend/storage/buffer/buf_init.c,v 1.37 2000/10/23 04:10:06 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -68,7 +68,6 @@ bits8 *BufferLocks; /* flag bits showing locks I have set */ ...@@ -68,7 +68,6 @@ bits8 *BufferLocks; /* flag bits showing locks I have set */
BufferTag *BufferTagLastDirtied; /* tag buffer had when last BufferTag *BufferTagLastDirtied; /* tag buffer had when last
* dirtied by me */ * dirtied by me */
BufferBlindId *BufferBlindLastDirtied; BufferBlindId *BufferBlindLastDirtied;
LockRelId *BufferRelidLastDirtied;
bool *BufferDirtiedByMe; /* T if buf has been dirtied in cur xact */ bool *BufferDirtiedByMe; /* T if buf has been dirtied in cur xact */
...@@ -252,7 +251,6 @@ InitBufferPool(IPCKey key) ...@@ -252,7 +251,6 @@ InitBufferPool(IPCKey key)
BufferLocks = (bits8 *) calloc(NBuffers, sizeof(bits8)); BufferLocks = (bits8 *) calloc(NBuffers, sizeof(bits8));
BufferTagLastDirtied = (BufferTag *) calloc(NBuffers, sizeof(BufferTag)); BufferTagLastDirtied = (BufferTag *) calloc(NBuffers, sizeof(BufferTag));
BufferBlindLastDirtied = (BufferBlindId *) calloc(NBuffers, sizeof(BufferBlindId)); BufferBlindLastDirtied = (BufferBlindId *) calloc(NBuffers, sizeof(BufferBlindId));
BufferRelidLastDirtied = (LockRelId *) calloc(NBuffers, sizeof(LockRelId));
BufferDirtiedByMe = (bool *) calloc(NBuffers, sizeof(bool)); BufferDirtiedByMe = (bool *) calloc(NBuffers, sizeof(bool));
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.90 2000/10/22 20:20:49 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.91 2000/10/23 04:10:06 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -54,6 +54,10 @@ ...@@ -54,6 +54,10 @@
#include "storage/smgr.h" #include "storage/smgr.h"
#include "utils/relcache.h" #include "utils/relcache.h"
#ifdef XLOG
#include "catalog/pg_database.h"
#endif
extern SPINLOCK BufMgrLock; extern SPINLOCK BufMgrLock;
extern long int ReadBufferCount; extern long int ReadBufferCount;
extern long int ReadLocalBufferCount; extern long int ReadLocalBufferCount;
...@@ -611,7 +615,6 @@ BufferAlloc(Relation reln, ...@@ -611,7 +615,6 @@ BufferAlloc(Relation reln,
/* record the database name and relation name for this buffer */ /* record the database name and relation name for this buffer */
strcpy(buf->blind.dbname, (DatabaseName) ? DatabaseName : "Recovery"); strcpy(buf->blind.dbname, (DatabaseName) ? DatabaseName : "Recovery");
strcpy(buf->blind.relname, RelationGetPhysicalRelationName(reln)); strcpy(buf->blind.relname, RelationGetPhysicalRelationName(reln));
buf->relId = reln->rd_lockInfo.lockRelId;
INIT_BUFFERTAG(&(buf->tag), reln, blockNum); INIT_BUFFERTAG(&(buf->tag), reln, blockNum);
if (!BufTableInsert(buf)) if (!BufTableInsert(buf))
...@@ -711,7 +714,6 @@ int ...@@ -711,7 +714,6 @@ int
FlushBuffer(Buffer buffer, bool release) FlushBuffer(Buffer buffer, bool release)
{ {
BufferDesc *bufHdr; BufferDesc *bufHdr;
Oid bufdb;
Relation bufrel; Relation bufrel;
int status; int status;
...@@ -725,10 +727,7 @@ FlushBuffer(Buffer buffer, bool release) ...@@ -725,10 +727,7 @@ FlushBuffer(Buffer buffer, bool release)
bufHdr = &BufferDescriptors[buffer - 1]; bufHdr = &BufferDescriptors[buffer - 1];
bufdb = bufHdr->relId.dbId; bufrel = RelationNodeCacheGetRelation(bufHdr->tag.rnode);
Assert(bufdb == MyDatabaseId || bufdb == (Oid) NULL);
bufrel = RelationIdCacheGetRelation(bufHdr->relId.relId);
Assert(bufrel != (Relation) NULL); Assert(bufrel != (Relation) NULL);
...@@ -904,7 +903,7 @@ SetBufferDirtiedByMe(Buffer buffer, BufferDesc *bufHdr) ...@@ -904,7 +903,7 @@ SetBufferDirtiedByMe(Buffer buffer, BufferDesc *bufHdr)
SpinRelease(BufMgrLock); SpinRelease(BufMgrLock);
#endif /* OPTIMIZE_SINGLE */ #endif /* OPTIMIZE_SINGLE */
reln = RelationIdCacheGetRelation(BufferRelidLastDirtied[buffer - 1].relId); reln = RelationNodeCacheGetRelation(tagLastDirtied->rnode);
if (reln == (Relation) NULL) if (reln == (Relation) NULL)
{ {
...@@ -938,7 +937,6 @@ SetBufferDirtiedByMe(Buffer buffer, BufferDesc *bufHdr) ...@@ -938,7 +937,6 @@ SetBufferDirtiedByMe(Buffer buffer, BufferDesc *bufHdr)
} }
*tagLastDirtied = bufHdr->tag; *tagLastDirtied = bufHdr->tag;
BufferRelidLastDirtied[buffer - 1] = bufHdr->relId;
BufferBlindLastDirtied[buffer - 1] = bufHdr->blind; BufferBlindLastDirtied[buffer - 1] = bufHdr->blind;
BufferDirtiedByMe[buffer - 1] = true; BufferDirtiedByMe[buffer - 1] = true;
} }
...@@ -1010,15 +1008,14 @@ BufferSync() ...@@ -1010,15 +1008,14 @@ BufferSync()
if (RelFileNodeEquals(bufHdr->tag.rnode, BufferTagLastDirtied[i].rnode) && if (RelFileNodeEquals(bufHdr->tag.rnode, BufferTagLastDirtied[i].rnode) &&
bufHdr->tag.blockNum == BufferTagLastDirtied[i].blockNum) bufHdr->tag.blockNum == BufferTagLastDirtied[i].blockNum)
{ {
Oid bufrel = bufHdr->relId.relId;
/* /*
* Try to find relation for buf. This could fail, if the * Try to find relation for buf. This could fail, if the
* rel has been flushed from the relcache since we dirtied * rel has been flushed from the relcache since we dirtied
* the page. That should be uncommon, so paying the extra * the page. That should be uncommon, so paying the extra
* cost of a blind write when it happens seems OK. * cost of a blind write when it happens seems OK.
*/ */
reln = RelationIdCacheGetRelation(bufrel); if (!InRecovery)
reln = RelationNodeCacheGetRelation(bufHdr->tag.rnode);
/* /*
* We have to pin buffer to keep anyone from stealing it * We have to pin buffer to keep anyone from stealing it
...@@ -1083,8 +1080,6 @@ BufferSync() ...@@ -1083,8 +1080,6 @@ BufferSync()
} }
else else
{ {
Assert(RelFileNodeEquals(reln->rd_node,
BufferTagLastDirtied[i].rnode));
status = smgrwrite(DEFAULT_SMGR, reln, status = smgrwrite(DEFAULT_SMGR, reln,
bufHdr->tag.blockNum, bufHdr->tag.blockNum,
(char *) MAKE_PTR(bufHdr->data)); (char *) MAKE_PTR(bufHdr->data));
...@@ -1138,7 +1133,7 @@ BufferSync() ...@@ -1138,7 +1133,7 @@ BufferSync()
SpinRelease(BufMgrLock); SpinRelease(BufMgrLock);
#endif /* OPTIMIZE_SINGLE */ #endif /* OPTIMIZE_SINGLE */
reln = RelationIdCacheGetRelation(BufferRelidLastDirtied[i].relId); reln = RelationNodeCacheGetRelation(BufferTagLastDirtied[i].rnode);
if (reln == (Relation) NULL) if (reln == (Relation) NULL)
{ {
status = smgrblindmarkdirty(DEFAULT_SMGR, status = smgrblindmarkdirty(DEFAULT_SMGR,
...@@ -1147,8 +1142,6 @@ BufferSync() ...@@ -1147,8 +1142,6 @@ BufferSync()
} }
else else
{ {
Assert(RelFileNodeEquals(reln->rd_node,
BufferTagLastDirtied[i].rnode));
status = smgrmarkdirty(DEFAULT_SMGR, reln, status = smgrmarkdirty(DEFAULT_SMGR, reln,
BufferTagLastDirtied[i].blockNum); BufferTagLastDirtied[i].blockNum);
...@@ -1420,21 +1413,14 @@ static int ...@@ -1420,21 +1413,14 @@ static int
BufferReplace(BufferDesc *bufHdr) BufferReplace(BufferDesc *bufHdr)
{ {
Relation reln; Relation reln;
Oid bufdb,
bufrel;
int status; int status;
/* /*
* first try to find the reldesc in the cache, if no luck, don't * first try to find the reldesc in the cache, if no luck, don't
* bother to build the reldesc from scratch, just do a blind write. * bother to build the reldesc from scratch, just do a blind write.
*/ */
bufdb = bufHdr->relId.dbId;
bufrel = bufHdr->relId.relId;
if (bufdb == MyDatabaseId || bufdb == (Oid) NULL) reln = RelationNodeCacheGetRelation(bufHdr->tag.rnode);
reln = RelationIdCacheGetRelation(bufrel);
else
reln = (Relation) NULL;
/* To check if block content changed while flushing. - vadim 01/17/97 */ /* To check if block content changed while flushing. - vadim 01/17/97 */
bufHdr->flags &= ~BM_JUST_DIRTIED; bufHdr->flags &= ~BM_JUST_DIRTIED;
...@@ -1450,7 +1436,6 @@ BufferReplace(BufferDesc *bufHdr) ...@@ -1450,7 +1436,6 @@ BufferReplace(BufferDesc *bufHdr)
if (reln != (Relation) NULL) if (reln != (Relation) NULL)
{ {
Assert(RelFileNodeEquals(bufHdr->tag.rnode, reln->rd_node));
status = smgrwrite(DEFAULT_SMGR, reln, bufHdr->tag.blockNum, status = smgrwrite(DEFAULT_SMGR, reln, bufHdr->tag.blockNum,
(char *) MAKE_PTR(bufHdr->data)); (char *) MAKE_PTR(bufHdr->data));
} }
...@@ -1519,7 +1504,6 @@ RelationGetNumberOfBlocks(Relation relation) ...@@ -1519,7 +1504,6 @@ RelationGetNumberOfBlocks(Relation relation)
void void
ReleaseRelationBuffers(Relation rel) ReleaseRelationBuffers(Relation rel)
{ {
Oid relid = RelationGetRelid(rel);
int i; int i;
BufferDesc *bufHdr; BufferDesc *bufHdr;
...@@ -1534,10 +1518,6 @@ ReleaseRelationBuffers(Relation rel) ...@@ -1534,10 +1518,6 @@ ReleaseRelationBuffers(Relation rel)
LocalRefCount[i] = 0; LocalRefCount[i] = 0;
bufHdr->tag.rnode.relNode = InvalidOid; bufHdr->tag.rnode.relNode = InvalidOid;
} }
else
{
Assert(bufHdr->relId.relId != relid);
}
} }
return; return;
} }
...@@ -1590,12 +1570,6 @@ recheck: ...@@ -1590,12 +1570,6 @@ recheck:
*/ */
BufTableDelete(bufHdr); BufTableDelete(bufHdr);
} }
else
{
Assert(bufHdr->relId.relId != relid ||
(bufHdr->relId.dbId != MyDatabaseId &&
bufHdr->relId.dbId != InvalidOid));
}
/* /*
* Also check to see if BufferDirtiedByMe info for this buffer * Also check to see if BufferDirtiedByMe info for this buffer
...@@ -1608,7 +1582,7 @@ recheck: ...@@ -1608,7 +1582,7 @@ recheck:
* this rel, since we hold exclusive lock on this rel. * this rel, since we hold exclusive lock on this rel.
*/ */
if (RelFileNodeEquals(rel->rd_node, if (RelFileNodeEquals(rel->rd_node,
BufferTagLastDirtied[i - 1].rnode)) BufferTagLastDirtied[i - 1].rnode))
BufferDirtiedByMe[i - 1] = false; BufferDirtiedByMe[i - 1] = false;
} }
...@@ -1673,11 +1647,6 @@ recheck: ...@@ -1673,11 +1647,6 @@ recheck:
*/ */
BufTableDelete(bufHdr); BufTableDelete(bufHdr);
} }
else
{
Assert(bufHdr->relId.dbId != dbid);
}
/* /*
* Also check to see if BufferDirtiedByMe info for this buffer * Also check to see if BufferDirtiedByMe info for this buffer
* refers to the target database, and clear it if so. This is * refers to the target database, and clear it if so. This is
...@@ -1824,7 +1793,6 @@ BufferPoolBlowaway() ...@@ -1824,7 +1793,6 @@ BufferPoolBlowaway()
int int
FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock) FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock)
{ {
Oid relid = RelationGetRelid(rel);
int i; int i;
BufferDesc *bufHdr; BufferDesc *bufHdr;
...@@ -1857,10 +1825,6 @@ FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock) ...@@ -1857,10 +1825,6 @@ FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock)
bufHdr->tag.rnode.relNode = InvalidOid; bufHdr->tag.rnode.relNode = InvalidOid;
} }
} }
else
{
Assert(bufHdr->relId.relId != relid);
}
} }
return 0; return 0;
} }
...@@ -1906,12 +1870,6 @@ recheck: ...@@ -1906,12 +1870,6 @@ recheck:
BufTableDelete(bufHdr); BufTableDelete(bufHdr);
} }
} }
else
{
Assert(bufHdr->relId.relId != relid ||
(bufHdr->relId.dbId != MyDatabaseId &&
bufHdr->relId.dbId != InvalidOid));
}
} }
SpinRelease(BufMgrLock); SpinRelease(BufMgrLock);
return 0; return 0;
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/localbuf.c,v 1.31 2000/10/18 05:50:15 vadim Exp $ * $Header: /cvsroot/pgsql/src/backend/storage/buffer/localbuf.c,v 1.32 2000/10/23 04:10:06 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -103,7 +103,7 @@ LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr) ...@@ -103,7 +103,7 @@ LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr)
*/ */
if (bufHdr->flags & BM_DIRTY) if (bufHdr->flags & BM_DIRTY)
{ {
Relation bufrel = RelationIdCacheGetRelation(bufHdr->relId.relId); Relation bufrel = RelationNodeCacheGetRelation(bufHdr->tag.rnode);
Assert(bufrel != NULL); Assert(bufrel != NULL);
...@@ -127,7 +127,6 @@ LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr) ...@@ -127,7 +127,6 @@ LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr)
*/ */
bufHdr->tag.rnode = reln->rd_node; bufHdr->tag.rnode = reln->rd_node;
bufHdr->tag.blockNum = blockNum; bufHdr->tag.blockNum = blockNum;
bufHdr->relId = reln->rd_lockInfo.lockRelId;
bufHdr->flags &= ~BM_DIRTY; bufHdr->flags &= ~BM_DIRTY;
/* /*
...@@ -192,7 +191,7 @@ FlushLocalBuffer(Buffer buffer, bool release) ...@@ -192,7 +191,7 @@ FlushLocalBuffer(Buffer buffer, bool release)
bufid = -(buffer + 1); bufid = -(buffer + 1);
bufHdr = &LocalBufferDescriptors[bufid]; bufHdr = &LocalBufferDescriptors[bufid];
bufHdr->flags &= ~BM_DIRTY; bufHdr->flags &= ~BM_DIRTY;
bufrel = RelationIdCacheGetRelation(bufHdr->relId.relId); bufrel = RelationNodeCacheGetRelation(bufHdr->tag.rnode);
Assert(bufrel != NULL); Assert(bufrel != NULL);
smgrflush(DEFAULT_SMGR, bufrel, bufHdr->tag.blockNum, smgrflush(DEFAULT_SMGR, bufrel, bufHdr->tag.blockNum,
...@@ -268,7 +267,7 @@ LocalBufferSync(void) ...@@ -268,7 +267,7 @@ LocalBufferSync(void)
#ifdef LBDEBUG #ifdef LBDEBUG
fprintf(stderr, "LB SYNC %d\n", -i - 1); fprintf(stderr, "LB SYNC %d\n", -i - 1);
#endif #endif
bufrel = RelationIdCacheGetRelation(buf->relId.relId); bufrel = RelationNodeCacheGetRelation(buf->tag.rnode);
Assert(bufrel != NULL); Assert(bufrel != NULL);
...@@ -279,7 +278,6 @@ LocalBufferSync(void) ...@@ -279,7 +278,6 @@ LocalBufferSync(void)
/* drop relcache refcount from RelationIdCacheGetRelation */ /* drop relcache refcount from RelationIdCacheGetRelation */
RelationDecrementReferenceCount(bufrel); RelationDecrementReferenceCount(bufrel);
buf->relId.relId = InvalidOid;
buf->flags &= ~BM_DIRTY; buf->flags &= ~BM_DIRTY;
} }
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.112 2000/10/16 14:52:13 vadim Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.113 2000/10/23 04:10:08 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -83,6 +83,13 @@ static FormData_pg_attribute Desc_pg_log[Natts_pg_log] = {Schema_pg_log}; ...@@ -83,6 +83,13 @@ static FormData_pg_attribute Desc_pg_log[Natts_pg_log] = {Schema_pg_log};
static HTAB *RelationNameCache; static HTAB *RelationNameCache;
static HTAB *RelationIdCache; static HTAB *RelationIdCache;
/*
* Bufmgr uses RelFileNode for lookup. Actually, I would like to do
* not pass Relation to bufmgr & beyond at all and keep some cache
* in smgr, but no time to do it right way now. -- vadim 10/22/2000
*/
static HTAB *RelationNodeCache;
/* /*
* newlyCreatedRelns - * newlyCreatedRelns -
* relations created during this transaction. We need to keep track of * relations created during this transaction. We need to keep track of
...@@ -114,17 +121,23 @@ typedef struct RelationBuildDescInfo ...@@ -114,17 +121,23 @@ typedef struct RelationBuildDescInfo
} i; } i;
} RelationBuildDescInfo; } RelationBuildDescInfo;
typedef struct relnamecacheent
{
NameData relname;
Relation reldesc;
} RelNameCacheEnt;
typedef struct relidcacheent typedef struct relidcacheent
{ {
Oid reloid; Oid reloid;
Relation reldesc; Relation reldesc;
} RelIdCacheEnt; } RelIdCacheEnt;
typedef struct relnamecacheent typedef struct relnodecacheent
{ {
NameData relname; RelFileNode relnode;
Relation reldesc; Relation reldesc;
} RelNameCacheEnt; } RelNodeCacheEnt;
/* ----------------- /* -----------------
* macros to manipulate name cache and id cache * macros to manipulate name cache and id cache
...@@ -133,7 +146,7 @@ typedef struct relnamecacheent ...@@ -133,7 +146,7 @@ typedef struct relnamecacheent
#define RelationCacheInsert(RELATION) \ #define RelationCacheInsert(RELATION) \
do { \ do { \
RelIdCacheEnt *idhentry; RelNameCacheEnt *namehentry; \ RelIdCacheEnt *idhentry; RelNameCacheEnt *namehentry; \
char *relname; Oid reloid; bool found; \ char *relname; RelNodeCacheEnt *nodentry; bool found; \
relname = RelationGetPhysicalRelationName(RELATION); \ relname = RelationGetPhysicalRelationName(RELATION); \
namehentry = (RelNameCacheEnt*)hash_search(RelationNameCache, \ namehentry = (RelNameCacheEnt*)hash_search(RelationNameCache, \
relname, \ relname, \
...@@ -144,9 +157,8 @@ do { \ ...@@ -144,9 +157,8 @@ do { \
if (found && !IsBootstrapProcessingMode()) \ if (found && !IsBootstrapProcessingMode()) \
/* used to give notice -- now just keep quiet */ ; \ /* used to give notice -- now just keep quiet */ ; \
namehentry->reldesc = RELATION; \ namehentry->reldesc = RELATION; \
reloid = RELATION->rd_id; \
idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \ idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \
(char *)&reloid, \ (char *)&(RELATION->rd_id), \
HASH_ENTER, \ HASH_ENTER, \
&found); \ &found); \
if (idhentry == NULL) \ if (idhentry == NULL) \
...@@ -154,6 +166,15 @@ do { \ ...@@ -154,6 +166,15 @@ do { \
if (found && !IsBootstrapProcessingMode()) \ if (found && !IsBootstrapProcessingMode()) \
/* used to give notice -- now just keep quiet */ ; \ /* used to give notice -- now just keep quiet */ ; \
idhentry->reldesc = RELATION; \ idhentry->reldesc = RELATION; \
nodentry = (RelNodeCacheEnt*)hash_search(RelationNodeCache, \
(char *)&(RELATION->rd_node), \
HASH_ENTER, \
&found); \
if (nodentry == NULL) \
elog(FATAL, "can't insert into relation descriptor cache"); \
if (found && !IsBootstrapProcessingMode()) \
/* used to give notice -- now just keep quiet */ ; \
nodentry->reldesc = RELATION; \
} while(0) } while(0)
#define RelationNameCacheLookup(NAME, RELATION) \ #define RelationNameCacheLookup(NAME, RELATION) \
...@@ -183,10 +204,24 @@ do { \ ...@@ -183,10 +204,24 @@ do { \
RELATION = NULL; \ RELATION = NULL; \
} while(0) } while(0)
#define RelationNodeCacheLookup(NODE, RELATION) \
do { \
RelNodeCacheEnt *hentry; \
bool found; \
hentry = (RelNodeCacheEnt*)hash_search(RelationNodeCache, \
(char *)&(NODE),HASH_FIND, &found); \
if (hentry == NULL) \
elog(FATAL, "error in CACHE"); \
if (found) \
RELATION = hentry->reldesc; \
else \
RELATION = NULL; \
} while(0)
#define RelationCacheDelete(RELATION) \ #define RelationCacheDelete(RELATION) \
do { \ do { \
RelNameCacheEnt *namehentry; RelIdCacheEnt *idhentry; \ RelNameCacheEnt *namehentry; RelIdCacheEnt *idhentry; \
char *relname; Oid reloid; bool found; \ char *relname; RelNodeCacheEnt *nodentry; bool found; \
relname = RelationGetPhysicalRelationName(RELATION); \ relname = RelationGetPhysicalRelationName(RELATION); \
namehentry = (RelNameCacheEnt*)hash_search(RelationNameCache, \ namehentry = (RelNameCacheEnt*)hash_search(RelationNameCache, \
relname, \ relname, \
...@@ -196,14 +231,20 @@ do { \ ...@@ -196,14 +231,20 @@ do { \
elog(FATAL, "can't delete from relation descriptor cache"); \ elog(FATAL, "can't delete from relation descriptor cache"); \
if (!found) \ if (!found) \
elog(NOTICE, "trying to delete a reldesc that does not exist."); \ elog(NOTICE, "trying to delete a reldesc that does not exist."); \
reloid = RELATION->rd_id; \
idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \ idhentry = (RelIdCacheEnt*)hash_search(RelationIdCache, \
(char *)&reloid, \ (char *)&(RELATION->rd_id), \
HASH_REMOVE, &found); \ HASH_REMOVE, &found); \
if (idhentry == NULL) \ if (idhentry == NULL) \
elog(FATAL, "can't delete from relation descriptor cache"); \ elog(FATAL, "can't delete from relation descriptor cache"); \
if (!found) \ if (!found) \
elog(NOTICE, "trying to delete a reldesc that does not exist."); \ elog(NOTICE, "trying to delete a reldesc that does not exist."); \
nodentry = (RelNodeCacheEnt*)hash_search(RelationNodeCache, \
(char *)&(RELATION->rd_node), \
HASH_REMOVE, &found); \
if (nodentry == NULL) \
elog(FATAL, "can't delete from relation descriptor cache"); \
if (!found) \
elog(NOTICE, "trying to delete a reldesc that does not exist."); \
} while(0) } while(0)
/* non-export function prototypes */ /* non-export function prototypes */
...@@ -1192,12 +1233,6 @@ formrdesc(char *relationName, ...@@ -1192,12 +1233,6 @@ formrdesc(char *relationName,
*/ */
RelationInitLockInfo(relation); /* see lmgr.c */ RelationInitLockInfo(relation); /* see lmgr.c */
/* ----------------
* add new reldesc to relcache
* ----------------
*/
RelationCacheInsert(relation);
if (IsSharedSystemRelationName(relationName)) if (IsSharedSystemRelationName(relationName))
relation->rd_node.tblNode = InvalidOid; relation->rd_node.tblNode = InvalidOid;
else else
...@@ -1205,6 +1240,12 @@ formrdesc(char *relationName, ...@@ -1205,6 +1240,12 @@ formrdesc(char *relationName,
relation->rd_node.relNode = relation->rd_node.relNode =
relation->rd_rel->relfilenode = RelationGetRelid(relation); relation->rd_rel->relfilenode = RelationGetRelid(relation);
/* ----------------
* add new reldesc to relcache
* ----------------
*/
RelationCacheInsert(relation);
/* /*
* Determining this requires a scan on pg_class, but to do the scan * Determining this requires a scan on pg_class, but to do the scan
* the rdesc for pg_class must already exist. Therefore we must do * the rdesc for pg_class must already exist. Therefore we must do
...@@ -1343,6 +1384,28 @@ RelationNameCacheGetRelation(const char *relationName) ...@@ -1343,6 +1384,28 @@ RelationNameCacheGetRelation(const char *relationName)
return rd; return rd;
} }
Relation
RelationNodeCacheGetRelation(RelFileNode rnode)
{
Relation rd;
RelationNodeCacheLookup(rnode, rd);
if (RelationIsValid(rd))
{
if (rd->rd_fd == -1 && rd->rd_rel->relkind != RELKIND_VIEW)
{
rd->rd_fd = smgropen(DEFAULT_SMGR, rd);
Assert(rd->rd_fd != -1 || rd->rd_unlinked);
}
RelationIncrementReferenceCount(rd);
}
return rd;
}
/* -------------------------------- /* --------------------------------
* RelationIdGetRelation * RelationIdGetRelation
* *
...@@ -1942,6 +2005,11 @@ RelationCacheInitialize(void) ...@@ -1942,6 +2005,11 @@ RelationCacheInitialize(void)
RelationIdCache = hash_create(INITRELCACHESIZE, &ctl, RelationIdCache = hash_create(INITRELCACHESIZE, &ctl,
HASH_ELEM | HASH_FUNCTION); HASH_ELEM | HASH_FUNCTION);
ctl.keysize = sizeof(RelFileNode);
ctl.hash = tag_hash;
RelationNodeCache = hash_create(INITRELCACHESIZE, &ctl,
HASH_ELEM | HASH_FUNCTION);
/* ---------------- /* ----------------
* initialize the cache with pre-made relation descriptors * initialize the cache with pre-made relation descriptors
* for some of the more important system relations. These * for some of the more important system relations. These
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: buf_internals.h,v 1.40 2000/10/20 11:01:21 vadim Exp $ * $Id: buf_internals.h,v 1.41 2000/10/23 04:10:14 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -109,22 +109,6 @@ typedef struct sbufdesc ...@@ -109,22 +109,6 @@ typedef struct sbufdesc
bool ri_lock; /* read-intent lock */ bool ri_lock; /* read-intent lock */
bool w_lock; /* context exclusively locked */ bool w_lock; /* context exclusively locked */
/*
* This is logical information about relation.
* IT MUST CORRESPOND TO BUFFER TAG!
* If you're going to play with relation file node (ie change relation
* file) then you have to exclusively lock relation, create new one
* (with new relID), make data transformation, flush from pool buffers
* of both files (old and new), flush old relation from cache,
* update relfilenode in pg_class, flush new relation version from
* cache, open it - now you can use relation with new file.
*
* Why we keep relId here? To re-use file descriptors. On rollback
* WAL uses dummy relId - bad (more blind writes - open/close calls),
* but allowable. Obviously we should have another cache in file manager
* - fd is not relcache deal.
*/
LockRelId relId;
BufferBlindId blind; /* was used to support blind write */ BufferBlindId blind; /* was used to support blind write */
/* /*
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: relcache.h,v 1.21 2000/08/06 04:39:55 tgl Exp $ * $Id: relcache.h,v 1.22 2000/10/23 04:10:24 vadim Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
*/ */
extern Relation RelationIdGetRelation(Oid relationId); extern Relation RelationIdGetRelation(Oid relationId);
extern Relation RelationNameGetRelation(const char *relationName); extern Relation RelationNameGetRelation(const char *relationName);
extern Relation RelationNodeCacheGetRelation(RelFileNode rnode);
/* finds an existing cache entry, but won't make a new one */ /* finds an existing cache entry, but won't make a new one */
extern Relation RelationIdCacheGetRelation(Oid relationId); extern Relation RelationIdCacheGetRelation(Oid relationId);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment