]> granicus.if.org Git - postgresql/commitdiff
I had to change buffer tag: now RelFileNode is used instead of
authorVadim B. Mikheev <vadim4o@yahoo.com>
Wed, 18 Oct 2000 05:50:16 +0000 (05:50 +0000)
committerVadim B. Mikheev <vadim4o@yahoo.com>
Wed, 18 Oct 2000 05:50:16 +0000 (05:50 +0000)
LockRelId - ie physical information, not logical. It's required
for WAL. Regression tests passed.

src/backend/storage/buffer/buf_init.c
src/backend/storage/buffer/buf_table.c
src/backend/storage/buffer/bufmgr.c
src/backend/storage/buffer/localbuf.c
src/include/storage/buf_internals.h
src/include/storage/relfilenode.h

index 5023b4042617f0205ce2ec924248e9f6dc6147b9..13aca31a3e4f481e09b1bb5de20618e278cfa3e0 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * 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 */
 BufferTag  *BufferTagLastDirtied;              /* tag buffer had when last
                                                                                 * dirtied by me */
-BufferBlindId *BufferBlindLastDirtied; /* and its BlindId too */
-bool      *BufferDirtiedByMe;  /* T if buf has been dirtied in cur xact */
+BufferBlindId  *BufferBlindLastDirtied;
+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));
        BufferTagLastDirtied = (BufferTag *) calloc(NBuffers, sizeof(BufferTag));
        BufferBlindLastDirtied = (BufferBlindId *) calloc(NBuffers, sizeof(BufferBlindId));
+       BufferRelidLastDirtied = (LockRelId *) calloc(NBuffers, sizeof(LockRelId));
        BufferDirtiedByMe = (bool *) calloc(NBuffers, sizeof(bool));
 }
 
index 8139337e3522f48574b8d83468dd26cae3d1f40f..d48d321e8f8a2c9c5099d1468faf6cf18a510b98 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * 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
         * buffer is still valid for its old page.
         */
-       buf->tag.relId.relId = InvalidOid;
-       buf->tag.relId.dbId = InvalidOid;
+       buf->tag.rnode.relNode = InvalidOid;
+       buf->tag.rnode.tblNode = InvalidOid;
 
        return TRUE;
 }
