Fixed bug where FlushRelationBuffers() did call StrategyInvalidateBuffer()
authorJan Wieck <JanWieck@Yahoo.com>
Thu, 12 Feb 2004 15:06:56 +0000 (15:06 +0000)
committerJan Wieck <JanWieck@Yahoo.com>
Thu, 12 Feb 2004 15:06:56 +0000 (15:06 +0000)
for already empty buffers because their buffer tag was not cleard out
when the buffers have been invalidated before.

Also removed the misnamed BM_FREE bufhdr flag and replaced the checks,
which effectively ask if the buffer is unpinned, with checks against the
refcount field.

Jan

src/backend/storage/buffer/buf_init.c
src/backend/storage/buffer/bufmgr.c
src/backend/storage/buffer/freelist.c
src/include/storage/buf_internals.h

index 2f3c818c19167e5dd5608251759467762a43ee47..a671bf9f7ff87a755fa53b0d75826efc5956fa36 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/storage/buffer/buf_init.c,v 1.61 2004/01/15 16:14:26 wieck Exp $
+ *       $PostgreSQL: pgsql/src/backend/storage/buffer/buf_init.c,v 1.62 2004/02/12 15:06:56 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -164,7 +164,7 @@ InitBufferPool(void)
                        buf->buf_id = i;
 
                        buf->data = MAKE_OFFSET(block);
-                       buf->flags = (BM_DELETED | BM_FREE | BM_VALID);
+                       buf->flags = (BM_DELETED | BM_VALID);
                        buf->refcount = 0;
                        buf->io_in_progress_lock = LWLockAssign();
                        buf->cntx_lock = LWLockAssign();
index 0ad26ee4f0be2aeae73400caf908236dbde2a4de..e7435b9534a4e894ef06276a817da7f3edfc4786 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.158 2004/02/10 03:42:45 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.159 2004/02/12 15:06:56 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1190,7 +1190,7 @@ recheck:
                         * Release any refcount we may have.  If someone else has a
                         * pin on the buffer, we got trouble.
                         */
-                       if (!(bufHdr->flags & BM_FREE))
+                       if (bufHdr->refcount != 0)
                        {
                                /* the sole pin should be ours */
                                if (bufHdr->refcount != 1 || PrivateRefCount[i - 1] == 0)
@@ -1268,7 +1268,7 @@ recheck:
                         * The thing should be free, if caller has checked that no
                         * backends are running in that database.
                         */
-                       Assert(bufHdr->flags & BM_FREE);
+                       Assert(bufHdr->refcount == 0);
 
                        /*
                         * And mark the buffer as no longer occupied by this page.
@@ -1501,7 +1501,7 @@ FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock)
                                }
                                UnpinBuffer(bufHdr);
                        }
-                       if (!(bufHdr->flags & BM_FREE))
+                       if (bufHdr->refcount != 0)
                        {
                                LWLockRelease(BufMgrLock);
                                error_context_stack = errcontext.previous;
index 74ec4518ab90fdec2b61310df342a862f930987a..595e4905a80c6fdb1e8d4f9946d867f4126c26e6 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/storage/buffer/freelist.c,v 1.40 2004/02/06 19:36:18 wieck Exp $
+ *       $PostgreSQL: pgsql/src/backend/storage/buffer/freelist.c,v 1.41 2004/02/12 15:06:56 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -662,9 +662,6 @@ void
 StrategyInvalidateBuffer(BufferDesc *buf)
 {
        int                                     cdb_id;
-#ifdef USE_ASSERT_CHECKING
-       int                                     buf_id;
-#endif
        BufferStrategyCDB  *cdb;
 
        /* The buffer cannot be dirty or pinned */
@@ -672,41 +669,37 @@ StrategyInvalidateBuffer(BufferDesc *buf)
        Assert(buf->refcount == 0);
 
        /*
-        * If we have the buffer somewhere in the directory, remove it,
-        * add the CDB to the list of unused CDB's. and the buffer to
-        * the list of free buffers
+        * Lookup the cache directory block for this buffer
         */
        cdb_id = BufTableLookup(&(buf->tag));
-       if (cdb_id >= 0)
-       {
-               cdb = &StrategyCDB[cdb_id];
-               BufTableDelete(&(cdb->buf_tag));
-               STRAT_LIST_REMOVE(cdb);
-               cdb->buf_id = -1;
-               cdb->next = StrategyControl->listUnusedCDB;
-               StrategyControl->listUnusedCDB = cdb_id;
-
-               buf->bufNext = StrategyControl->listFreeBuffers;
-               StrategyControl->listFreeBuffers = buf->buf_id;
-               return;
-       }
+       if (cdb_id < 0)
+               elog(ERROR, "StrategyInvalidateBuffer() buffer %d not in directory",
+                               buf->buf_id);
+       cdb = &StrategyCDB[cdb_id];
 
-#ifdef USE_ASSERT_CHECKING
        /*
-        * Check that we have this buffer in the freelist already.
+        * Remove the CDB from the hashtable and the ARC queue it is
+        * currently on.
         */
-       buf_id = StrategyControl->listFreeBuffers;
-       while (buf_id >= 0)
-       {
-               if (buf == &BufferDescriptors[buf_id])
-                       return;
+       BufTableDelete(&(cdb->buf_tag));
+       STRAT_LIST_REMOVE(cdb);
 
-               buf_id = BufferDescriptors[buf_id].bufNext;
-       }
+       /*
+        * Clear out the CDB's buffer tag and association with the buffer
+        * and add it to the list of unused CDB's
+        */
+       CLEAR_BUFFERTAG(&(cdb->buf_tag));
+       cdb->buf_id = -1;
+       cdb->next = StrategyControl->listUnusedCDB;
+       StrategyControl->listUnusedCDB = cdb_id;
 
-       elog(ERROR, "StrategyInvalidateBuffer() buffer %d not in directory or freelist",
-                               buf->buf_id);
-#endif
+       /*
+        * Clear out the buffers tag and add it to the list of
+        * currently unused buffers.
+        */
+       CLEAR_BUFFERTAG(&(buf->tag));
+       buf->bufNext = StrategyControl->listFreeBuffers;
+       StrategyControl->listFreeBuffers = buf->buf_id;
 }
 
 
