Remove unnecessary calls of FlushRelationBuffers: there is no need
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 20 Mar 2005 22:00:54 +0000 (22:00 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 20 Mar 2005 22:00:54 +0000 (22:00 +0000)
to write out data that we are about to tell the filesystem to drop.
smgr_internal_unlink already had a DropRelFileNodeBuffers call to
get rid of dead buffers without a write after it's no longer possible
to roll back the deleting transaction.  Adding a similar call in
smgrtruncate simplifies callers and makes the overall division of
labor clearer.  This patch removes the former behavior that VACUUM
would write all dirty buffers of a relation unconditionally.

src/backend/access/nbtree/nbtree.c
src/backend/catalog/heap.c
src/backend/catalog/index.c
src/backend/commands/cluster.c
src/backend/commands/tablecmds.c
src/backend/commands/vacuum.c
src/backend/commands/vacuumlazy.c
src/backend/storage/buffer/bufmgr.c
src/backend/storage/smgr/smgr.c
src/include/storage/bufmgr.h

index ba31abcbbfdf013b32f2cc05d078d3e100afe960..8f6fe7d27ccc3cb72725cdac3f9e18ce0b68edb6 100644 (file)
@@ -12,7 +12,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.124 2004/12/31 21:59:22 pgsql Exp $
+ *   $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.125 2005/03/20 22:00:50 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -772,17 +772,6 @@ btvacuumcleanup(PG_FUNCTION_ARGS)
        {
            /*
             * Okay to truncate.
-            *
-            * First, flush any shared buffers for the blocks we intend to
-            * delete.  FlushRelationBuffers is a bit more than we need
-            * for this, since it will also write out dirty buffers for
-            * blocks we aren't deleting, but it's the closest thing in
-            * bufmgr's API.
-            */
-           FlushRelationBuffers(rel, new_pages);
-
-           /*
-            * Do the physical truncation.
             */
            RelationTruncate(rel, new_pages);
 
index 2bf73a5984e276630aadc85d1f4bbce52efa3d1d..0616eab58952c91e1d0131d9b8141ea2c58a7490 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.280 2005/01/27 03:17:17 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.281 2005/03/20 22:00:51 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -1174,12 +1174,6 @@ heap_drop_with_catalog(Oid relid)
     */
    rel = relation_open(relid, AccessExclusiveLock);
 
-   /*
-    * Release all buffers that belong to this relation, after writing any
-    * that are dirty
-    */
-   FlushRelationBuffers(rel, (BlockNumber) 0);
-
    /*
     * Schedule unlinking of the relation's physical file at commit.
     */
@@ -1958,13 +1952,7 @@ RelationTruncateIndexes(Oid heapId)
        /* Fetch info needed for index_build */
        indexInfo = BuildIndexInfo(currentIndex);
 
-       /*
-        * Drop any buffers associated with this index. If they're dirty,
-        * they're just dropped without bothering to flush to disk.
-        */
-       DropRelationBuffers(currentIndex);
-
-       /* Now truncate the actual data */
+       /* Now truncate the actual file (and discard buffers) */
        RelationTruncate(currentIndex, 0);
 
        /* Initialize the index and rebuild */
@@ -2024,13 +2012,7 @@ heap_truncate(List *relids)
    {
        Relation    rel = lfirst(cell);
 
-       /*
-        * Release any buffers associated with this relation.  If they're
-        * dirty, they're just dropped without bothering to flush to disk.
-        */
-       DropRelationBuffers(rel);
-
-       /* Now truncate the actual data */
+       /* Truncate the actual file (and discard buffers) */
        RelationTruncate(rel, 0);
 
        /* If this relation has indexes, truncate the indexes too */
index 48c8fb072f23ed0e2d58edff40b3d96dfbc9b063..3ea8a99f8f45c518dba17279adb7efb2c6f10052 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.247 2005/03/16 21:38:04 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.248 2005/03/20 22:00:51 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -775,10 +775,8 @@ index_drop(Oid indexId)
    LockRelation(userIndexRelation, AccessExclusiveLock);
 
    /*
-    * flush buffer cache and schedule physical removal of the file
+    * Schedule physical removal of the file
     */
-   FlushRelationBuffers(userIndexRelation, (BlockNumber) 0);
-
    RelationOpenSmgr(userIndexRelation);
    smgrscheduleunlink(userIndexRelation->rd_smgr,
                       userIndexRelation->rd_istemp);
@@ -1617,14 +1615,7 @@ reindex_index(Oid indexId)
 
        if (inplace)
        {
-           /*
-            * Release any buffers associated with this index.  If they're
-            * dirty, they're just dropped without bothering to flush to
-            * disk.
-            */
-           DropRelationBuffers(iRel);
-
-           /* Now truncate the actual data */
+           /* Truncate the actual file (and discard buffers) */
            RelationTruncate(iRel, 0);
        }
        else
index 17fcbb3afba01cc51d3bbb8d51012dc4d2844c3f..e9f364fa9aaf83828ec1f5d93ebe2479607721be 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.132 2005/02/06 20:19:08 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.133 2005/03/20 22:00:52 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -709,8 +709,7 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex)
 void
 swap_relation_files(Oid r1, Oid r2)
 {
-   Relation    relRelation,
-               rel;
+   Relation    relRelation;
    HeapTuple   reltup1,
                reltup2;
    Form_pg_class relform1,
@@ -735,20 +734,6 @@ swap_relation_files(Oid r1, Oid r2)
        elog(ERROR, "cache lookup failed for relation %u", r2);
    relform2 = (Form_pg_class) GETSTRUCT(reltup2);
 
-   /*
-    * The buffer manager gets confused if we swap relfilenodes for
-    * relations that are not both local or non-local to this transaction.
-    * Flush the buffers on both relations so the buffer manager can
-    * forget about'em.  (XXX this might not be necessary anymore?)
-    */
-   rel = relation_open(r1, NoLock);
-   FlushRelationBuffers(rel, 0);
-   relation_close(rel, NoLock);
-
-   rel = relation_open(r2, NoLock);
-   FlushRelationBuffers(rel, 0);
-   relation_close(rel, NoLock);
-
    /*
     * Actually swap the fields in the two tuples
     */
index 819ac84e1e8e0f2ab7a30cb7166afa066924e77a..0b11976db848aa9ffd067847c8e5439f8245ca92 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.147 2005/03/16 21:38:05 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.148 2005/03/20 22:00:52 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -5628,13 +5628,12 @@ copy_relation_data(Relation rel, SMgrRelation dst)
    Page        page = (Page) buf;
 
    /*
-    * Since we copy the data directly without looking at the shared
+    * Since we copy the file directly without looking at the shared
     * buffers, we'd better first flush out any pages of the source
-    * relation that are in shared buffers.  We assume no new pages will
-    * get loaded into buffers while we are holding exclusive lock on the
-    * rel.
+    * relation that are in shared buffers.  We assume no new changes
+    * will be made while we are holding exclusive lock on the rel.
     */
-   FlushRelationBuffers(rel, 0);
+   FlushRelationBuffers(rel);
 
    /*
     * We need to log the copied data in WAL iff WAL archiving is enabled
index a0ee3e8f355459743a2506bc45f9a2a796f01197..b2b39c5a58c03d81b1e090a7fee65ac8cb39b008 100644 (file)
@@ -13,7 +13,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.304 2005/03/16 21:38:05 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.305 2005/03/20 22:00:52 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1138,16 +1138,6 @@ full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt)
            /* Clean pages from vacuum_pages list */
            vacuum_heap(vacrelstats, onerel, &vacuum_pages);
        }
-       else
-       {
-           /*
-            * Flush dirty pages out to disk.  We must do this even if we
-            * didn't do anything else, because we want to ensure that all
-            * tuples have correct on-row commit status on disk (see
-            * bufmgr.c's comments for FlushRelationBuffers()).
-            */
-           FlushRelationBuffers(onerel, vacrelstats->rel_pages);
-       }
    }
 
    /* update shared free space map with final free space info */
@@ -2420,15 +2410,7 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
        pfree(Nvacpagelist.pagedesc);
    }
 