index d5badefd084ebfb1be8a7ca458cc3dbdee4a4f8c..41ee78e547c018e263cde96dcf17dd3b4304e23f 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * 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))
                {
-                       LockRelId  *lrelId = &relation->rd_lockInfo.lockRelId;
-
                        bufHdr = &BufferDescriptors[buffer - 1];
                        SpinAcquire(BufMgrLock);
                        if (bufHdr->tag.blockNum == blockNumber &&
-                               bufHdr->tag.relId.relId == lrelId->relId &&
-                               bufHdr->tag.relId.dbId == lrelId->dbId)
+                               RelFileNodeEquals(bufHdr->tag.rnode, relation->rd_node))
                        {
                                SpinRelease(BufMgrLock);
                                return buffer;
@@ -132,8 +129,8 @@ RelationGetBufferWithBuffer(Relation relation,
                else
                {
                        bufHdr = &LocalBufferDescriptors[-buffer - 1];
-                       if (bufHdr->tag.relId.relId == RelationGetRelid(relation) &&
-                               bufHdr->tag.blockNum == blockNumber)
+                       if (bufHdr->tag.blockNum == blockNumber &&
+                               RelFileNodeEquals(bufHdr->tag.rnode, relation->rd_node))
                                return buffer;
                }
        }
@@ -614,9 +611,7 @@ BufferAlloc(Relation reln,
        /* record the database name and relation name for this buffer */
        strcpy(buf->blind.dbname, DatabaseName);
        strcpy(buf->blind.relname, RelationGetPhysicalRelationName(reln));
-#ifndef OLD_FILE_NAMING
-       buf->blind.rnode = reln->rd_node;
-#endif
+       buf->relId = reln->rd_lockInfo.lockRelId;
 
        INIT_BUFFERTAG(&(buf->tag), reln, blockNum);
        if (!BufTableInsert(buf))
@@ -703,59 +698,6 @@ refcount = %ld, file: %s, line: %d\n",
 
 #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.
  *
@@ -783,10 +725,10 @@ FlushBuffer(Buffer buffer, bool release)
 
        bufHdr = &BufferDescriptors[buffer - 1];
 
-       bufdb = bufHdr->tag.relId.dbId;
+       bufdb = bufHdr->relId.dbId;
 
        Assert(bufdb == MyDatabaseId || bufdb == (Oid) NULL);
-       bufrel = RelationIdCacheGetRelation(bufHdr->tag.relId.relId);
+       bufrel = RelationIdCacheGetRelation(bufHdr->relId.relId);
 
        Assert(bufrel != (Relation) NULL);
 
@@ -954,8 +896,7 @@ SetBufferDirtiedByMe(Buffer buffer, BufferDesc *bufHdr)
         */
        if (BufferDirtiedByMe[buffer - 1])
        {
-               if (bufHdr->tag.relId.dbId == tagLastDirtied->relId.dbId &&
-                       bufHdr->tag.relId.relId == tagLastDirtied->relId.relId &&
+               if (RelFileNodeEquals(bufHdr->tag.rnode, tagLastDirtied->rnode) &&
                        bufHdr->tag.blockNum == tagLastDirtied->blockNum)
                        return;                         /* Same tag already dirtied, so no work */
 
@@ -963,25 +904,17 @@ SetBufferDirtiedByMe(Buffer buffer, BufferDesc *bufHdr)
                SpinRelease(BufMgrLock);
 #endif  /* OPTIMIZE_SINGLE */
 
-               reln = RelationIdCacheGetRelation(tagLastDirtied->relId.relId);
+               reln = RelationIdCacheGetRelation(BufferRelidLastDirtied[buffer - 1].relId);
 
                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,
-                                                       BufferBlindLastDirtied[buffer - 1].rnode,
+                                                       tagLastDirtied->rnode,
                                                        tagLastDirtied->blockNum);
-#endif
                }
                else
                {
+                       Assert(RelFileNodeEquals(tagLastDirtied->rnode, reln->rd_node));
                        status = smgrmarkdirty(DEFAULT_SMGR, reln,
                                                                   tagLastDirtied->blockNum);
 
@@ -1005,6 +938,7 @@ SetBufferDirtiedByMe(Buffer buffer, BufferDesc *bufHdr)
        }
 
        *tagLastDirtied = bufHdr->tag;
+       BufferRelidLastDirtied[buffer - 1] = bufHdr->relId;
        BufferBlindLastDirtied[buffer - 1] = bufHdr->blind;
        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
         * other backend replaced the buffer contents since we set our flag.
         */
-               if (bufHdr->tag.relId.dbId == tagLastDirtied->relId.dbId &&
-                               bufHdr->tag.relId.relId == tagLastDirtied->relId.relId &&
-                               bufHdr->tag.blockNum == tagLastDirtied->blockNum)
-                       BufferDirtiedByMe[buffer - 1] = false;
+       if (RelFileNodeEquals(bufHdr->tag.rnode, tagLastDirtied->rnode) &&
+                       bufHdr->tag.blockNum == tagLastDirtied->blockNum)
+               BufferDirtiedByMe[buffer - 1] = false;
 }
 
 /*
@@ -1074,15 +1007,10 @@ BufferSync()
                didwrite = false;
                if ((bufHdr->flags & BM_VALID) && (bufHdr->flags & BM_DIRTY))
                {
-                       Oid                     bufdb;
-                       Oid                     bufrel;
-
-                       bufdb = bufHdr->tag.relId.dbId;
-                       bufrel = bufHdr->tag.relId.relId;
-                       if (bufdb == BufferTagLastDirtied[i].relId.dbId &&
-                               bufrel == BufferTagLastDirtied[i].relId.relId &&
+                       if (RelFileNodeEquals(bufHdr->tag.rnode, BufferTagLastDirtied[i].rnode) &&
                                bufHdr->tag.blockNum == BufferTagLastDirtied[i].blockNum)
                        {
+                               Oid             bufrel = bufHdr->relId.relId;
 
                                /*
                                 * Try to find relation for buf.  This could fail, if the
@@ -1147,24 +1075,16 @@ BufferSync()
                                         */
                                        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,
-                                                                                       bufHdr->blind.rnode,
+                                                                                       bufHdr->tag.rnode,
                                                                                        bufHdr->tag.blockNum,
                                                                                        (char *) MAKE_PTR(bufHdr->data),
                                                                                        true);  /* must fsync */