@@ -869,12 +862,6 @@ PinBuffer(BufferDesc *buf)
 {
        int                     b = BufferDescriptorGetBuffer(buf) - 1;
 
-       if (buf->refcount == 0)
-       {
-               /* mark buffer as no longer free */
-               buf->flags &= ~BM_FREE;
-       }
-
        if (PrivateRefCount[b] == 0)
                buf->refcount++;
        PrivateRefCount[b]++;
@@ -917,12 +904,7 @@ UnpinBuffer(BufferDesc *buf)
        if (PrivateRefCount[b] == 0)
                buf->refcount--;
 
-       if (buf->refcount == 0)
-       {
-               /* buffer is now unpinned */
-               buf->flags |= BM_FREE;
-       }
-       else if ((buf->flags & BM_PIN_COUNT_WAITER) != 0 &&
+       if ((buf->flags & BM_PIN_COUNT_WAITER) != 0 &&
                         buf->refcount == 1)
        {
                /* we just released the last pin other than the waiter's */
@@ -953,70 +935,3 @@ refcount = %ld, file: %s, line: %d\n",
 #endif
 
 
-/*
- * print out the free list and check for breaks.
- */
-#ifdef NOT_USED
-void
-DBG_FreeListCheck(int nfree)
-{
-       int                     i;
-       BufferDesc *buf;
-
-       buf = &(BufferDescriptors[SharedFreeList->freeNext]);
-       for (i = 0; i < nfree; i++, buf = &(BufferDescriptors[buf->freeNext]))
-       {
-               if (!(buf->flags & (BM_FREE)))
-               {
-                       if (buf != SharedFreeList)
-                               printf("\tfree list corrupted: %d flags %x\n",
-                                          buf->buf_id, buf->flags);
-                       else
-                               printf("\tfree list corrupted: too short -- %d not %d\n",
-                                          i, nfree);
-               }
-               if ((BufferDescriptors[buf->freeNext].freePrev != buf->buf_id) ||
-                       (BufferDescriptors[buf->freePrev].freeNext != buf->buf_id))
-                       printf("\tfree list links corrupted: %d %ld %ld\n",
-                                  buf->buf_id, buf->freePrev, buf->freeNext);
-       }
-       if (buf != SharedFreeList)
-               printf("\tfree list corrupted: %d-th buffer is %d\n",
-                          nfree, buf->buf_id);
-}
-#endif
-
-#ifdef NOT_USED
-/*
- * PrintBufferFreeList -
- *       prints the buffer free list, for debugging
- */
-static void
-PrintBufferFreeList()
-{
-       BufferDesc *buf;
-
-       if (SharedFreeList->freeNext == Free_List_Descriptor)
-       {
-               printf("free list is empty.\n");
-               return;
-       }
-
-       buf = &(BufferDescriptors[SharedFreeList->freeNext]);
-       for (;;)
-       {
-               int                     i = (buf - BufferDescriptors);
-
-               printf("[%-2d] (%s, %d) flags=0x%x, refcnt=%d %ld, nxt=%ld prv=%ld)\n",
-                          i, buf->blind.relname, buf->tag.blockNum,
-                          buf->flags, buf->refcount, PrivateRefCount[i],
-                          buf->freeNext, buf->freePrev);
-
-               if (buf->freeNext == Free_List_Descriptor)
-                       break;
-
-               buf = &(BufferDescriptors[buf->freeNext]);
-       }
-}
-
-#endif
index ce4be5439b4d2a5712643f6ab9f305e82e68e16a..f401791d93a7c7c3168cee9305a9d3562bdc82eb 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/storage/buf_internals.h,v 1.67 2004/01/15 16:14:26 wieck Exp $
+ * $PostgreSQL: pgsql/src/include/storage/buf_internals.h,v 1.68 2004/02/12 15:06:56 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -36,11 +36,10 @@ extern int  ShowPinTrace;
 #define BM_DIRTY                               (1 << 0)
 #define BM_VALID                               (1 << 1)
 #define BM_DELETED                             (1 << 2)
-#define BM_FREE                                        (1 << 3)
-#define BM_IO_IN_PROGRESS              (1 << 4)
-#define BM_IO_ERROR                            (1 << 5)
-#define BM_JUST_DIRTIED                        (1 << 6)
-#define BM_PIN_COUNT_WAITER            (1 << 7)
+#define BM_IO_IN_PROGRESS              (1 << 3)
+#define BM_IO_ERROR                            (1 << 4)
+#define BM_JUST_DIRTIED                        (1 << 5)
+#define BM_PIN_COUNT_WAITER            (1 << 6)
 
 typedef bits16 BufFlags;