I had to change buffer tag: now RelFileNode is used instead of
authorVadim B. Mikheev
Wed, 18 Oct 2000 05:50:16 +0000 (05:50 +0000)
committerVadim B. Mikheev
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 */