-#endif
                                        }
                                        else
                                        {
+                                               Assert(RelFileNodeEquals(reln->rd_node,
+                                                                       BufferTagLastDirtied[i].rnode));
                                                status = smgrwrite(DEFAULT_SMGR, reln,
                                                                                   bufHdr->tag.blockNum,
                                                                                (char *) MAKE_PTR(bufHdr->data));
@@ -1218,24 +1138,17 @@ BufferSync()
                        SpinRelease(BufMgrLock);
 #endif  /* OPTIMIZE_SINGLE */
 
-                       reln = RelationIdCacheGetRelation(BufferTagLastDirtied[i].relId.relId);
+                       reln = RelationIdCacheGetRelation(BufferRelidLastDirtied[i].relId);
                        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,
-                                                                       BufferBlindLastDirtied[i].rnode,
+                                                                       BufferTagLastDirtied[i].rnode,
                                                                        BufferTagLastDirtied[i].blockNum);
-#endif
                        }
                        else
                        {
+                               Assert(RelFileNodeEquals(reln->rd_node,
+                                                       BufferTagLastDirtied[i].rnode));
                                status = smgrmarkdirty(DEFAULT_SMGR, reln,
                                                                           BufferTagLastDirtied[i].blockNum);
 
@@ -1492,46 +1405,6 @@ BufferGetBlockNumber(Buffer buffer)
                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
  *
@@ -1554,8 +1427,8 @@ BufferReplace(BufferDesc *bufHdr)
         * 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.
         */
-       bufdb = bufHdr->tag.relId.dbId;
-       bufrel = bufHdr->tag.relId.relId;
+       bufdb = bufHdr->relId.dbId;
+       bufrel = bufHdr->relId.relId;
 
        if (bufdb == MyDatabaseId || bufdb == (Oid) NULL)
                reln = RelationIdCacheGetRelation(bufrel);
@@ -1576,23 +1449,16 @@ BufferReplace(BufferDesc *bufHdr)
 
        if (reln != (Relation) NULL)
        {
+               Assert(RelFileNodeEquals(bufHdr->tag.rnode, reln->rd_node));
                status = smgrwrite(DEFAULT_SMGR, reln, bufHdr->tag.blockNum,
                                                   (char *) MAKE_PTR(bufHdr->data));
        }
        else
        {
-#ifdef OLD_FILE_NAMING
-               status = smgrblindwrt(DEFAULT_SMGR, bufHdr->blind.dbname,
-                                                         bufHdr->blind.relname, bufdb, bufrel,
+               status = smgrblindwrt(DEFAULT_SMGR, bufHdr->tag.rnode,
                                                          bufHdr->tag.blockNum,
                                                          (char *) MAKE_PTR(bufHdr->data),
                                                          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);
@@ -1654,18 +1520,22 @@ ReleaseRelationBuffers(Relation rel)
 {
        Oid                     relid = RelationGetRelid(rel);
        int                     i;
-       BufferDesc *buf;
+       BufferDesc *bufHdr;
 
        if (rel->rd_myxactonly)
        {
                for (i = 0; i < NLocBuffer; i++)
                {
-                       buf = &LocalBufferDescriptors[i];
-                       if (buf->tag.relId.relId == relid)
+                       bufHdr = &LocalBufferDescriptors[i];
+                       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;
-                               buf->tag.relId.relId = InvalidOid;
+                               bufHdr->tag.rnode.relNode = InvalidOid;
+                       }
+                       else
+                       {
+                               Assert(bufHdr->relId.relId != relid);
                        }
                }
                return;
@@ -1674,11 +1544,9 @@ ReleaseRelationBuffers(Relation rel)
        SpinAcquire(BufMgrLock);
        for (i = 1; i <= NBuffers; i++)
        {
-               buf = &BufferDescriptors[i - 1];
+               bufHdr = &BufferDescriptors[i - 1];
 recheck:
-               if (buf->tag.relId.relId == relid &&
-                       (buf->tag.relId.dbId == MyDatabaseId ||
-                        buf->tag.relId.dbId == (Oid) NULL))
+               if (RelFileNodeEquals(bufHdr->tag.rnode, rel->rd_node))
                {
 
                        /*
@@ -1686,9 +1554,9 @@ recheck:
                         * don't want to delete the relation out from under someone
                         * 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
@@ -1697,8 +1565,8 @@ recheck:
                                goto recheck;
                        }
                        /* Now we can do what we came for */
-                       buf->flags &= ~(BM_DIRTY | BM_JUST_DIRTIED);
-                       ClearBufferDirtiedByMe(i, buf);
+                       bufHdr->flags &= ~(BM_DIRTY | BM_JUST_DIRTIED);
+                       BufferDirtiedByMe[i - 1] = false;
 
                        /*
                         * Release any refcount we may have.
@@ -1707,11 +1575,11 @@ recheck:
                         * probably wrong.      I added the Assert to find out --- tgl
                         * 11/99.
                         */
-                       if (!(buf->flags & BM_FREE))
+                       if (!(bufHdr->flags & BM_FREE))
                        {
                                /* Assert checks that buffer will actually get freed! */
                                Assert(PrivateRefCount[i - 1] == 1 &&
-                                          buf->refcount == 1);
+                                          bufHdr->refcount == 1);
                                /* ReleaseBuffer expects we do not hold the lock at entry */
                                SpinRelease(BufMgrLock);
                                ReleaseBuffer(i);
@@ -1720,9 +1588,19 @@ recheck:
                        /*
                         * 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);
 }
 
@@ -1741,14 +1619,19 @@ void
 DropBuffers(Oid dbid)
 {
        int                     i;
-       BufferDesc *buf;
+       BufferDesc *bufHdr;
 
        SpinAcquire(BufMgrLock);
        for (i = 1; i <= NBuffers; i++)
        {
-               buf = &BufferDescriptors[i - 1];
+               bufHdr = &BufferDescriptors[i - 1];
 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
                         * 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
@@ -1767,18 +1650,24 @@ recheck:
                                goto recheck;
                        }
                        /* Now we can do what we came for */
-                       buf->flags &= ~(BM_DIRTY | BM_JUST_DIRTIED);
-                       ClearBufferDirtiedByMe(i, buf);
+                       bufHdr->flags &= ~(BM_DIRTY | BM_JUST_DIRTIED);
+                       BufferDirtiedByMe[i - 1] = false;
 
                        /*
                         * The thing should be free, if caller has checked that no
                         * 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.
                         */
-                       BufTableDelete(buf);
+                       BufTableDelete(bufHdr);
+               }
+               else
+               {
+                       Assert(bufHdr->relId.dbId != dbid);
+                       if (BufferTagLastDirtied[i - 1].rnode.tblNode == dbid)
+                               BufferDirtiedByMe[i - 1] = false;
                }
        }
        SpinRelease(BufMgrLock);
@@ -1917,22 +1806,22 @@ FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock)
 {
        Oid                     relid = RelationGetRelid(rel);
        int                     i;
-       BufferDesc *buf;
+       BufferDesc *bufHdr;
 
        if (rel->rd_myxactonly)
        {
                for (i = 0; i < NLocBuffer; i++)
                {
-                       buf = &LocalBufferDescriptors[i];
-                       if (buf->tag.relId.relId == relid)
+                       bufHdr = &LocalBufferDescriptors[i];
+                       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)
                                        {
                                                elog(NOTICE, "FlushRelationBuffers(%s (local), %u): block %u is dirty, could not flush it",
                                                         RelationGetRelationName(rel), firstDelBlock,
-                                                        buf->tag.blockNum);
+                                                        bufHdr->tag.blockNum);
                                                return -1;
                                        }
                                }
@@ -1940,14 +1829,18 @@ FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock)
                                {
                                        elog(NOTICE, "FlushRelationBuffers(%s (local), %u): block %u is referenced (%ld)",
                                                 RelationGetRelationName(rel), firstDelBlock,
-                                                buf->tag.blockNum, LocalRefCount[i]);
+                                                bufHdr->tag.blockNum, LocalRefCount[i]);
                                        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;
        }
@@ -1955,22 +1848,20 @@ FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock)
        SpinAcquire(BufMgrLock);
        for (i = 0; i < NBuffers; i++)
        {
-               buf = &BufferDescriptors[i];
+               bufHdr = &BufferDescriptors[i];
 recheck:
-               if (buf->tag.relId.relId == relid &&
-                       (buf->tag.relId.dbId == MyDatabaseId ||
-                        buf->tag.relId.dbId == (Oid) NULL))
+               if (RelFileNodeEquals(bufHdr->tag.rnode, rel->rd_node))
                {
-                       if (buf->flags & BM_DIRTY)
+                       if (bufHdr->flags & BM_DIRTY)
                        {
-                               PinBuffer(buf);
+                               PinBuffer(bufHdr);
                                SpinRelease(BufMgrLock);
                                if (FlushBuffer(i + 1, true) != STATUS_OK)
                                {
                                        elog(NOTICE, "FlushRelationBuffers(%s, %u): block %u is dirty (private %ld, global %d), could not flush it",
                                                 RelationGetRelationName(rel), firstDelBlock,
-                                                buf->tag.blockNum,
-                                                PrivateRefCount[i], buf->refcount);
+                                                bufHdr->tag.blockNum,
+                                                PrivateRefCount[i], bufHdr->refcount);
                                        return -1;
                                }
                                SpinAcquire(BufMgrLock);
@@ -1981,20 +1872,26 @@ recheck:
                                 */
                                goto recheck;
                        }
-                       if (!(buf->flags & BM_FREE))
+                       if (!(bufHdr->flags & BM_FREE))
                        {
                                SpinRelease(BufMgrLock);
                                elog(NOTICE, "FlushRelationBuffers(%s, %u): block %u is referenced (private %ld, global %d)",
                                         RelationGetRelationName(rel), firstDelBlock,
-                                        buf->tag.blockNum,
-                                        PrivateRefCount[i], buf->refcount);
+                                        bufHdr->tag.blockNum,
+                                        PrivateRefCount[i], bufHdr->refcount);
                                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);
        return 0;
