Thread: BufMgr cleanup

BufMgr cleanup

From
Manfred Koizar
Date:
Minor code cleanup in bufmgr.c and bufmgr.h, mainly by moving repeated
lines of code into internal routines (drop_relfilenode_buffers,
release_buffer) and by hiding unused routines (PrintBufferDescs,
PrintPinnedBufs) behind #ifdef NOT_USED.
Remove AbortBufferIO() declaration from bufmgr.c (already declared
in bufmgr.h)

diff -ru ../orig/src/backend/storage/buffer/bufmgr.c src/backend/storage/buffer/bufmgr.c
--- ../orig/src/backend/storage/buffer/bufmgr.c    2002-06-13 09:32:40.000000000 +0200
+++ src/backend/storage/buffer/bufmgr.c    2002-06-13 11:02:47.000000000 +0200
@@ -71,7 +71,6 @@
 static void StartBufferIO(BufferDesc *buf, bool forInput);
 static void TerminateBufferIO(BufferDesc *buf);
 static void ContinueBufferIO(BufferDesc *buf, bool forInput);
-extern void AbortBufferIO(void);

 /*
  * Macro : BUFFER_IS_BROKEN
@@ -85,9 +84,14 @@
             bool *foundPtr);
 static int    ReleaseBufferWithBufferLock(Buffer buffer);
 static int    BufferReplace(BufferDesc *bufHdr);
+#ifdef NOT_USED
 void        PrintBufferDescs(void);
+#endif

 static void write_buffer(Buffer buffer, bool unpin);
+static void drop_relfilenode_buffers(RelFileNode rnode,
+                                     bool do_local, bool do_both);
+static int release_buffer(Buffer buffer, bool havelock);

 /*
  * ReadBuffer -- returns a buffer containing the requested
@@ -1097,34 +1101,26 @@
     return relation->rd_nblocks;
 }

-/* ---------------------------------------------------------------------
- *        DropRelationBuffers
- *
- *        This function removes all the buffered pages for a relation
- *        from the buffer pool.  Dirty pages are simply dropped, without
- *        bothering to write them out first.    This is NOT rollback-able,
- *        and so should be used only with extreme caution!
- *
- *        We assume that the caller holds an exclusive lock on the relation,
- *        which should assure that no new buffers will be acquired for the rel
- *        meanwhile.
+/*
+ * drop_relfilenode_buffers -- common functionality for
+ *                             DropRelationBuffers and
+ *                             DropRelFileNodeBuffers
  *
  *        XXX currently it sequentially searches the buffer pool, should be
  *        changed to more clever ways of searching.
- * --------------------------------------------------------------------
  */
