I had to change buffer tag: now RelFileNode is used instead of
LockRelId - ie physical information, not logical. It's required for WAL. Regression tests passed.
This commit is contained in:
parent
8b6b414a5e
commit
2e6358172f
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/buf_init.c,v 1.35 2000/05/31 00:28:26 petere Exp $
|
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/buf_init.c,v 1.36 2000/10/18 05:50:15 vadim Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -67,8 +67,9 @@ long *PrivateRefCount; /* also used in freelist.c */
|
|||||||
bits8 *BufferLocks; /* flag bits showing locks I have set */
|
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; /* and its BlindId too */
|
BufferBlindId *BufferBlindLastDirtied;
|
||||||
bool *BufferDirtiedByMe; /* T if buf has been dirtied in cur xact */
|
LockRelId *BufferRelidLastDirtied;
|
||||||
|
bool *BufferDirtiedByMe; /* T if buf has been dirtied in cur xact */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -251,6 +252,7 @@ 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/buf_table.c,v 1.17 2000/05/19 03:22:28 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/buf_table.c,v 1.18 2000/10/18 05:50:15 vadim Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -125,8 +125,8 @@ BufTableDelete(BufferDesc *buf)
|
|||||||
* sequential searches through the buffer table won't think the
|
* sequential searches through the buffer table won't think the
|
||||||
* buffer is still valid for its old page.
|
* buffer is still valid for its old page.
|
||||||
*/
|
*/
|
||||||
buf->tag.relId.relId = InvalidOid;
|
buf->tag.rnode.relNode = InvalidOid;
|
||||||
buf->tag.relId.dbId = InvalidOid;
|
buf->tag.rnode.tblNode = InvalidOid;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.86 2000/10/16 14:52:09 vadim Exp $
|
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.87 2000/10/18 05:50:15 vadim Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -116,13 +116,10 @@ RelationGetBufferWithBuffer(Relation relation,
|
|||||||
{
|
{
|
||||||
if (!BufferIsLocal(buffer))
|
if (!BufferIsLocal(buffer))
|
||||||
{
|
{
|
||||||
LockRelId *lrelId = &relation->rd_lockInfo.lockRelId;
|
|
||||||
|
|
||||||
bufHdr = &BufferDescriptors[buffer - 1];
|
bufHdr = &BufferDescriptors[buffer - 1];
|
||||||
SpinAcquire(BufMgrLock);
|
SpinAcquire(BufMgrLock);
|
||||||
if (bufHdr->tag.blockNum == blockNumber &&
|
if (bufHdr->tag.blockNum == blockNumber &&
|
||||||
bufHdr->tag.relId.relId == lrelId->relId &&
|
RelFileNodeEquals(bufHdr->tag.rnode, relation->rd_node))
|
||||||
bufHdr->tag.relId.dbId == lrelId->dbId)
|
|
||||||
{
|
{
|
||||||
SpinRelease(BufMgrLock);
|
SpinRelease(BufMgrLock);
|
||||||
return buffer;
|
return buffer;
|
||||||
@ -132,8 +129,8 @@ RelationGetBufferWithBuffer(Relation relation,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
bufHdr = &LocalBufferDescriptors[-buffer - 1];
|
bufHdr = &LocalBufferDescriptors[-buffer - 1];
|
||||||
if (bufHdr->tag.relId.relId == RelationGetRelid(relation) &&
|
if (bufHdr->tag.blockNum == blockNumber &&
|
||||||
bufHdr->tag.blockNum == blockNumber)
|
RelFileNodeEquals(bufHdr->tag.rnode, relation->rd_node))
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -614,9 +611,7 @@ 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);
|
strcpy(buf->blind.dbname, DatabaseName);
|
||||||
strcpy(buf->blind.relname, RelationGetPhysicalRelationName(reln));
|
strcpy(buf->blind.relname, RelationGetPhysicalRelationName(reln));
|
||||||
#ifndef OLD_FILE_NAMING
|
buf->relId = reln->rd_lockInfo.lockRelId;
|
||||||
buf->blind.rnode = reln->rd_node;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
INIT_BUFFERTAG(&(buf->tag), reln, blockNum);
|
INIT_BUFFERTAG(&(buf->tag), reln, blockNum);
|
||||||
if (!BufTableInsert(buf))
|
if (!BufTableInsert(buf))
|
||||||
@ -703,59 +698,6 @@ refcount = %ld, file: %s, line: %d\n",
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* DirtyBufferCopy() -- For a given dbid/relid/blockno, if the buffer is
|
|
||||||
* in the cache and is dirty, mark it clean and copy
|
|
||||||
* it to the requested location. This is a logical
|
|
||||||
* write, and has been installed to support the cache
|
|
||||||
* management code for write-once storage managers.
|
|
||||||
*
|
|
||||||
* DirtyBufferCopy() -- Copy a given dirty buffer to the requested
|
|
||||||
* destination.
|
|
||||||
*
|
|
||||||
* We treat this as a write. If the requested buffer is in the pool
|
|
||||||
* and is dirty, we copy it to the location requested and mark it
|
|
||||||
* clean. This routine supports the Sony jukebox storage manager,
|
|
||||||
* which agrees to take responsibility for the data once we mark
|
|
||||||
* it clean.
|
|
||||||
*
|
|
||||||
* NOTE: used by sony jukebox code in postgres 4.2 - ay 2/95
|
|
||||||
*/
|
|
||||||
#ifdef NOT_USED
|
|
||||||
void
|
|
||||||
DirtyBufferCopy(Oid dbid, Oid relid, BlockNumber blkno, char *dest)
|
|
||||||
{
|
|
||||||
BufferDesc *buf;
|
|
||||||
BufferTag btag;
|
|
||||||
|
|
||||||
btag.relId.relId = relid;
|
|
||||||
btag.relId.dbId = dbid;
|
|
||||||
btag.blockNum = blkno;
|
|
||||||
|
|
||||||
SpinAcquire(BufMgrLock);
|
|
||||||
buf = BufTableLookup(&btag);
|
|
||||||
|
|
||||||
if (buf == (BufferDesc *) NULL
|
|
||||||
|| !(buf->flags & BM_DIRTY)
|
|
||||||
|| !(buf->flags & BM_VALID))
|
|
||||||
{
|
|
||||||
SpinRelease(BufMgrLock);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* hate to do this holding the lock, but release and reacquire is
|
|
||||||
* slower
|
|
||||||
*/
|
|
||||||
memmove(dest, (char *) MAKE_PTR(buf->data), BLCKSZ);
|
|
||||||
|
|
||||||
buf->flags &= ~BM_DIRTY;
|
|
||||||
|
|
||||||
SpinRelease(BufMgrLock);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FlushBuffer -- like WriteBuffer, but force the page to disk.
|
* FlushBuffer -- like WriteBuffer, but force the page to disk.
|
||||||
*
|
*
|
||||||
@ -783,10 +725,10 @@ FlushBuffer(Buffer buffer, bool release)
|
|||||||
|
|
||||||
bufHdr = &BufferDescriptors[buffer - 1];
|
bufHdr = &BufferDescriptors[buffer - 1];
|
||||||
|
|
||||||
bufdb = bufHdr->tag.relId.dbId;
|
bufdb = bufHdr->relId.dbId;
|
||||||
|
|
||||||
Assert(bufdb == MyDatabaseId || bufdb == (Oid) NULL);
|
Assert(bufdb == MyDatabaseId || bufdb == (Oid) NULL);
|
||||||
bufrel = RelationIdCacheGetRelation(bufHdr->tag.relId.relId);
|
bufrel = RelationIdCacheGetRelation(bufHdr->relId.relId);
|
||||||
|
|
||||||
Assert(bufrel != (Relation) NULL);
|
Assert(bufrel != (Relation) NULL);
|
||||||
|
|
||||||
@ -954,8 +896,7 @@ SetBufferDirtiedByMe(Buffer buffer, BufferDesc *bufHdr)
|
|||||||
*/
|
*/
|
||||||
if (BufferDirtiedByMe[buffer - 1])
|
if (BufferDirtiedByMe[buffer - 1])
|
||||||
{
|
{
|
||||||
if (bufHdr->tag.relId.dbId == tagLastDirtied->relId.dbId &&
|
if (RelFileNodeEquals(bufHdr->tag.rnode, tagLastDirtied->rnode) &&
|
||||||
bufHdr->tag.relId.relId == tagLastDirtied->relId.relId &&
|
|
||||||
bufHdr->tag.blockNum == tagLastDirtied->blockNum)
|
bufHdr->tag.blockNum == tagLastDirtied->blockNum)
|
||||||
return; /* Same tag already dirtied, so no work */
|
return; /* Same tag already dirtied, so no work */
|
||||||
|
|
||||||
@ -963,25 +904,17 @@ SetBufferDirtiedByMe(Buffer buffer, BufferDesc *bufHdr)
|
|||||||
SpinRelease(BufMgrLock);
|
SpinRelease(BufMgrLock);
|
||||||
#endif /* OPTIMIZE_SINGLE */
|
#endif /* OPTIMIZE_SINGLE */
|
||||||
|
|
||||||
reln = RelationIdCacheGetRelation(tagLastDirtied->relId.relId);
|
reln = RelationIdCacheGetRelation(BufferRelidLastDirtied[buffer - 1].relId);
|
||||||
|
|
||||||
if (reln == (Relation) NULL)
|
if (reln == (Relation) NULL)
|
||||||
{
|
{
|
||||||
#ifdef OLD_FILE_NAMING
|
|
||||||
status = smgrblindmarkdirty(DEFAULT_SMGR,
|
status = smgrblindmarkdirty(DEFAULT_SMGR,
|
||||||
BufferBlindLastDirtied[buffer - 1].dbname,
|
tagLastDirtied->rnode,
|
||||||
BufferBlindLastDirtied[buffer - 1].relname,
|
|
||||||
tagLastDirtied->relId.dbId,
|
|
||||||
tagLastDirtied->relId.relId,
|
|
||||||
tagLastDirtied->blockNum);
|
tagLastDirtied->blockNum);
|
||||||
#else
|
|
||||||
status = smgrblindmarkdirty(DEFAULT_SMGR,
|
|
||||||
BufferBlindLastDirtied[buffer - 1].rnode,
|
|
||||||
tagLastDirtied->blockNum);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Assert(RelFileNodeEquals(tagLastDirtied->rnode, reln->rd_node));
|
||||||
status = smgrmarkdirty(DEFAULT_SMGR, reln,
|
status = smgrmarkdirty(DEFAULT_SMGR, reln,
|
||||||
tagLastDirtied->blockNum);
|
tagLastDirtied->blockNum);
|
||||||
|
|
||||||
@ -1005,6 +938,7 @@ 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;
|
||||||
}
|
}
|
||||||
@ -1028,10 +962,9 @@ ClearBufferDirtiedByMe(Buffer buffer, BufferDesc *bufHdr)
|
|||||||
* the data we just wrote. This is unlikely, but possible if some
|
* the data we just wrote. This is unlikely, but possible if some
|
||||||
* other backend replaced the buffer contents since we set our flag.
|
* other backend replaced the buffer contents since we set our flag.
|
||||||
*/
|
*/
|
||||||
if (bufHdr->tag.relId.dbId == tagLastDirtied->relId.dbId &&
|
if (RelFileNodeEquals(bufHdr->tag.rnode, tagLastDirtied->rnode) &&
|
||||||
bufHdr->tag.relId.relId == tagLastDirtied->relId.relId &&
|
bufHdr->tag.blockNum == tagLastDirtied->blockNum)
|
||||||
bufHdr->tag.blockNum == tagLastDirtied->blockNum)
|
BufferDirtiedByMe[buffer - 1] = false;
|
||||||
BufferDirtiedByMe[buffer - 1] = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1074,15 +1007,10 @@ BufferSync()
|
|||||||
didwrite = false;
|
didwrite = false;
|
||||||
if ((bufHdr->flags & BM_VALID) && (bufHdr->flags & BM_DIRTY))
|
if ((bufHdr->flags & BM_VALID) && (bufHdr->flags & BM_DIRTY))
|
||||||
{
|
{
|
||||||
Oid bufdb;
|
if (RelFileNodeEquals(bufHdr->tag.rnode, BufferTagLastDirtied[i].rnode) &&
|
||||||
Oid bufrel;
|
|
||||||
|
|
||||||
bufdb = bufHdr->tag.relId.dbId;
|
|
||||||
bufrel = bufHdr->tag.relId.relId;
|
|
||||||
if (bufdb == BufferTagLastDirtied[i].relId.dbId &&
|
|
||||||
bufrel == BufferTagLastDirtied[i].relId.relId &&
|
|
||||||
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
|
||||||
@ -1147,24 +1075,16 @@ BufferSync()
|
|||||||
*/
|
*/
|
||||||
if (reln == (Relation) NULL)
|
if (reln == (Relation) NULL)
|
||||||
{
|
{
|
||||||
#ifdef OLD_FILE_NAMING
|
|
||||||
status = smgrblindwrt(DEFAULT_SMGR,
|
status = smgrblindwrt(DEFAULT_SMGR,
|
||||||
bufHdr->blind.dbname,
|
bufHdr->tag.rnode,
|
||||||
bufHdr->blind.relname,
|
|
||||||
bufdb, bufrel,
|
|
||||||
bufHdr->tag.blockNum,
|
bufHdr->tag.blockNum,
|
||||||
(char *) MAKE_PTR(bufHdr->data),
|
(char *) MAKE_PTR(bufHdr->data),
|
||||||
true); /* must fsync */
|
true); /* must fsync */
|
||||||
#else
|
|
||||||
status = smgrblindwrt(DEFAULT_SMGR,
|
|
||||||
bufHdr->blind.rnode,
|
|
||||||
bufHdr->tag.blockNum,
|
|
||||||
(char *) MAKE_PTR(bufHdr->data),
|
|
||||||
true); /* must fsync */
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
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));
|
||||||
@ -1218,24 +1138,17 @@ BufferSync()
|
|||||||
SpinRelease(BufMgrLock);
|
SpinRelease(BufMgrLock);
|
||||||
#endif /* OPTIMIZE_SINGLE */
|
#endif /* OPTIMIZE_SINGLE */
|
||||||
|
|
||||||
reln = RelationIdCacheGetRelation(BufferTagLastDirtied[i].relId.relId);
|
reln = RelationIdCacheGetRelation(BufferRelidLastDirtied[i].relId);
|
||||||
if (reln == (Relation) NULL)
|
if (reln == (Relation) NULL)
|
||||||
{
|
{
|
||||||
#ifdef OLD_FILE_NAMING
|
|
||||||
status = smgrblindmarkdirty(DEFAULT_SMGR,
|
status = smgrblindmarkdirty(DEFAULT_SMGR,
|
||||||
BufferBlindLastDirtied[i].dbname,
|
BufferTagLastDirtied[i].rnode,
|
||||||
BufferBlindLastDirtied[i].relname,
|
|
||||||
BufferTagLastDirtied[i].relId.dbId,
|
|
||||||
BufferTagLastDirtied[i].relId.relId,
|
|
||||||
BufferTagLastDirtied[i].blockNum);
|
BufferTagLastDirtied[i].blockNum);
|
||||||
#else
|
|
||||||
status = smgrblindmarkdirty(DEFAULT_SMGR,
|
|
||||||
BufferBlindLastDirtied[i].rnode,
|
|
||||||
BufferTagLastDirtied[i].blockNum);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
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);
|
||||||
|
|
||||||
@ -1492,46 +1405,6 @@ BufferGetBlockNumber(Buffer buffer)
|
|||||||
return BufferDescriptors[buffer - 1].tag.blockNum;
|
return BufferDescriptors[buffer - 1].tag.blockNum;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NOT_USED
|
|
||||||
/*
|
|
||||||
* BufferGetRelation
|
|
||||||
* Returns the relation desciptor associated with a buffer.
|
|
||||||
*
|
|
||||||
* Note:
|
|
||||||
* Assumes buffer is valid.
|
|
||||||
*/
|
|
||||||
Relation
|
|
||||||
BufferGetRelation(Buffer buffer)
|
|
||||||
{
|
|
||||||
Relation relation;
|
|
||||||
Oid relid;
|
|
||||||
|
|
||||||
Assert(BufferIsValid(buffer));
|
|
||||||
Assert(!BufferIsLocal(buffer)); /* not supported for local buffers */
|
|
||||||
|
|
||||||
/* XXX should be a critical section */
|
|
||||||
relid = BufferDescriptors[buffer - 1].tag.relId.relId;
|
|
||||||
relation = RelationIdGetRelation(relid);
|
|
||||||
Assert(relation);
|
|
||||||
|
|
||||||
/* drop relcache refcnt incremented by RelationIdGetRelation */
|
|
||||||
RelationDecrementReferenceCount(relation);
|
|
||||||
|
|
||||||
if (RelationHasReferenceCountZero(relation))
|
|
||||||
{
|
|
||||||
|
|
||||||
/*
|
|
||||||
* XXX why??
|
|
||||||
*/
|
|
||||||
|
|
||||||
RelationIncrementReferenceCount(relation);
|
|
||||||
}
|
|
||||||
|
|
||||||
return relation;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* BufferReplace
|
* BufferReplace
|
||||||
*
|
*
|
||||||
@ -1554,8 +1427,8 @@ BufferReplace(BufferDesc *bufHdr)
|
|||||||
* 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->tag.relId.dbId;
|
bufdb = bufHdr->relId.dbId;
|
||||||
bufrel = bufHdr->tag.relId.relId;
|
bufrel = bufHdr->relId.relId;
|
||||||
|
|
||||||
if (bufdb == MyDatabaseId || bufdb == (Oid) NULL)
|
if (bufdb == MyDatabaseId || bufdb == (Oid) NULL)
|
||||||
reln = RelationIdCacheGetRelation(bufrel);
|
reln = RelationIdCacheGetRelation(bufrel);
|
||||||
@ -1576,23 +1449,16 @@ 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));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifdef OLD_FILE_NAMING
|
status = smgrblindwrt(DEFAULT_SMGR, bufHdr->tag.rnode,
|
||||||
status = smgrblindwrt(DEFAULT_SMGR, bufHdr->blind.dbname,
|
|
||||||
bufHdr->blind.relname, bufdb, bufrel,
|
|
||||||
bufHdr->tag.blockNum,
|
bufHdr->tag.blockNum,
|
||||||
(char *) MAKE_PTR(bufHdr->data),
|
(char *) MAKE_PTR(bufHdr->data),
|
||||||
false); /* no fsync */
|
false); /* no fsync */
|
||||||
#else
|
|
||||||
status = smgrblindwrt(DEFAULT_SMGR, bufHdr->blind.rnode,
|
|
||||||
bufHdr->tag.blockNum,
|
|
||||||
(char *) MAKE_PTR(bufHdr->data),
|
|
||||||
false); /* no fsync */
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LockBuffer(BufferDescriptorGetBuffer(bufHdr), BUFFER_LOCK_UNLOCK);
|
LockBuffer(BufferDescriptorGetBuffer(bufHdr), BUFFER_LOCK_UNLOCK);
|
||||||
@ -1654,18 +1520,22 @@ ReleaseRelationBuffers(Relation rel)
|
|||||||
{
|
{
|
||||||
Oid relid = RelationGetRelid(rel);
|
Oid relid = RelationGetRelid(rel);
|
||||||
int i;
|
int i;
|
||||||
BufferDesc *buf;
|
BufferDesc *bufHdr;
|
||||||
|
|
||||||
if (rel->rd_myxactonly)
|
if (rel->rd_myxactonly)
|
||||||
{
|
{
|
||||||
for (i = 0; i < NLocBuffer; i++)
|
for (i = 0; i < NLocBuffer; i++)
|
||||||
{
|
{
|
||||||
buf = &LocalBufferDescriptors[i];
|
bufHdr = &LocalBufferDescriptors[i];
|
||||||
if (buf->tag.relId.relId == relid)
|
if (RelFileNodeEquals(bufHdr->tag.rnode, rel->rd_node))
|
||||||
{
|
{
|
||||||
buf->flags &= ~(BM_DIRTY | BM_JUST_DIRTIED);
|
bufHdr->flags &= ~(BM_DIRTY | BM_JUST_DIRTIED);
|
||||||
LocalRefCount[i] = 0;
|
LocalRefCount[i] = 0;
|
||||||
buf->tag.relId.relId = InvalidOid;
|
bufHdr->tag.rnode.relNode = InvalidOid;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Assert(bufHdr->relId.relId != relid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -1674,11 +1544,9 @@ ReleaseRelationBuffers(Relation rel)
|
|||||||
SpinAcquire(BufMgrLock);
|
SpinAcquire(BufMgrLock);
|
||||||
for (i = 1; i <= NBuffers; i++)
|
for (i = 1; i <= NBuffers; i++)
|
||||||
{
|
{
|
||||||
buf = &BufferDescriptors[i - 1];
|
bufHdr = &BufferDescriptors[i - 1];
|
||||||
recheck:
|
recheck:
|
||||||
if (buf->tag.relId.relId == relid &&
|
if (RelFileNodeEquals(bufHdr->tag.rnode, rel->rd_node))
|
||||||
(buf->tag.relId.dbId == MyDatabaseId ||
|
|
||||||
buf->tag.relId.dbId == (Oid) NULL))
|
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1686,9 +1554,9 @@ recheck:
|
|||||||
* don't want to delete the relation out from under someone
|
* don't want to delete the relation out from under someone
|
||||||
* who's just trying to flush the buffer!
|
* who's just trying to flush the buffer!
|
||||||
*/
|
*/
|
||||||
if (buf->flags & BM_IO_IN_PROGRESS)
|
if (bufHdr->flags & BM_IO_IN_PROGRESS)
|
||||||
{
|
{
|
||||||
WaitIO(buf, BufMgrLock);
|
WaitIO(bufHdr, BufMgrLock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* By now, the buffer very possibly belongs to some other
|
* By now, the buffer very possibly belongs to some other
|
||||||
@ -1697,8 +1565,8 @@ recheck:
|
|||||||
goto recheck;
|
goto recheck;
|
||||||
}
|
}
|
||||||
/* Now we can do what we came for */
|
/* Now we can do what we came for */
|
||||||
buf->flags &= ~(BM_DIRTY | BM_JUST_DIRTIED);
|
bufHdr->flags &= ~(BM_DIRTY | BM_JUST_DIRTIED);
|
||||||
ClearBufferDirtiedByMe(i, buf);
|
BufferDirtiedByMe[i - 1] = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Release any refcount we may have.
|
* Release any refcount we may have.
|
||||||
@ -1707,11 +1575,11 @@ recheck:
|
|||||||
* probably wrong. I added the Assert to find out --- tgl
|
* probably wrong. I added the Assert to find out --- tgl
|
||||||
* 11/99.
|
* 11/99.
|
||||||
*/
|
*/
|
||||||
if (!(buf->flags & BM_FREE))
|
if (!(bufHdr->flags & BM_FREE))
|
||||||
{
|
{
|
||||||
/* Assert checks that buffer will actually get freed! */
|
/* Assert checks that buffer will actually get freed! */
|
||||||
Assert(PrivateRefCount[i - 1] == 1 &&
|
Assert(PrivateRefCount[i - 1] == 1 &&
|
||||||
buf->refcount == 1);
|
bufHdr->refcount == 1);
|
||||||
/* ReleaseBuffer expects we do not hold the lock at entry */
|
/* ReleaseBuffer expects we do not hold the lock at entry */
|
||||||
SpinRelease(BufMgrLock);
|
SpinRelease(BufMgrLock);
|
||||||
ReleaseBuffer(i);
|
ReleaseBuffer(i);
|
||||||
@ -1720,9 +1588,19 @@ recheck:
|
|||||||
/*
|
/*
|
||||||
* And mark the buffer as no longer occupied by this rel.
|
* And mark the buffer as no longer occupied by this rel.
|
||||||
*/
|
*/
|
||||||
BufTableDelete(buf);
|
BufTableDelete(bufHdr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Assert(bufHdr->relId.relId != relid ||
|
||||||
|
(bufHdr->relId.dbId != MyDatabaseId &&
|
||||||
|
bufHdr->relId.dbId != InvalidOid));
|
||||||
|
if (RelFileNodeEquals(rel->rd_node,
|
||||||
|
BufferTagLastDirtied[i - 1].rnode))
|
||||||
|
BufferDirtiedByMe[i - 1] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SpinRelease(BufMgrLock);
|
SpinRelease(BufMgrLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1741,14 +1619,19 @@ void
|
|||||||
DropBuffers(Oid dbid)
|
DropBuffers(Oid dbid)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
BufferDesc *buf;
|
BufferDesc *bufHdr;
|
||||||
|
|
||||||
SpinAcquire(BufMgrLock);
|
SpinAcquire(BufMgrLock);
|
||||||
for (i = 1; i <= NBuffers; i++)
|
for (i = 1; i <= NBuffers; i++)
|
||||||
{
|
{
|
||||||
buf = &BufferDescriptors[i - 1];
|
bufHdr = &BufferDescriptors[i - 1];
|
||||||
recheck:
|
recheck:
|
||||||
if (buf->tag.relId.dbId == dbid)
|
/*
|
||||||
|
* We know that currently database OID is tblNode but
|
||||||
|
* this probably will be changed in future and this
|
||||||
|
* func will be used to drop tablespace buffers.
|
||||||
|
*/
|
||||||
|
if (bufHdr->tag.rnode.tblNode == dbid)
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1756,9 +1639,9 @@ recheck:
|
|||||||
* don't want to delete the database out from under someone
|
* don't want to delete the database out from under someone
|
||||||
* who's just trying to flush the buffer!
|
* who's just trying to flush the buffer!
|
||||||
*/
|
*/
|
||||||
if (buf->flags & BM_IO_IN_PROGRESS)
|
if (bufHdr->flags & BM_IO_IN_PROGRESS)
|
||||||
{
|
{
|
||||||
WaitIO(buf, BufMgrLock);
|
WaitIO(bufHdr, BufMgrLock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* By now, the buffer very possibly belongs to some other
|
* By now, the buffer very possibly belongs to some other
|
||||||
@ -1767,18 +1650,24 @@ recheck:
|
|||||||
goto recheck;
|
goto recheck;
|
||||||
}
|
}
|
||||||
/* Now we can do what we came for */
|
/* Now we can do what we came for */
|
||||||
buf->flags &= ~(BM_DIRTY | BM_JUST_DIRTIED);
|
bufHdr->flags &= ~(BM_DIRTY | BM_JUST_DIRTIED);
|
||||||
ClearBufferDirtiedByMe(i, buf);
|
BufferDirtiedByMe[i - 1] = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The thing should be free, if caller has checked that no
|
* The thing should be free, if caller has checked that no
|
||||||
* backends are running in that database.
|
* backends are running in that database.
|
||||||
*/
|
*/
|
||||||
Assert(buf->flags & BM_FREE);
|
Assert(bufHdr->flags & BM_FREE);
|
||||||
/*
|
/*
|
||||||
* And mark the buffer as no longer occupied by this page.
|
* And mark the buffer as no longer occupied by this page.
|
||||||
*/
|
*/
|
||||||
BufTableDelete(buf);
|
BufTableDelete(bufHdr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Assert(bufHdr->relId.dbId != dbid);
|
||||||
|
if (BufferTagLastDirtied[i - 1].rnode.tblNode == dbid)
|
||||||
|
BufferDirtiedByMe[i - 1] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SpinRelease(BufMgrLock);
|
SpinRelease(BufMgrLock);
|
||||||
@ -1917,22 +1806,22 @@ FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock)
|
|||||||
{
|
{
|
||||||
Oid relid = RelationGetRelid(rel);
|
Oid relid = RelationGetRelid(rel);
|
||||||
int i;
|
int i;
|
||||||
BufferDesc *buf;
|
BufferDesc *bufHdr;
|
||||||
|
|
||||||
if (rel->rd_myxactonly)
|
if (rel->rd_myxactonly)
|
||||||
{
|
{
|
||||||
for (i = 0; i < NLocBuffer; i++)
|
for (i = 0; i < NLocBuffer; i++)
|
||||||
{
|
{
|
||||||
buf = &LocalBufferDescriptors[i];
|
bufHdr = &LocalBufferDescriptors[i];
|
||||||
if (buf->tag.relId.relId == relid)
|
if (RelFileNodeEquals(bufHdr->tag.rnode, rel->rd_node))
|
||||||
{
|
{
|
||||||
if (buf->flags & BM_DIRTY)
|
if (bufHdr->flags & BM_DIRTY)
|
||||||
{
|
{
|
||||||
if (FlushBuffer(-i - 1, false) != STATUS_OK)
|
if (FlushBuffer(-i - 1, false) != STATUS_OK)
|
||||||
{
|
{
|
||||||
elog(NOTICE, "FlushRelationBuffers(%s (local), %u): block %u is dirty, could not flush it",
|
elog(NOTICE, "FlushRelationBuffers(%s (local), %u): block %u is dirty, could not flush it",
|
||||||
RelationGetRelationName(rel), firstDelBlock,
|
RelationGetRelationName(rel), firstDelBlock,
|
||||||
buf->tag.blockNum);
|
bufHdr->tag.blockNum);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1940,14 +1829,18 @@ FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock)
|
|||||||
{
|
{
|
||||||
elog(NOTICE, "FlushRelationBuffers(%s (local), %u): block %u is referenced (%ld)",
|
elog(NOTICE, "FlushRelationBuffers(%s (local), %u): block %u is referenced (%ld)",
|
||||||
RelationGetRelationName(rel), firstDelBlock,
|
RelationGetRelationName(rel), firstDelBlock,
|
||||||
buf->tag.blockNum, LocalRefCount[i]);
|
bufHdr->tag.blockNum, LocalRefCount[i]);
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
if (buf->tag.blockNum >= firstDelBlock)
|
if (bufHdr->tag.blockNum >= firstDelBlock)
|
||||||
{
|
{
|
||||||
buf->tag.relId.relId = InvalidOid;
|
bufHdr->tag.rnode.relNode = InvalidOid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Assert(bufHdr->relId.relId != relid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1955,22 +1848,20 @@ FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock)
|
|||||||
SpinAcquire(BufMgrLock);
|
SpinAcquire(BufMgrLock);
|
||||||
for (i = 0; i < NBuffers; i++)
|
for (i = 0; i < NBuffers; i++)
|
||||||
{
|
{
|
||||||
buf = &BufferDescriptors[i];
|
bufHdr = &BufferDescriptors[i];
|
||||||
recheck:
|
recheck:
|
||||||
if (buf->tag.relId.relId == relid &&
|
if (RelFileNodeEquals(bufHdr->tag.rnode, rel->rd_node))
|
||||||
(buf->tag.relId.dbId == MyDatabaseId ||
|
|
||||||
buf->tag.relId.dbId == (Oid) NULL))
|
|
||||||
{
|
{
|
||||||
if (buf->flags & BM_DIRTY)
|
if (bufHdr->flags & BM_DIRTY)
|
||||||
{
|
{
|
||||||
PinBuffer(buf);
|
PinBuffer(bufHdr);
|
||||||
SpinRelease(BufMgrLock);
|
SpinRelease(BufMgrLock);
|
||||||
if (FlushBuffer(i + 1, true) != STATUS_OK)
|
if (FlushBuffer(i + 1, true) != STATUS_OK)
|
||||||
{
|
{
|
||||||
elog(NOTICE, "FlushRelationBuffers(%s, %u): block %u is dirty (private %ld, global %d), could not flush it",
|
elog(NOTICE, "FlushRelationBuffers(%s, %u): block %u is dirty (private %ld, global %d), could not flush it",
|
||||||
RelationGetRelationName(rel), firstDelBlock,
|
RelationGetRelationName(rel), firstDelBlock,
|
||||||
buf->tag.blockNum,
|
bufHdr->tag.blockNum,
|
||||||
PrivateRefCount[i], buf->refcount);
|
PrivateRefCount[i], bufHdr->refcount);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
SpinAcquire(BufMgrLock);
|
SpinAcquire(BufMgrLock);
|
||||||
@ -1981,20 +1872,26 @@ recheck:
|
|||||||
*/
|
*/
|
||||||
goto recheck;
|
goto recheck;
|
||||||
}
|
}
|
||||||
if (!(buf->flags & BM_FREE))
|
if (!(bufHdr->flags & BM_FREE))
|
||||||
{
|
{
|
||||||
SpinRelease(BufMgrLock);
|
SpinRelease(BufMgrLock);
|
||||||
elog(NOTICE, "FlushRelationBuffers(%s, %u): block %u is referenced (private %ld, global %d)",
|
elog(NOTICE, "FlushRelationBuffers(%s, %u): block %u is referenced (private %ld, global %d)",
|
||||||
RelationGetRelationName(rel), firstDelBlock,
|
RelationGetRelationName(rel), firstDelBlock,
|
||||||
buf->tag.blockNum,
|
bufHdr->tag.blockNum,
|
||||||
PrivateRefCount[i], buf->refcount);
|
PrivateRefCount[i], bufHdr->refcount);
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
if (buf->tag.blockNum >= firstDelBlock)
|
if (bufHdr->tag.blockNum >= firstDelBlock)
|
||||||
{
|
{
|
||||||
BufTableDelete(buf);
|
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.30 2000/04/12 17:15:34 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/localbuf.c,v 1.31 2000/10/18 05:50:15 vadim Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -60,7 +60,8 @@ LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr)
|
|||||||
/* 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.relId.relId == RelationGetRelid(reln) &&
|
if (LocalBufferDescriptors[i].tag.rnode.relNode ==
|
||||||
|
reln->rd_node.relNode &&
|
||||||
LocalBufferDescriptors[i].tag.blockNum == blockNum)
|
LocalBufferDescriptors[i].tag.blockNum == blockNum)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -102,7 +103,7 @@ LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr)
|
|||||||
*/
|
*/
|
||||||
if (bufHdr->flags & BM_DIRTY)
|
if (bufHdr->flags & BM_DIRTY)
|
||||||
{
|
{
|
||||||
Relation bufrel = RelationIdCacheGetRelation(bufHdr->tag.relId.relId);
|
Relation bufrel = RelationIdCacheGetRelation(bufHdr->relId.relId);
|
||||||
|
|
||||||
Assert(bufrel != NULL);
|
Assert(bufrel != NULL);
|
||||||
|
|
||||||
@ -120,9 +121,13 @@ LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* it's all ours now.
|
* it's all ours now.
|
||||||
|
*
|
||||||
|
* We need not in tblNode currently but will in future I think,
|
||||||
|
* when we'll give up rel->rd_fd to fmgr cache.
|
||||||
*/
|
*/
|
||||||
bufHdr->tag.relId.relId = RelationGetRelid(reln);
|
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;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -187,7 +192,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->tag.relId.relId);
|
bufrel = RelationIdCacheGetRelation(bufHdr->relId.relId);
|
||||||
|
|
||||||
Assert(bufrel != NULL);
|
Assert(bufrel != NULL);
|
||||||
smgrflush(DEFAULT_SMGR, bufrel, bufHdr->tag.blockNum,
|
smgrflush(DEFAULT_SMGR, bufrel, bufHdr->tag.blockNum,
|
||||||
@ -263,7 +268,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->tag.relId.relId);
|
bufrel = RelationIdCacheGetRelation(buf->relId.relId);
|
||||||
|
|
||||||
Assert(bufrel != NULL);
|
Assert(bufrel != NULL);
|
||||||
|
|
||||||
@ -274,7 +279,7 @@ LocalBufferSync(void)
|
|||||||
/* drop relcache refcount from RelationIdCacheGetRelation */
|
/* drop relcache refcount from RelationIdCacheGetRelation */
|
||||||
RelationDecrementReferenceCount(bufrel);
|
RelationDecrementReferenceCount(bufrel);
|
||||||
|
|
||||||
buf->tag.relId.relId = InvalidOid;
|
buf->relId.relId = InvalidOid;
|
||||||
buf->flags &= ~BM_DIRTY;
|
buf->flags &= ~BM_DIRTY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -292,7 +297,7 @@ ResetLocalBufferPool(void)
|
|||||||
{
|
{
|
||||||
BufferDesc *buf = &LocalBufferDescriptors[i];
|
BufferDesc *buf = &LocalBufferDescriptors[i];
|
||||||
|
|
||||||
buf->tag.relId.relId = InvalidOid;
|
buf->tag.rnode.relNode = InvalidOid;
|
||||||
buf->flags &= ~BM_DIRTY;
|
buf->flags &= ~BM_DIRTY;
|
||||||
buf->buf_id = -i - 2;
|
buf->buf_id = -i - 2;
|
||||||
}
|
}
|
||||||
|
@ -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.38 2000/10/16 14:52:28 vadim Exp $
|
* $Id: buf_internals.h,v 1.39 2000/10/18 05:50:16 vadim Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -44,27 +44,27 @@ typedef long **BufferBlock;
|
|||||||
|
|
||||||
typedef struct buftag
|
typedef struct buftag
|
||||||
{
|
{
|
||||||
LockRelId relId;
|
RelFileNode rnode;
|
||||||
BlockNumber blockNum; /* blknum relative to begin of reln */
|
BlockNumber blockNum; /* blknum relative to begin of reln */
|
||||||
} BufferTag;
|
} BufferTag;
|
||||||
|
|
||||||
#define CLEAR_BUFFERTAG(a) \
|
#define CLEAR_BUFFERTAG(a) \
|
||||||
( \
|
( \
|
||||||
(a)->relId.dbId = InvalidOid, \
|
(a)->rnode.tblNode = InvalidOid, \
|
||||||
(a)->relId.relId = 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)->blockNum = (xx_blockNum), \
|
||||||
(a)->relId = (xx_reln)->rd_lockInfo.lockRelId \
|
(a)->rnode = (xx_reln)->rd_node \
|
||||||
)
|
)
|
||||||
|
|
||||||
#ifdef OLD_FILE_NAMING
|
/*
|
||||||
/* If we have to write a buffer "blind" (without a relcache entry),
|
* We don't need in this data any more but it allows more user
|
||||||
* the BufferTag is not enough information. BufferBlindId carries the
|
* friendly error messages. Feel free to get rid of it
|
||||||
* additional information needed.
|
* (and change a lot of places -:))
|
||||||
*/
|
*/
|
||||||
typedef struct bufblindid
|
typedef struct bufblindid
|
||||||
{
|
{
|
||||||
@ -72,17 +72,6 @@ typedef struct bufblindid
|
|||||||
char relname[NAMEDATALEN]; /* name of reln */
|
char relname[NAMEDATALEN]; /* name of reln */
|
||||||
} BufferBlindId;
|
} BufferBlindId;
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
typedef struct bufblindid
|
|
||||||
{
|
|
||||||
char dbname[NAMEDATALEN]; /* name of db in which buf belongs */
|
|
||||||
char relname[NAMEDATALEN]; /* name of reln */
|
|
||||||
RelFileNode rnode;
|
|
||||||
} BufferBlindId;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define BAD_BUFFER_ID(bid) ((bid) < 1 || (bid) > NBuffers)
|
#define BAD_BUFFER_ID(bid) ((bid) < 1 || (bid) > NBuffers)
|
||||||
#define INVALID_DESCRIPTOR (-3)
|
#define INVALID_DESCRIPTOR (-3)
|
||||||
|
|
||||||
@ -120,7 +109,22 @@ 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 */
|
||||||
|
|
||||||
BufferBlindId blind; /* extra info to support blind write */
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
LockRelId relId;
|
||||||
|
BufferBlindId blind; /* was used to support blind write */
|
||||||
} BufferDesc;
|
} BufferDesc;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -187,6 +191,7 @@ extern long *PrivateRefCount;
|
|||||||
extern bits8 *BufferLocks;
|
extern bits8 *BufferLocks;
|
||||||
extern BufferTag *BufferTagLastDirtied;
|
extern BufferTag *BufferTagLastDirtied;
|
||||||
extern BufferBlindId *BufferBlindLastDirtied;
|
extern BufferBlindId *BufferBlindLastDirtied;
|
||||||
|
extern LockRelId *BufferRelidLastDirtied;
|
||||||
extern bool *BufferDirtiedByMe;
|
extern bool *BufferDirtiedByMe;
|
||||||
extern SPINLOCK BufMgrLock;
|
extern SPINLOCK BufMgrLock;
|
||||||
|
|
||||||
|
@ -15,4 +15,8 @@ typedef struct RelFileNode
|
|||||||
Oid relNode; /* relation */
|
Oid relNode; /* relation */
|
||||||
} RelFileNode;
|
} RelFileNode;
|
||||||
|
|
||||||
|
#define RelFileNodeEquals(node1, node2) \
|
||||||
|
((node1).relNode == (node2).relNode && \
|
||||||
|
(node2).tblNode == (node2).tblNode)
|
||||||
|
|
||||||
#endif /* RELFILENODE_H */
|
#endif /* RELFILENODE_H */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user