index 91eff97f26482649de63578b35394ce71cc1b373..3cb8f572b896bbf4352c0d007f91fcd434d4e347 100644 (file)
@@ -16,7 +16,7 @@
  *
  *
  * 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 */
        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)
                {
 
@@ -102,7 +103,7 @@ LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr)
         */
        if (bufHdr->flags & BM_DIRTY)
        {
-               Relation        bufrel = RelationIdCacheGetRelation(bufHdr->tag.relId.relId);
+               Relation        bufrel = RelationIdCacheGetRelation(bufHdr->relId.relId);
 
                Assert(bufrel != NULL);
 
@@ -120,9 +121,13 @@ LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr)
 
        /*
         * 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->relId = reln->rd_lockInfo.lockRelId;
        bufHdr->flags &= ~BM_DIRTY;
 
        /*
@@ -187,7 +192,7 @@ FlushLocalBuffer(Buffer buffer, bool release)
        bufid = -(buffer + 1);
        bufHdr = &LocalBufferDescriptors[bufid];
        bufHdr->flags &= ~BM_DIRTY;
-       bufrel = RelationIdCacheGetRelation(bufHdr->tag.relId.relId);
+       bufrel = RelationIdCacheGetRelation(bufHdr->relId.relId);
 
        Assert(bufrel != NULL);
        smgrflush(DEFAULT_SMGR, bufrel, bufHdr->tag.blockNum,
@@ -263,7 +268,7 @@ LocalBufferSync(void)
 #ifdef LBDEBUG
                        fprintf(stderr, "LB SYNC %d\n", -i - 1);
 #endif
-                       bufrel = RelationIdCacheGetRelation(buf->tag.relId.relId);
+                       bufrel = RelationIdCacheGetRelation(buf->relId.relId);
 
                        Assert(bufrel != NULL);
 
@@ -274,7 +279,7 @@ LocalBufferSync(void)
                        /* drop relcache refcount from RelationIdCacheGetRelation */
                        RelationDecrementReferenceCount(bufrel);
 