-void
-DropRelationBuffers(Relation rel)
+static void
+drop_relfilenode_buffers(RelFileNode rnode, bool do_local, bool do_both)
 {
     int            i;
     BufferDesc *bufHdr;

-    if (rel->rd_myxactonly)
+    if (do_local)
     {
         for (i = 0; i < NLocBuffer; i++)
         {
             bufHdr = &LocalBufferDescriptors[i];
-            if (RelFileNodeEquals(bufHdr->tag.rnode, rel->rd_node))
+            if (RelFileNodeEquals(bufHdr->tag.rnode, rnode))
             {
                 bufHdr->flags &= ~(BM_DIRTY | BM_JUST_DIRTIED);
                 bufHdr->cntxDirty = false;
@@ -1132,7 +1128,8 @@
                 bufHdr->tag.rnode.relNode = InvalidOid;
             }
         }
-        return;
+        if (!do_both)
+            return;
     }

     LWLockAcquire(BufMgrLock, LW_EXCLUSIVE);
@@ -1141,7 +1138,7 @@
     {
         bufHdr = &BufferDescriptors[i - 1];
 recheck:
-        if (RelFileNodeEquals(bufHdr->tag.rnode, rel->rd_node))
+        if (RelFileNodeEquals(bufHdr->tag.rnode, rnode))
         {
             /*
              * If there is I/O in progress, better wait till it's done;
@@ -1188,6 +1185,25 @@
 }

 /* ---------------------------------------------------------------------
+ *        DropRelationBuffers
+ *
+ *        This function removes all the buffered pages for a relation
+ *        from the buffer pool.  Dirty pages are simply dropped, without
+ *        bothering to write them out first.    This is NOT rollback-able,
+ *        and so should be used only with extreme caution!
+ *
+ *        We assume that the caller holds an exclusive lock on the relation,
+ *        which should assure that no new buffers will be acquired for the rel
+ *        meanwhile.
+ * --------------------------------------------------------------------
+ */
+void
+DropRelationBuffers(Relation rel)
+{
+    drop_relfilenode_buffers(rel->rd_node, rel->rd_myxactonly, false);
+}
+
+/* ---------------------------------------------------------------------
  *        DropRelFileNodeBuffers
  *
  *        This is the same as DropRelationBuffers, except that the target
@@ -1201,73 +1217,8 @@
 void
 DropRelFileNodeBuffers(RelFileNode rnode)
 {
-    int            i;
-    BufferDesc *bufHdr;
-
     /* We have to search both local and shared buffers... */
-
-    for (i = 0; i < NLocBuffer; i++)
-    {
-        bufHdr = &LocalBufferDescriptors[i];
-        if (RelFileNodeEquals(bufHdr->tag.rnode, rnode))
-        {
-            bufHdr->flags &= ~(BM_DIRTY | BM_JUST_DIRTIED);
-            bufHdr->cntxDirty = false;
-            LocalRefCount[i] = 0;
-            bufHdr->tag.rnode.relNode = InvalidOid;
-        }
-    }
-
-    LWLockAcquire(BufMgrLock, LW_EXCLUSIVE);
-
-    for (i = 1; i <= NBuffers; i++)
-    {
-        bufHdr = &BufferDescriptors[i - 1];
-recheck:
-        if (RelFileNodeEquals(bufHdr->tag.rnode, rnode))
-        {
-            /*
-             * If there is I/O in progress, better wait till it's done;
-             * don't want to delete the relation out from under someone
-             * who's just trying to flush the buffer!
-             */
-            if (bufHdr->flags & BM_IO_IN_PROGRESS)
-            {
-                WaitIO(bufHdr);
-
-                /*
-                 * By now, the buffer very possibly belongs to some other
-                 * rel, so check again before proceeding.
-                 */
-                goto recheck;
-            }
-            /* Now we can do what we came for */
-            bufHdr->flags &= ~(BM_DIRTY | BM_JUST_DIRTIED);
-            bufHdr->cntxDirty = false;
-
-            /*
-             * Release any refcount we may have.
-             *
-             * This is very probably dead code, and if it isn't then it's
-             * probably wrong.    I added the Assert to find out --- tgl
-             * 11/99.
-             */
-            if (!(bufHdr->flags & BM_FREE))
-            {
-                /* Assert checks that buffer will actually get freed! */
-                Assert(PrivateRefCount[i - 1] == 1 &&
-                       bufHdr->refcount == 1);
-                ReleaseBufferWithBufferLock(i);
-            }
-
-            /*
-             * And mark the buffer as no longer occupied by this rel.
-             */
-            BufTableDelete(bufHdr);
-        }
-    }
-
-    LWLockRelease(BufMgrLock);
+    drop_relfilenode_buffers(rnode, true, true);
 }

 /* ---------------------------------------------------------------------
@@ -1343,6 +1294,7 @@
  *        use only.
  * -----------------------------------------------------------------
  */
+#ifdef NOT_USED
 void
 PrintBufferDescs()
 {
@@ -1375,7 +1327,9 @@
         }
     }
 }
+#endif

+#ifdef NOT_USED
 void
 PrintPinnedBufs()
 {
@@ -1395,6 +1349,7 @@
     }
     LWLockRelease(BufMgrLock);
 }
+#endif

 /*
  * BufferPoolBlowaway
@@ -1589,14 +1544,12 @@
     return 0;
 }

-#undef ReleaseBuffer
-
 /*
- * ReleaseBuffer -- remove the pin on a buffer without
- *        marking it dirty.
+ * release_buffer -- common functionality for
+ *                   ReleaseBuffer and ReleaseBufferWithBufferLock
  */
-int
-ReleaseBuffer(Buffer buffer)
+static int
+release_buffer(Buffer buffer, bool havelock)
 {
     BufferDesc *bufHdr;

@@ -1617,14 +1570,30 @@
         PrivateRefCount[buffer - 1]--;
     else
     {
-        LWLockAcquire(BufMgrLock, LW_EXCLUSIVE);
+        if (!havelock)
+            LWLockAcquire(BufMgrLock, LW_EXCLUSIVE);
+
         UnpinBuffer(bufHdr);
-        LWLockRelease(BufMgrLock);
+
+        if (!havelock)
+            LWLockRelease(BufMgrLock);
     }

     return STATUS_OK;
 }