-   /*
-    * Flush dirty pages out to disk.  We do this unconditionally, even if
-    * we don't need to truncate, because we want to ensure that all
-    * tuples have correct on-row commit status on disk (see bufmgr.c's
-    * comments for FlushRelationBuffers()).
-    */
-   FlushRelationBuffers(onerel, blkno);
-
-   /* truncate relation, if needed */
+   /* Truncate relation, if needed */
    if (blkno < nblocks)
    {
        RelationTruncate(onerel, blkno);
@@ -2818,27 +2800,17 @@ vacuum_heap(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages)
        }
    }
 
-   /*
-    * Flush dirty pages out to disk.  We do this unconditionally, even if
-    * we don't need to truncate, because we want to ensure that all
-    * tuples have correct on-row commit status on disk (see bufmgr.c's
-    * comments for FlushRelationBuffers()).
-    */
+   /* Truncate relation if there are some empty end-pages */
    Assert(vacrelstats->rel_pages >= vacuum_pages->empty_end_pages);
-   relblocks = vacrelstats->rel_pages - vacuum_pages->empty_end_pages;
-
-   FlushRelationBuffers(onerel, relblocks);
-
-   /* truncate relation if there are some empty end-pages */
    if (vacuum_pages->empty_end_pages > 0)
    {
+       relblocks = vacrelstats->rel_pages - vacuum_pages->empty_end_pages;
        ereport(elevel,
                (errmsg("\"%s\": truncated %u to %u pages",
                        RelationGetRelationName(onerel),
                        vacrelstats->rel_pages, relblocks)));
        RelationTruncate(onerel, relblocks);
-       vacrelstats->rel_pages = relblocks;     /* set new number of
-                                                * blocks */
+       vacrelstats->rel_pages = relblocks;     /* set new number of blocks */
    }
 }
 
