mirror of
https://github.com/postgres/postgres.git
synced 2025-04-27 22:56:53 +03:00
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.
This commit is contained in:
parent
c82c9559a7
commit
4b65a2840b
@ -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()
|
|||||||
*/
|
*/
|
||||||
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()
|
|||||||
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()
|
|||||||
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 @@
|
|||||||
* 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:;
|
|||||||
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()
|
|||||||
{
|
{
|
||||||
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 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* 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 */
|
|||||||
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)
|
|||||||
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 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* 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 @@
|
|||||||
#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,
|
|||||||
/* 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
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
*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()
|
|||||||
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()
|
|||||||
}
|
}
|
||||||
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()
|
|||||||
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()
|
|||||||
}
|
}
|
||||||
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
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
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:
|
|||||||
*/
|
*/
|
||||||
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:
|
|||||||
* 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:
|
|||||||
*/
|
*/
|
||||||
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()
|
|||||||
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)
|
|||||||
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:
|
|||||||
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 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* 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)
|
|||||||
*/
|
*/
|
||||||
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)
|
|||||||
*/
|
*/
|
||||||
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)
|
|||||||
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)
|
|||||||
#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)
|
|||||||
/* 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
100
src/backend/utils/cache/relcache.c
vendored
100
src/backend/utils/cache/relcache.c
vendored
@ -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};
|
|||||||
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
|
|||||||
} 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
|
|||||||
#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 { \
|
|||||||
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 { \
|
|||||||
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 { \
|
|||||||
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 { \
|
|||||||
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,
|
|||||||
*/
|
*/
|
||||||
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,
|
|||||||
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)
|
|||||||
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)
|
|||||||
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 @@
|
|||||||
* 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
|
|||||||
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 @@
|
|||||||
* 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 @@
|
|||||||
*/
|
*/
|
||||||
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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user