Commit 2e635817 authored by Vadim B. Mikheev's avatar Vadim B. Mikheev

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.
parent 8b6b414a
...@@ -8,7 +8,7 @@ ...@@ -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 */ ...@@ -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) ...@@ -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 @@ ...@@ -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) ...@@ -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 @@ ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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", ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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,
BufferBlindLastDirtied[buffer - 1].dbname,
BufferBlindLastDirtied[buffer - 1].relname,
tagLastDirtied->relId.dbId,
tagLastDirtied->relId.relId,
tagLastDirtied->blockNum);
#else
status = smgrblindmarkdirty(DEFAULT_SMGR, status = smgrblindmarkdirty(DEFAULT_SMGR,
BufferBlindLastDirtied[buffer - 1].rnode, tagLastDirtied->rnode,
tagLastDirtied->blockNum); 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) ...@@ -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) ...@@ -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() ...@@ -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() ...@@ -1147,24 +1075,16 @@ BufferSync()
*/ */
if (reln == (Relation) NULL) if (reln == (Relation) NULL)
{ {
#ifdef OLD_FILE_NAMING
status = smgrblindwrt(DEFAULT_SMGR,
bufHdr->blind.dbname,
bufHdr->blind.relname,
bufdb, bufrel,
bufHdr->tag.blockNum,
(char *) MAKE_PTR(bufHdr->data),
true); /* must fsync */
#else
status = smgrblindwrt(DEFAULT_SMGR, status = smgrblindwrt(DEFAULT_SMGR,
bufHdr->blind.rnode, bufHdr->tag.rnode,
bufHdr->tag.blockNum, bufHdr->tag.blockNum,
(char *) MAKE_PTR(bufHdr->data), (char *) MAKE_PTR(bufHdr->data),
true); /* must fsync */ 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() ...@@ -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,
BufferBlindLastDirtied[i].dbname,
BufferBlindLastDirtied[i].relname,
BufferTagLastDirtied[i].relId.dbId,
BufferTagLastDirtied[i].relId.relId,
BufferTagLastDirtied[i].blockNum);
#else
status = smgrblindmarkdirty(DEFAULT_SMGR, status = smgrblindmarkdirty(DEFAULT_SMGR,
BufferBlindLastDirtied[i].rnode, BufferTagLastDirtied[i].rnode,
BufferTagLastDirtied[i].blockNum); 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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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 ...@@ -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: ...@@ -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: ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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: ...@@ -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 @@ ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 @@ ...@@ -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; ...@@ -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 ...@@ -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 ...@@ -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; ...@@ -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 ...@@ -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 */
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