+#undef ReleaseBuffer
+
+/*
+ * ReleaseBuffer -- remove the pin on a buffer without
+ *        marking it dirty.
+ */
+int
+ReleaseBuffer(Buffer buffer)
+{
+    return release_buffer(buffer, false);
+}
+
 /*
  * ReleaseBufferWithBufferLock
  *        Same as ReleaseBuffer except we hold the bufmgr lock
@@ -1632,27 +1601,7 @@
 static int
 ReleaseBufferWithBufferLock(Buffer buffer)
 {
-    BufferDesc *bufHdr;
-
-    if (BufferIsLocal(buffer))
-    {
-        Assert(LocalRefCount[-buffer - 1] > 0);
-        LocalRefCount[-buffer - 1]--;
-        return STATUS_OK;
-    }
-
-    if (BAD_BUFFER_ID(buffer))
-        return STATUS_ERROR;
-
-    bufHdr = &BufferDescriptors[buffer - 1];
-
-    Assert(PrivateRefCount[buffer - 1] > 0);
-    if (PrivateRefCount[buffer - 1] > 1)
-        PrivateRefCount[buffer - 1]--;
-    else
-        UnpinBuffer(bufHdr);
-
-    return STATUS_OK;
+    return release_buffer(buffer, true);
 }


@@ -1695,7 +1644,7 @@
 #endif

 #ifdef NOT_USED
-int
+Buffer
 ReleaseAndReadBuffer_Debug(char *file,
                            int line,
                            Buffer buffer,
@@ -2117,7 +2066,7 @@
 {
     Assert(buf == InProgressBuf);
     LWLockRelease(buf->io_in_progress_lock);
-    InProgressBuf = (BufferDesc *) 0;
+    InProgressBuf = (BufferDesc *) NULL;
 }

 /*
@@ -2142,7 +2091,7 @@
 void
 InitBufferIO(void)
 {
-    InProgressBuf = (BufferDesc *) 0;
+    InProgressBuf = (BufferDesc *) NULL;
 }
 #endif

diff -ru ../orig/src/include/storage/bufmgr.h src/include/storage/bufmgr.h
--- ../orig/src/include/storage/bufmgr.h    2002-06-13 09:22:59.000000000 +0200
+++ src/include/storage/bufmgr.h    2002-06-13 10:57:22.000000000 +0200
@@ -167,7 +167,9 @@
 extern void DropRelationBuffers(Relation rel);
 extern void DropRelFileNodeBuffers(RelFileNode rnode);
 extern void DropBuffers(Oid dbid);
+#ifdef NOT_USED
 extern void PrintPinnedBufs(void);
+#endif
 extern int    BufferShmemSize(void);
 extern RelFileNode BufferGetFileNode(Buffer buffer);



Re: BufMgr cleanup

From
Bruce Momjian
Date:
Your patch has been added to the PostgreSQL unapplied patches list at:

    http://candle.pha.pa.us/cgi-bin/pgpatches

I will try to apply it within the next 48 hours.

---------------------------------------------------------------------------


Manfred Koizar wrote:
> Minor code cleanup in bufmgr.c and bufmgr.h, mainly by moving repeated
> lines of code into internal routines (drop_relfilenode_buffers,
> release_buffer) and by hiding unused routines (PrintBufferDescs,
> PrintPinnedBufs) behind #ifdef NOT_USED.
> Remove AbortBufferIO() declaration from bufmgr.c (already declared
> in bufmgr.h)
>
> diff -ru ../orig/src/backend/storage/buffer/bufmgr.c src/backend/storage/buffer/bufmgr.c
> --- ../orig/src/backend/storage/buffer/bufmgr.c    2002-06-13 09:32:40.000000000 +0200
> +++ src/backend/storage/buffer/bufmgr.c    2002-06-13 11:02:47.000000000 +0200
> @@ -71,7 +71,6 @@
>  static void StartBufferIO(BufferDesc *buf, bool forInput);
>  static void TerminateBufferIO(BufferDesc *buf);
>  static void ContinueBufferIO(BufferDesc *buf, bool forInput);
> -extern void AbortBufferIO(void);
>
>  /*
>   * Macro : BUFFER_IS_BROKEN
> @@ -85,9 +84,14 @@
>              bool *foundPtr);
>  static int    ReleaseBufferWithBufferLock(Buffer buffer);
>  static int    BufferReplace(BufferDesc *bufHdr);
> +#ifdef NOT_USED
>  void        PrintBufferDescs(void);
> +#endif
>
>  static void write_buffer(Buffer buffer, bool unpin);
> +static void drop_relfilenode_buffers(RelFileNode rnode,
> +                                     bool do_local, bool do_both);
> +static int release_buffer(Buffer buffer, bool havelock);
>
>  /*
>   * ReadBuffer -- returns a buffer containing the requested
> @@ -1097,34 +1101,26 @@
>      return relation->rd_nblocks;
>  }
>
> -/* ---------------------------------------------------------------------
> - *        DropRelationBuffers
> - *
> - *        This function removes all the buffered pages for a relation
> - *        from the buffer pool.  Dirty pages are simply dropped, without
> - *        bothering to write them out first.    This is NOT rollback-able,
> - *        and so should be used only with extreme caution!
> - *
> - *        We assume that the caller holds an exclusive lock on the relation,
> - *        which should assure that no new buffers will be acquired for the rel
> - *        meanwhile.
> +/*
> + * drop_relfilenode_buffers -- common functionality for
> + *                             DropRelationBuffers and
> + *                             DropRelFileNodeBuffers
>   *
>   *        XXX currently it sequentially searches the buffer pool, should be
>   *        changed to more clever ways of searching.
> - * --------------------------------------------------------------------
>   */
> -void
> -DropRelationBuffers(Relation rel)
> +static void
> +drop_relfilenode_buffers(RelFileNode rnode, bool do_local, bool do_both)
>  {
>      int            i;
>      BufferDesc *bufHdr;
>
> -    if (rel->rd_myxactonly)
> +    if (do_local)
>      {
>          for (i = 0; i < NLocBuffer; i++)
>          {
>              bufHdr = &LocalBufferDescriptors[i];
> -            if (RelFileNodeEquals(bufHdr->tag.rnode, rel->rd_node))
> +            if (RelFileNodeEquals(bufHdr->tag.rnode, rnode))
>              {
>                  bufHdr->flags &= ~(BM_DIRTY | BM_JUST_DIRTIED);
>                  bufHdr->cntxDirty = false;
> @@ -1132,7 +1128,8 @@
>                  bufHdr->tag.rnode.relNode = InvalidOid;
>              }
>          }
> -        return;
> +        if (!do_both)
> +            return;
>      }
>
>      LWLockAcquire(BufMgrLock, LW_EXCLUSIVE);
> @@ -1141,7 +1138,7 @@
>      {
>          bufHdr = &BufferDescriptors[i - 1];
>  recheck:
> -        if (RelFileNodeEquals(bufHdr->tag.rnode, rel->rd_node))
> +        if (RelFileNodeEquals(bufHdr->tag.rnode, rnode))
>          {
>              /*
>               * If there is I/O in progress, better wait till it's done;
> @@ -1188,6 +1185,25 @@
>  }
>
>  /* ---------------------------------------------------------------------
> + *        DropRelationBuffers
> + *
> + *        This function removes all the buffered pages for a relation
> + *        from the buffer pool.  Dirty pages are simply dropped, without
> + *        bothering to write them out first.    This is NOT rollback-able,
> + *        and so should be used only with extreme caution!
> + *
> + *        We assume that the caller holds an exclusive lock on the relation,
> + *        which should assure that no new buffers will be acquired for the rel
> + *        meanwhile.
> + * --------------------------------------------------------------------
> + */
> +void
> +DropRelationBuffers(Relation rel)
> +{
> +    drop_relfilenode_buffers(rel->rd_node, rel->rd_myxactonly, false);
> +}
> +
> +/* ---------------------------------------------------------------------
>   *        DropRelFileNodeBuffers
>   *
>   *        This is the same as DropRelationBuffers, except that the target
> @@ -1201,73 +1217,8 @@
>  void
>  DropRelFileNodeBuffers(RelFileNode rnode)
>  {
> -    int            i;
> -    BufferDesc *bufHdr;
> -
>      /* We have to search both local and shared buffers... */
> -
> -    for (i = 0; i < NLocBuffer; i++)
> -    {
> -        bufHdr = &LocalBufferDescriptors[i];
> -        if (RelFileNodeEquals(bufHdr->tag.rnode, rnode))
> -        {
> -            bufHdr->flags &= ~(BM_DIRTY | BM_JUST_DIRTIED);
> -            bufHdr->cntxDirty = false;
> -            LocalRefCount[i] = 0;
> -            bufHdr->tag.rnode.relNode = InvalidOid;
> -        }
> -    }
> -
> -    LWLockAcquire(BufMgrLock, LW_EXCLUSIVE);
> -
> -    for (i = 1; i <= NBuffers; i++)
> -    {
> -        bufHdr = &BufferDescriptors[i - 1];
> -recheck:
> -        if (RelFileNodeEquals(bufHdr->tag.rnode, rnode))
> -        {
> -            /*
> -             * If there is I/O in progress, better wait till it's done;
> -             * don't want to delete the relation out from under someone
> -             * who's just trying to flush the buffer!
> -             */
> -            if (bufHdr->flags & BM_IO_IN_PROGRESS)
> -            {
> -                WaitIO(bufHdr);
> -
> -                /*
> -                 * By now, the buffer very possibly belongs to some other
> -                 * rel, so check again before proceeding.
> -                 */
> -                goto recheck;
> -            }
> -            /* Now we can do what we came for */
> -            bufHdr->flags &= ~(BM_DIRTY | BM_JUST_DIRTIED);
> -            bufHdr->cntxDirty = false;
> -
> -            /*
> -             * Release any refcount we may have.
> -             *
> -             * This is very probably dead code, and if it isn't then it's
> -             * probably wrong.    I added the Assert to find out --- tgl
> -             * 11/99.
> -             */
> -            if (!(bufHdr->flags & BM_FREE))
> -            {
> -                /* Assert checks that buffer will actually get freed! */
> -                Assert(PrivateRefCount[i - 1] == 1 &&
> -                       bufHdr->refcount == 1);
> -                ReleaseBufferWithBufferLock(i);
> -            }
> -
> -            /*
> -             * And mark the buffer as no longer occupied by this rel.
> -             */
> -            BufTableDelete(bufHdr);
> -        }
> -    }
> -
> -    LWLockRelease(BufMgrLock);
> +    drop_relfilenode_buffers(rnode, true, true);
>  }
>
>  /* ---------------------------------------------------------------------
> @@ -1343,6 +1294,7 @@
>   *        use only.
>   * -----------------------------------------------------------------
>   */
> +#ifdef NOT_USED
>  void
>  PrintBufferDescs()
>  {
> @@ -1375,7 +1327,9 @@
>          }
>      }
>  }
> +#endif
>
> +#ifdef NOT_USED
>  void
>  PrintPinnedBufs()
>  {
> @@ -1395,6 +1349,7 @@
>      }
>      LWLockRelease(BufMgrLock);
>  }
> +#endif
>
>  /*
>   * BufferPoolBlowaway
> @@ -1589,14 +1544,12 @@
>      return 0;
>  }
>
> -#undef ReleaseBuffer
> -
>  /*
> - * ReleaseBuffer -- remove the pin on a buffer without
> - *        marking it dirty.
> + * release_buffer -- common functionality for
> + *                   ReleaseBuffer and ReleaseBufferWithBufferLock
>   */
> -int
> -ReleaseBuffer(Buffer buffer)
> +static int
> +release_buffer(Buffer buffer, bool havelock)
>  {
>      BufferDesc *bufHdr;
>
> @@ -1617,14 +1570,30 @@
>          PrivateRefCount[buffer - 1]--;
>      else
>      {
> -        LWLockAcquire(BufMgrLock, LW_EXCLUSIVE);
> +        if (!havelock)
> +            LWLockAcquire(BufMgrLock, LW_EXCLUSIVE);
> +
>          UnpinBuffer(bufHdr);
> -        LWLockRelease(BufMgrLock);
> +
> +        if (!havelock)
> +            LWLockRelease(BufMgrLock);
>      }
>
>      return STATUS_OK;
>  }
>
> +#undef ReleaseBuffer
> +
> +/*
> + * ReleaseBuffer -- remove the pin on a buffer without
> + *        marking it dirty.
> + */
> +int
> +ReleaseBuffer(Buffer buffer)
> +{
> +    return release_buffer(buffer, false);
> +}
> +
>  /*
>   * ReleaseBufferWithBufferLock
>   *        Same as ReleaseBuffer except we hold the bufmgr lock
> @@ -1632,27 +1601,7 @@
>  static int
>  ReleaseBufferWithBufferLock(Buffer buffer)
>  {
> -    BufferDesc *bufHdr;
> -
> -    if (BufferIsLocal(buffer))
> -    {
> -        Assert(LocalRefCount[-buffer - 1] > 0);
> -        LocalRefCount[-buffer - 1]--;
> -        return STATUS_OK;
> -    }
> -
> -    if (BAD_BUFFER_ID(buffer))
> -        return STATUS_ERROR;
> -
> -    bufHdr = &BufferDescriptors[buffer - 1];
> -
> -    Assert(PrivateRefCount[buffer - 1] > 0);
> -    if (PrivateRefCount[buffer - 1] > 1)
> -        PrivateRefCount[buffer - 1]--;
> -    else
> -        UnpinBuffer(bufHdr);
> -
> -    return STATUS_OK;
> +    return release_buffer(buffer, true);
>  }
>
>
> @@ -1695,7 +1644,7 @@
>  #endif
>
>  #ifdef NOT_USED
> -int
> +Buffer
>  ReleaseAndReadBuffer_Debug(char *file,
>                             int line,
>                             Buffer buffer,
> @@ -2117,7 +2066,7 @@
>  {
>      Assert(buf == InProgressBuf);
>      LWLockRelease(buf->io_in_progress_lock);
> -    InProgressBuf = (BufferDesc *) 0;
> +    InProgressBuf = (BufferDesc *) NULL;
>  }
>
>  /*
> @@ -2142,7 +2091,7 @@
>  void
>  InitBufferIO(void)
>  {
> -    InProgressBuf = (BufferDesc *) 0;
> +    InProgressBuf = (BufferDesc *) NULL;
>  }
>  #endif
>
> diff -ru ../orig/src/include/storage/bufmgr.h src/include/storage/bufmgr.h
> --- ../orig/src/include/storage/bufmgr.h    2002-06-13 09:22:59.000000000 +0200
> +++ src/include/storage/bufmgr.h    2002-06-13 10:57:22.000000000 +0200
> @@ -167,7 +167,9 @@
>  extern void DropRelationBuffers(Relation rel);
>  extern void DropRelFileNodeBuffers(RelFileNode rnode);
>  extern void DropBuffers(Oid dbid);
> +#ifdef NOT_USED
>  extern void PrintPinnedBufs(void);
> +#endif
>  extern int    BufferShmemSize(void);
>  extern RelFileNode BufferGetFileNode(Buffer buffer);
>
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 5: Have you checked our extensive FAQ?
>
> http://www.postgresql.org/users-lounge/docs/faq.html
>

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026



Re: BufMgr cleanup

From
Bruce Momjian
Date:
Patch applied.  Thanks.

---------------------------------------------------------------------------


Manfred Koizar wrote:
> Minor code cleanup in bufmgr.c and bufmgr.h, mainly by moving repeated
> lines of code into internal routines (drop_relfilenode_buffers,
> release_buffer) and by hiding unused routines (PrintBufferDescs,
> PrintPinnedBufs) behind #ifdef NOT_USED.
> Remove AbortBufferIO() declaration from bufmgr.c (already declared
> in bufmgr.h)
>
> diff -ru ../orig/src/backend/storage/buffer/bufmgr.c src/backend/storage/buffer/bufmgr.c
> --- ../orig/src/backend/storage/buffer/bufmgr.c    2002-06-13 09:32:40.000000000 +0200
> +++ src/backend/storage/buffer/bufmgr.c    2002-06-13 11:02:47.000000000 +0200
> @@ -71,7 +71,6 @@
>  static void StartBufferIO(BufferDesc *buf, bool forInput);
>  static void TerminateBufferIO(BufferDesc *buf);
>  static void ContinueBufferIO(BufferDesc *buf, bool forInput);
> -extern void AbortBufferIO(void);
>
>  /*
>   * Macro : BUFFER_IS_BROKEN
> @@ -85,9 +84,14 @@
>              bool *foundPtr);
>  static int    ReleaseBufferWithBufferLock(Buffer buffer);
>  static int    BufferReplace(BufferDesc *bufHdr);
> +#ifdef NOT_USED
>  void        PrintBufferDescs(void);
> +#endif
>
>  static void write_buffer(Buffer buffer, bool unpin);
> +static void drop_relfilenode_buffers(RelFileNode rnode,
> +                                     bool do_local, bool do_both);
> +static int release_buffer(Buffer buffer, bool havelock);
>
>  /*
>   * ReadBuffer -- returns a buffer containing the requested
> @@ -1097,34 +1101,26 @@
>      return relation->rd_nblocks;
>  }
>
> -/* ---------------------------------------------------------------------
> - *        DropRelationBuffers
> - *
> - *        This function removes all the buffered pages for a relation
> - *        from the buffer pool.  Dirty pages are simply dropped, without
> - *        bothering to write them out first.    This is NOT rollback-able,
> - *        and so should be used only with extreme caution!
> - *
> - *        We assume that the caller holds an exclusive lock on the relation,
> - *        which should assure that no new buffers will be acquired for the rel
> - *        meanwhile.
> +/*
> + * drop_relfilenode_buffers -- common functionality for
> + *                             DropRelationBuffers and
> + *                             DropRelFileNodeBuffers
>   *
>   *        XXX currently it sequentially searches the buffer pool, should be
>   *        changed to more clever ways of searching.
> - * --------------------------------------------------------------------
>   */
> -void
> -DropRelationBuffers(Relation rel)
> +static void
> +drop_relfilenode_buffers(RelFileNode rnode, bool do_local, bool do_both)
>  {
>      int            i;
>      BufferDesc *bufHdr;
>
> -    if (rel->rd_myxactonly)
> +    if (do_local)
>      {
>          for (i = 0; i < NLocBuffer; i++)
>          {
>              bufHdr = &LocalBufferDescriptors[i];
> -            if (RelFileNodeEquals(bufHdr->tag.rnode, rel->rd_node))
> +            if (RelFileNodeEquals(bufHdr->tag.rnode, rnode))
>              {
>                  bufHdr->flags &= ~(BM_DIRTY | BM_JUST_DIRTIED);
>                  bufHdr->cntxDirty = false;
> @@ -1132,7 +1128,8 @@
>                  bufHdr->tag.rnode.relNode = InvalidOid;
>              }
>          }
> -        return;
> +        if (!do_both)
> +            return;
>      }
>
>      LWLockAcquire(BufMgrLock, LW_EXCLUSIVE);
> @@ -1141,7 +1138,7 @@
>      {
>          bufHdr = &BufferDescriptors[i - 1];
>  recheck:
> -        if (RelFileNodeEquals(bufHdr->tag.rnode, rel->rd_node))
> +        if (RelFileNodeEquals(bufHdr->tag.rnode, rnode))
>          {
>              /*
>               * If there is I/O in progress, better wait till it's done;
> @@ -1188,6 +1185,25 @@
>  }
>
>  /* ---------------------------------------------------------------------
> + *        DropRelationBuffers
> + *
> + *        This function removes all the buffered pages for a relation
> + *        from the buffer pool.  Dirty pages are simply dropped, without
> + *        bothering to write them out first.    This is NOT rollback-able,
> + *        and so should be used only with extreme caution!
> + *
> + *        We assume that the caller holds an exclusive lock on the relation,
> + *        which should assure that no new buffers will be acquired for the rel
> + *        meanwhile.
> + * --------------------------------------------------------------------
> + */
> +void
> +DropRelationBuffers(Relation rel)
> +{
> +    drop_relfilenode_buffers(rel->rd_node, rel->rd_myxactonly, false);
> +}
> +
> +/* ---------------------------------------------------------------------
>   *        DropRelFileNodeBuffers
>   *
>   *        This is the same as DropRelationBuffers, except that the target
> @@ -1201,73 +1217,8 @@
>  void
>  DropRelFileNodeBuffers(RelFileNode rnode)
>  {
> -    int            i;
> -    BufferDesc *bufHdr;
> -
>      /* We have to search both local and shared buffers... */
> -
> -    for (i = 0; i < NLocBuffer; i++)
> -    {
> -        bufHdr = &LocalBufferDescriptors[i];
> -        if (RelFileNodeEquals(bufHdr->tag.rnode, rnode))
> -        {
> -            bufHdr->flags &= ~(BM_DIRTY | BM_JUST_DIRTIED);
> -            bufHdr->cntxDirty = false;
> -            LocalRefCount[i] = 0;
> -            bufHdr->tag.rnode.relNode = InvalidOid;
> -        }
> -    }
> -
> -    LWLockAcquire(BufMgrLock, LW_EXCLUSIVE);
> -
> -    for (i = 1; i <= NBuffers; i++)
> -    {
> -        bufHdr = &BufferDescriptors[i - 1];
> -recheck:
> -        if (RelFileNodeEquals(bufHdr->tag.rnode, rnode))
> -        {
> -            /*
> -             * If there is I/O in progress, better wait till it's done;
> -             * don't want to delete the relation out from under someone
> -             * who's just trying to flush the buffer!
> -             */
> -            if (bufHdr->flags & BM_IO_IN_PROGRESS)
> -            {
> -                WaitIO(bufHdr);
> -
> -                /*
> -                 * By now, the buffer very possibly belongs to some other
> -                 * rel, so check again before proceeding.
> -                 */
> -                goto recheck;
> -            }
> -            /* Now we can do what we came for */
> -            bufHdr->flags &= ~(BM_DIRTY | BM_JUST_DIRTIED);
> -            bufHdr->cntxDirty = false;
> -
> -            /*
> -             * Release any refcount we may have.
> -             *
> -             * This is very probably dead code, and if it isn't then it's
> -             * probably wrong.    I added the Assert to find out --- tgl
> -             * 11/99.
> -             */
> -            if (!(bufHdr->flags & BM_FREE))
> -            {
> -                /* Assert checks that buffer will actually get freed! */
> -                Assert(PrivateRefCount[i - 1] == 1 &&
> -                       bufHdr->refcount == 1);
> -                ReleaseBufferWithBufferLock(i);
> -            }
> -
> -            /*
> -             * And mark the buffer as no longer occupied by this rel.
> -             */
> -            BufTableDelete(bufHdr);
> -        }
> -    }
> -
> -    LWLockRelease(BufMgrLock);
> +    drop_relfilenode_buffers(rnode, true, true);
>  }
>
>  /* ---------------------------------------------------------------------
> @@ -1343,6 +1294,7 @@
>   *        use only.
>   * -----------------------------------------------------------------
>   */
> +#ifdef NOT_USED
>  void
>  PrintBufferDescs()
>  {
> @@ -1375,7 +1327,9 @@
>          }
>      }
>  }
> +#endif
>
> +#ifdef NOT_USED
>  void
>  PrintPinnedBufs()
>  {
> @@ -1395,6 +1349,7 @@
>      }
>      LWLockRelease(BufMgrLock);
>  }
> +#endif
>
>  /*
>   * BufferPoolBlowaway
> @@ -1589,14 +1544,12 @@
>      return 0;
>  }
>
> -#undef ReleaseBuffer
> -
>  /*
> - * ReleaseBuffer -- remove the pin on a buffer without
> - *        marking it dirty.
> + * release_buffer -- common functionality for
> + *                   ReleaseBuffer and ReleaseBufferWithBufferLock
>   */
> -int
> -ReleaseBuffer(Buffer buffer)
> +static int
> +release_buffer(Buffer buffer, bool havelock)
>  {
>      BufferDesc *bufHdr;
>
> @@ -1617,14 +1570,30 @@
>          PrivateRefCount[buffer - 1]--;
>      else
>      {
> -        LWLockAcquire(BufMgrLock, LW_EXCLUSIVE);
> +        if (!havelock)
> +            LWLockAcquire(BufMgrLock, LW_EXCLUSIVE);
> +
>          UnpinBuffer(bufHdr);
> -        LWLockRelease(BufMgrLock);
> +
> +        if (!havelock)
> +            LWLockRelease(BufMgrLock);
>      }
>
>      return STATUS_OK;
>  }
>
> +#undef ReleaseBuffer
> +
> +/*
> + * ReleaseBuffer -- remove the pin on a buffer without
> + *        marking it dirty.
> + */
> +int
> +ReleaseBuffer(Buffer buffer)
> +{
> +    return release_buffer(buffer, false);
> +}
> +
>  /*
>   * ReleaseBufferWithBufferLock
>   *        Same as ReleaseBuffer except we hold the bufmgr lock
> @@ -1632,27 +1601,7 @@
>  static int
>  ReleaseBufferWithBufferLock(Buffer buffer)
>  {
> -    BufferDesc *bufHdr;
> -
> -    if (BufferIsLocal(buffer))
> -    {
> -        Assert(LocalRefCount[-buffer - 1] > 0);
> -        LocalRefCount[-buffer - 1]--;
> -        return STATUS_OK;
> -    }
> -
> -    if (BAD_BUFFER_ID(buffer))
> -        return STATUS_ERROR;
> -
> -    bufHdr = &BufferDescriptors[buffer - 1];
> -
> -    Assert(PrivateRefCount[buffer - 1] > 0);
> -    if (PrivateRefCount[buffer - 1] > 1)
> -        PrivateRefCount[buffer - 1]--;
> -    else
> -        UnpinBuffer(bufHdr);
> -
> -    return STATUS_OK;
> +    return release_buffer(buffer, true);
>  }
>
>
> @@ -1695,7 +1644,7 @@
>  #endif
>
>  #ifdef NOT_USED
> -int
> +Buffer
>  ReleaseAndReadBuffer_Debug(char *file,
>                             int line,
>                             Buffer buffer,
> @@ -2117,7 +2066,7 @@
>  {
>      Assert(buf == InProgressBuf);
>      LWLockRelease(buf->io_in_progress_lock);
> -    InProgressBuf = (BufferDesc *) 0;
> +    InProgressBuf = (BufferDesc *) NULL;
>  }
>
>  /*
> @@ -2142,7 +2091,7 @@
>  void
>  InitBufferIO(void)
>  {
> -    InProgressBuf = (BufferDesc *) 0;
> +    InProgressBuf = (BufferDesc *) NULL;
>  }
>  #endif
>
> diff -ru ../orig/src/include/storage/bufmgr.h src/include/storage/bufmgr.h
> --- ../orig/src/include/storage/bufmgr.h    2002-06-13 09:22:59.000000000 +0200
> +++ src/include/storage/bufmgr.h    2002-06-13 10:57:22.000000000 +0200
> @@ -167,7 +167,9 @@
>  extern void DropRelationBuffers(Relation rel);
>  extern void DropRelFileNodeBuffers(RelFileNode rnode);
>  extern void DropBuffers(Oid dbid);
> +#ifdef NOT_USED
>  extern void PrintPinnedBufs(void);
> +#endif
>  extern int    BufferShmemSize(void);
>  extern RelFileNode BufferGetFileNode(Buffer buffer);
>
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 5: Have you checked our extensive FAQ?
>
> http://www.postgresql.org/users-lounge/docs/faq.html
>

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026