-                       buf->tag.relId.relId = InvalidOid;
+                       buf->relId.relId = InvalidOid;
                        buf->flags &= ~BM_DIRTY;
                }
        }
@@ -292,7 +297,7 @@ ResetLocalBufferPool(void)
        {
                BufferDesc *buf = &LocalBufferDescriptors[i];
 
-               buf->tag.relId.relId = InvalidOid;
+               buf->tag.rnode.relNode = InvalidOid;
                buf->flags &= ~BM_DIRTY;
                buf->buf_id = -i - 2;
        }
index 4f4a516afdfe9aca17b8d9853847cf65a576202b..12bf6604da198a504a23d96fd0871a46b3388599 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * 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
 {
-       LockRelId       relId;
+       RelFileNode     rnode;
        BlockNumber blockNum;           /* blknum relative to begin of reln */
 } BufferTag;
 
 #define CLEAR_BUFFERTAG(a) \
 ( \
-       (a)->relId.dbId = InvalidOid, \
-       (a)->relId.relId = InvalidOid, \
+       (a)->rnode.tblNode = InvalidOid, \
+       (a)->rnode.relNode = InvalidOid, \
        (a)->blockNum = InvalidBlockNumber \
 )
 
 #define INIT_BUFFERTAG(a,xx_reln,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),