index 0e5b204fc2af9a7ec1f783d4c3f16c8830ec4c5d..bc12f1150708d6433eb10df314553c0303104add 100644 (file)
@@ -31,7 +31,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.50 2004/12/31 21:59:42 pgsql Exp $
+ *   $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.51 2005/03/20 22:00:52 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -773,16 +773,6 @@ lazy_truncate_heap(Relation onerel, LVRelStats *vacrelstats)
 
    /*
     * Okay to truncate.
-    *
-    * First, flush any shared buffers for the blocks we intend to delete.
-    * FlushRelationBuffers is a bit more than we need for this, since it
-    * will also write out dirty buffers for blocks we aren't deleting,
-    * but it's the closest thing in bufmgr's API.
-    */
-   FlushRelationBuffers(onerel, new_rel_pages);
-
-   /*
-    * Do the physical truncation.
     */
    RelationTruncate(onerel, new_rel_pages);
 
index bda4544b279c733d1f418dfce5212ca512182f82..e3a60612e3010c2f13bcdf971a49d8671f722fa2 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.187 2005/03/18 05:25:23 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.188 2005/03/20 22:00:53 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1298,8 +1298,8 @@ RelationGetNumberOfBlocks(Relation relation)
  * RelationTruncate
  *     Physically truncate a relation to the specified number of blocks.
  *
- * Caller should already have done something to flush any buffered pages
- * that are to be dropped.
+ * As of Postgres 8.1, this includes getting rid of any buffers for the
+ * blocks that are to be dropped; previously, callers had to do that.
  */
 void
 RelationTruncate(Relation rel, BlockNumber nblocks)
@@ -1314,38 +1314,30 @@ RelationTruncate(Relation rel, BlockNumber nblocks)
    smgrtruncate(rel->rd_smgr, nblocks, rel->rd_istemp);
 }
 