- * the BufferTag is not enough information.  BufferBlindId carries the
- * additional information needed.
+/*
+ * We don't need in this data any more but it allows more user
+ * friendly error messages. Feel free to get rid of it
+ * (and change a lot of places -:))
  */
 typedef struct bufblindid
 {
@@ -72,17 +72,6 @@ typedef struct bufblindid
        char            relname[NAMEDATALEN];   /* name of reln */
 }                      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 INVALID_DESCRIPTOR (-3)
 
@@ -120,7 +109,22 @@ typedef struct sbufdesc
        bool            ri_lock;                /* read-intent lock */
        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;
 
 /*
@@ -187,6 +191,7 @@ extern long *PrivateRefCount;
 extern bits8 *BufferLocks;
 extern BufferTag *BufferTagLastDirtied;
 extern BufferBlindId *BufferBlindLastDirtied;
+extern LockRelId *BufferRelidLastDirtied;
 extern bool *BufferDirtiedByMe;
 extern SPINLOCK BufMgrLock;
 
index de4d1e1beea1ee13b97ec3ba4537cacc0a450159..ee6e2c2280504b89017cd12d114eb5937a332636 100644 (file)
@@ -15,4 +15,8 @@ typedef struct RelFileNode
        Oid                                     relNode;                /* relation */
 } RelFileNode;
 
+#define        RelFileNodeEquals(node1, node2) \
+       ((node1).relNode == (node2).relNode && \
+       (node2).tblNode == (node2).tblNode)
+
 #endif /* RELFILENODE_H */