-/* ---------------------------------------------------------------------
- *     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!
- *
- *     There is no particularly good reason why this doesn't have a
- *     firstDelBlock parameter, except that current callers don't need it.
- *
- *     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)
-{
-   DropRelFileNodeBuffers(rel->rd_node, rel->rd_istemp, 0);
-}
-
 /* ---------------------------------------------------------------------
  *     DropRelFileNodeBuffers
  *
- *     This is the same as DropRelationBuffers, except that the target
- *     relation is specified by RelFileNode and temp status, and one
- *     may specify the first block to drop.
+ *     This function removes from the buffer pool all the pages of the
+ *     specified relation that have block numbers >= firstDelBlock.
+ *     (In particular, with firstDelBlock = 0, all pages are removed.)
+ *     Dirty pages are simply dropped, without bothering to write them
+ *     out first.  Therefore, this is NOT rollback-able, and so should be
+ *     used only with extreme caution!
+ *
+ *     Currently, this is called only from smgr.c when the underlying file
+ *     is about to be deleted or truncated (firstDelBlock is needed for
+ *     the truncation case).  The data in the affected pages would therefore
+ *     be deleted momentarily anyway, and there is no point in writing it.
+ *     It is the responsibility of higher-level code to ensure that the
+ *     deletion or truncation does not lose any data that could be needed
+ *     later.  It is also the responsibility of higher-level code to ensure
+ *     that no other process could be trying to load more pages of the
+ *     relation into buffers.
  *
- *     This is NOT rollback-able.  One legitimate use is to clear the
- *     buffer cache of buffers for a relation that is being deleted
- *     during transaction abort.
+ *     XXX currently it sequentially searches the buffer pool, should be
+ *     changed to more clever ways of searching.  However, this routine
+ *     is used only in code paths that aren't very performance-critical,
+ *     and we shouldn't slow down the hot paths to make it faster ...
  * --------------------------------------------------------------------
  */
 void
@@ -1398,7 +1390,7 @@ DropRelFileNodeBuffers(RelFileNode rnode, bool istemp,
  *     bothering to write them out first.  This is used when we destroy a
  *     database, to avoid trying to flush data to disk when the directory
  *     tree no longer exists.  Implementation is pretty similar to
- *     DropRelationBuffers() which is for destroying just one relation.
+ *     DropRelFileNodeBuffers() which is for destroying just one relation.
  * --------------------------------------------------------------------
  */
 void
@@ -1480,44 +1472,24 @@ PrintPinnedBufs(void)
 /* ---------------------------------------------------------------------
  *     FlushRelationBuffers
  *
- *     This function writes all dirty pages of a relation out to disk.
- *     Furthermore, pages that have blocknumber >= firstDelBlock are
- *     actually removed from the buffer pool.
- *
- *     This is called by DROP TABLE to clear buffers for the relation
- *     from the buffer pool.  Note that we must write dirty buffers,
- *     rather than just dropping the changes, because our transaction
- *     might abort later on; we want to roll back safely in that case.
- *
- *     This is also called by VACUUM before truncating the relation to the
- *     given number of blocks.  It might seem unnecessary for VACUUM to
- *     write dirty pages before firstDelBlock, since VACUUM should already
- *     have committed its changes.  However, it is possible for there still
- *     to be dirty pages: if some page had unwritten on-row tuple status
- *     updates from a prior transaction, and VACUUM had no additional
- *     changes to make to that page, then VACUUM won't have written it.
- *     This is harmless in most cases but will break pg_upgrade, which
- *     relies on VACUUM to ensure that *all* tuples have correct on-row
- *     status.  So, we check and flush all dirty pages of the rel
- *     regardless of block number.
- *
- *     In all cases, the caller should be holding AccessExclusiveLock on
- *     the target relation to ensure that no other backend is busy reading
- *     more blocks of the relation (or might do so before we commit).
- *     This should also ensure that no one is busy dirtying these blocks.
- *
- *     Formerly, we considered it an error condition if we found dirty
- *     buffers here.   However, since BufferSync no longer forces out all
- *     dirty buffers at every xact commit, it's possible for dirty buffers
- *     to still be present in the cache due to failure of an earlier
- *     transaction.  So, must flush dirty buffers without complaint.
+ *     This function writes all dirty pages of a relation out to disk
+ *     (or more accurately, out to kernel disk buffers), ensuring that the
+ *     kernel has an up-to-date view of the relation.
+ *
+ *     Generally, the caller should be holding AccessExclusiveLock on the
+ *     target relation to ensure that no other backend is busy dirtying
+ *     more blocks of the relation; the effects can't be expected to last
+ *     after the lock is released.
  *
  *     XXX currently it sequentially searches the buffer pool, should be
- *     changed to more clever ways of searching.
+ *     changed to more clever ways of searching.  This routine is not
+ *     used in any performance-critical code paths, so it's not worth
+ *     adding additional overhead to normal paths to make it go faster;
+ *     but see also DropRelFileNodeBuffers.
  * --------------------------------------------------------------------
  */
 void
-FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock)
+FlushRelationBuffers(Relation rel)
 {
    int         i;
    BufferDesc *bufHdr;
@@ -1530,38 +1502,26 @@ FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock)
        for (i = 0; i < NLocBuffer; i++)
        {
            bufHdr = &LocalBufferDescriptors[i];
-           if (RelFileNodeEquals(bufHdr->tag.rnode, rel->rd_node))
+           if (RelFileNodeEquals(bufHdr->tag.rnode, rel->rd_node) &&
+               (bufHdr->flags & BM_VALID) && (bufHdr->flags & BM_DIRTY))
            {
-               if ((bufHdr->flags & BM_VALID) && (bufHdr->flags & BM_DIRTY))
-               {
-                   ErrorContextCallback errcontext;
+               ErrorContextCallback errcontext;
 
-                   /* Setup error traceback support for ereport() */
-                   errcontext.callback = buffer_write_error_callback;
-                   errcontext.arg = bufHdr;
-                   errcontext.previous = error_context_stack;
-                   error_context_stack = &errcontext;
+               /* Setup error traceback support for ereport() */
+               errcontext.callback = buffer_write_error_callback;
+               errcontext.arg = bufHdr;
+               errcontext.previous = error_context_stack;
+               error_context_stack = &errcontext;
 
-                   smgrwrite(rel->rd_smgr,
-                             bufHdr->tag.blockNum,
-                             (char *) LocalBufHdrGetBlock(bufHdr),
-                             true);
+               smgrwrite(rel->rd_smgr,
+                         bufHdr->tag.blockNum,
+                         (char *) LocalBufHdrGetBlock(bufHdr),
+                         true);
 
-                   bufHdr->flags &= ~(BM_DIRTY | BM_JUST_DIRTIED);
+               bufHdr->flags &= ~(BM_DIRTY | BM_JUST_DIRTIED);
 
-                   /* Pop the error context stack */
-                   error_context_stack = errcontext.previous;
-               }
-               if (LocalRefCount[i] > 0)
-                   elog(ERROR, "FlushRelationBuffers(\"%s\" (local), %u): block %u is referenced (%d)",
-                        RelationGetRelationName(rel), firstDelBlock,
-                        bufHdr->tag.blockNum, LocalRefCount[i]);
-               if (bufHdr->tag.blockNum >= firstDelBlock)
-               {
-                   CLEAR_BUFFERTAG(bufHdr->tag);
-                   bufHdr->flags = 0;
-                   bufHdr->usage_count = 0;
-               }
+               /* Pop the error context stack */
+               error_context_stack = errcontext.previous;
            }
        }
 
@@ -1574,33 +1534,15 @@ FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock)
    for (i = 0; i < NBuffers; i++)
    {
        bufHdr = &BufferDescriptors[i];
-   recheck:
        LockBufHdr(bufHdr);
-       if (RelFileNodeEquals(bufHdr->tag.rnode, rel->rd_node))
+       if (RelFileNodeEquals(bufHdr->tag.rnode, rel->rd_node) &&
+           (bufHdr->flags & BM_VALID) && (bufHdr->flags & BM_DIRTY))
        {
-           if ((bufHdr->flags & BM_VALID) && (bufHdr->flags & BM_DIRTY))
-           {
-               PinBuffer_Locked(bufHdr);
-               LWLockAcquire(bufHdr->content_lock, LW_SHARED);
-               FlushBuffer(bufHdr, rel->rd_smgr);
-               LWLockRelease(bufHdr->content_lock);
-               UnpinBuffer(bufHdr, true, false /* no freelist change */ );
-               /*
-                * As soon as we unpin, it's possible for someone to take
-                * the buffer away from us; so loop back to re-lock and
-                * re-check if it still belongs to the target relation.
-                */
-               goto recheck;
-           }
-           /*
-            * Even though it's not dirty, it could still be pinned because
-            * TerminateIO and UnpinBuffer are separate actions.  Hence,
-            * we can't error out on nonzero reference count here.
-            */
-           if (bufHdr->tag.blockNum >= firstDelBlock)
-               InvalidateBuffer(bufHdr);       /* releases spinlock */
-           else
-               UnlockBufHdr(bufHdr);
+           PinBuffer_Locked(bufHdr);
+           LWLockAcquire(bufHdr->content_lock, LW_SHARED);
+           FlushBuffer(bufHdr, rel->rd_smgr);
+           LWLockRelease(bufHdr->content_lock);
+           UnpinBuffer(bufHdr, true, false /* no freelist change */ );
        }
        else
            UnlockBufHdr(bufHdr);
index 0c88bbfcc7f9e299a07ea0f700827f03381da2e2..5abfc6d47741b97c6fe5f09e3ace0a422caa5847 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/storage/smgr/smgr.c,v 1.85 2005/01/10 20:02:22 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/storage/smgr/smgr.c,v 1.86 2005/03/20 22:00:53 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -461,8 +461,8 @@ static void
 smgr_internal_unlink(RelFileNode rnode, int which, bool isTemp, bool isRedo)
 {
    /*
-    * Get rid of any leftover buffers for the rel (shouldn't be any in
-    * the commit case, but there can be in the abort case).
+    * Get rid of any remaining buffers for the relation.  bufmgr will just
+    * drop them without bothering to write the contents.
     */
    DropRelFileNodeBuffers(rnode, isTemp, 0);
 
@@ -599,6 +599,12 @@ smgrtruncate(SMgrRelation reln, BlockNumber nblocks, bool isTemp)
 {
    BlockNumber newblks;
 
+   /*
+    * Get rid of any buffers for the about-to-be-deleted blocks.
+    * bufmgr will just drop them without bothering to write the contents.
+    */
+   DropRelFileNodeBuffers(reln->smgr_rnode, isTemp, nblocks);
+
    /*
     * Tell the free space map to forget anything it may have stored for
     * the about-to-be-deleted blocks.  We want to be sure it won't return
@@ -873,6 +879,8 @@ smgr_redo(XLogRecPtr lsn, XLogRecord *record)
 
        reln = smgropen(xlrec->rnode);
 
+       /* Can't use smgrtruncate because it would try to xlog */
+
        /*
         * First, force bufmgr to drop any buffers it has for the to-be-
         * truncated blocks.  We must do this, else subsequent
@@ -880,8 +888,6 @@ smgr_redo(XLogRecPtr lsn, XLogRecord *record)
         */
        DropRelFileNodeBuffers(xlrec->rnode, false, xlrec->blkno);
 
-       /* Can't use smgrtruncate because it would try to xlog */
-
        /*
         * Tell the free space map to forget anything it may have stored
         * for the about-to-be-deleted blocks.  We want to be sure it
index b8bf0f978a72748c2057ec46a42c8b4875238534..b77c3cc4675e7478c944380f4f965b10e81971ee 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/storage/bufmgr.h,v 1.92 2005/03/19 23:27:10 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/storage/bufmgr.h,v 1.93 2005/03/20 22:00:54 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -132,8 +132,7 @@ extern void FlushBufferPool(void);
 extern BlockNumber BufferGetBlockNumber(Buffer buffer);
 extern BlockNumber RelationGetNumberOfBlocks(Relation relation);
 extern void RelationTruncate(Relation rel, BlockNumber nblocks);
-extern void FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock);
-extern void DropRelationBuffers(Relation rel);
+extern void FlushRelationBuffers(Relation rel);
 extern void DropRelFileNodeBuffers(RelFileNode rnode, bool istemp,
                       BlockNumber firstDelBlock);
 extern void DropBuffers(Oid dbid);