]> granicus.if.org Git - postgresql/commitdiff
Get rid of rd_nblocks field in relcache entries. Turns out this was
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 8 May 2004 19:09:25 +0000 (19:09 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 8 May 2004 19:09:25 +0000 (19:09 +0000)
costing us lots more to maintain than it was worth.  On shared tables
it was of exactly zero benefit because we couldn't trust it to be
up to date.  On temp tables it sometimes saved an lseek, but not often
enough to be worth getting excited about.  And the real problem was that
we forced an lseek on every relcache flush in order to update the field.
So all in all it seems best to lose the complexity.

14 files changed:
contrib/pgstattuple/pgstattuple.c
src/backend/access/heap/heapam.c
src/backend/access/nbtree/nbtree.c
src/backend/catalog/heap.c
src/backend/catalog/index.c
src/backend/commands/analyze.c
src/backend/commands/sequence.c
src/backend/commands/vacuum.c
src/backend/commands/vacuumlazy.c
src/backend/storage/buffer/bufmgr.c
src/backend/utils/cache/relcache.c
src/include/access/relscan.h
src/include/storage/bufmgr.h
src/include/utils/rel.h

index ca082618568d182b6f178a4cf53daf4e81415868..98b4cc3d519ae1208aa85e5302aa397eba9632e7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $PostgreSQL: pgsql/contrib/pgstattuple/pgstattuple.c,v 1.14 2004/04/01 21:28:43 tgl Exp $
+ * $PostgreSQL: pgsql/contrib/pgstattuple/pgstattuple.c,v 1.15 2004/05/08 19:09:24 tgl Exp $
  *
  * Copyright (c) 2001,2002     Tatsuo Ishii
  *
@@ -127,9 +127,10 @@ pgstattuple_real(Relation rel)
         */
        attinmeta = TupleDescGetAttInMetadata(tupdesc);
 
-       nblocks = RelationGetNumberOfBlocks(rel);
        scan = heap_beginscan(rel, SnapshotAny, 0, NULL);
 
+       nblocks = scan->rs_nblocks;     /* # blocks to be scanned */
+
        /* scan the relation */
        while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
        {
index bff84588fc20b2a173fb251f4ba3a52d13857683..894980b41e625e12b17b18e364f2f80d20bd777a 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.165 2004/04/21 18:24:23 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.166 2004/05/08 19:09:24 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -73,12 +73,13 @@ static void
 initscan(HeapScanDesc scan, ScanKey key)
 {
        /*
-        * Make sure we have up-to-date idea of number of blocks in relation.
+        * Determine the number of blocks we have to scan.
+        *
         * It is sufficient to do this once at scan start, since any tuples
         * added while the scan is in progress will be invisible to my
         * transaction anyway...
         */
-       scan->rs_rd->rd_nblocks = RelationGetNumberOfBlocks(scan->rs_rd);
+       scan->rs_nblocks = RelationGetNumberOfBlocks(scan->rs_rd);
 
        scan->rs_ctup.t_datamcxt = NULL;
        scan->rs_ctup.t_data = NULL;
@@ -113,12 +114,12 @@ heapgettup(Relation relation,
                   Buffer *buffer,
                   Snapshot snapshot,
                   int nkeys,
-                  ScanKey key)
+                  ScanKey key,
+                  BlockNumber pages)
 {
        ItemId          lpp;
        Page            dp;
        BlockNumber page;
-       BlockNumber pages;
        int                     lines;
        OffsetNumber lineoff;
        int                     linesleft;
@@ -159,7 +160,7 @@ heapgettup(Relation relation,
        /*
         * return null immediately if relation is empty
         */
-       if ((pages = relation->rd_nblocks) == 0)
+       if (pages == 0)
        {
                if (BufferIsValid(*buffer))
                        ReleaseBuffer(*buffer);
@@ -832,7 +833,8 @@ heap_getnext(HeapScanDesc scan, ScanDirection direction)
                           &(scan->rs_cbuf),
                           scan->rs_snapshot,
                           scan->rs_nkeys,
-                          scan->rs_key);
+                          scan->rs_key,
+                          scan->rs_nblocks);
 
        if (scan->rs_ctup.t_data == NULL && !BufferIsValid(scan->rs_cbuf))
        {
@@ -1992,7 +1994,8 @@ heap_restrpos(HeapScanDesc scan)
                                   &(scan->rs_cbuf),
                                   scan->rs_snapshot,
                                   0,
-                                  NULL);
+                                  NULL,
+                                  scan->rs_nblocks);
        }
 }
 
index 57074a036333e398512d75a61b90a533d3ac809f..ededa6231de3bc97d9c61db3d8819d63185f4fb3 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.114 2004/04/21 18:24:26 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.115 2004/05/08 19:09:24 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -802,12 +802,7 @@ btvacuumcleanup(PG_FUNCTION_ARGS)
                        /*
                         * Do the physical truncation.
                         */
-                       if (rel->rd_smgr == NULL)
-                               rel->rd_smgr = smgropen(rel->rd_node);
-                       new_pages = smgrtruncate(rel->rd_smgr, new_pages);
-                       rel->rd_nblocks = new_pages;            /* update relcache
-                                                                                                * immediately */
-                       rel->rd_targblock = InvalidBlockNumber;
+                       RelationTruncate(rel, new_pages);
                        num_pages = new_pages;
                }
        }
index 51b7d31772aff88853ca9a49564809a55dc8262d..94f1fd2a13d2570c1fb5787947e9162f0a254046 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.263 2004/05/05 04:48:45 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.264 2004/05/08 19:09:24 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -1979,12 +1979,8 @@ RelationTruncateIndexes(Oid heapId)
                 */
                DropRelationBuffers(currentIndex);
 
-               /* Now truncate the actual data and set blocks to zero */
-               if (currentIndex->rd_smgr == NULL)
-                       currentIndex->rd_smgr = smgropen(currentIndex->rd_node);
-               smgrtruncate(currentIndex->rd_smgr, 0);
-               currentIndex->rd_nblocks = 0;
-               currentIndex->rd_targblock = InvalidBlockNumber;
+               /* Now truncate the actual data */
+               RelationTruncate(currentIndex, 0);
 
                /* Initialize the index and rebuild */
                index_build(heapRelation, currentIndex, indexInfo);
@@ -2028,12 +2024,8 @@ heap_truncate(Oid rid)
         */
        DropRelationBuffers(rel);
 
-       /* Now truncate the actual data and set blocks to zero */
-       if (rel->rd_smgr == NULL)
-               rel->rd_smgr = smgropen(rel->rd_node);
-       smgrtruncate(rel->rd_smgr, 0);
-       rel->rd_nblocks = 0;
-       rel->rd_targblock = InvalidBlockNumber;
+       /* Now truncate the actual data */
+       RelationTruncate(rel, 0);
 
        /* If this relation has indexes, truncate the indexes too */
        RelationTruncateIndexes(rid);
index 6a994aa0cccac8b3b17b5f374b6a9090a03575ea..d6d38795df8049bc8e481e556304a28860a92883 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.230 2004/05/08 00:34:49 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.231 2004/05/08 19:09:24 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -1702,12 +1702,8 @@ reindex_index(Oid indexId)
                 */
                DropRelationBuffers(iRel);
 
-               /* Now truncate the actual data and set blocks to zero */
-               if (iRel->rd_smgr == NULL)
-                       iRel->rd_smgr = smgropen(iRel->rd_node);
-               smgrtruncate(iRel->rd_smgr, 0);
-               iRel->rd_nblocks = 0;
-               iRel->rd_targblock = InvalidBlockNumber;
+               /* Now truncate the actual data */
+               RelationTruncate(iRel, 0);
        }
        else
        {
index bd82a96b65076c20f43ed192d5c3249175a2034b..d388f521f183383e53b07c0a9d0a9e8f45003f58 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.70 2004/02/15 21:01:39 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.71 2004/05/08 19:09:24 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -388,7 +388,7 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
 
        /*
         * If we are running a standalone ANALYZE, update pages/tuples stats
-        * in pg_class.  We have the accurate page count from heap_beginscan,
+        * in pg_class.  We know the accurate page count from the smgr,
         * but only an approximate number of tuples; therefore, if we are part
         * of VACUUM ANALYZE do *not* overwrite the accurate count already
         * inserted by VACUUM.  The same consideration applies to indexes.
@@ -396,7 +396,7 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
        if (!vacstmt->vacuum)
        {
                vac_update_relstats(RelationGetRelid(onerel),
-                                                       onerel->rd_nblocks,
+                                                       RelationGetNumberOfBlocks(onerel),
                                                        totalrows,
                                                        hasindex);
                for (ind = 0; ind < nindexes; ind++)
@@ -657,6 +657,7 @@ acquire_sample_rows(Relation onerel, HeapTuple *rows, int targrows,
 {
        int                     numrows = 0;
        HeapScanDesc scan;
+       BlockNumber     totalblocks;
        HeapTuple       tuple;
        ItemPointer lasttuple;
        BlockNumber lastblock,
@@ -673,6 +674,7 @@ acquire_sample_rows(Relation onerel, HeapTuple *rows, int targrows,
         * Do a simple linear scan until we reach the target number of rows.
         */
        scan = heap_beginscan(onerel, SnapshotNow, 0, NULL);
+       totalblocks = scan->rs_nblocks; /* grab current relation size */
        while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
        {
                rows[numrows++] = heap_copytuple(tuple);
@@ -693,7 +695,7 @@ acquire_sample_rows(Relation onerel, HeapTuple *rows, int targrows,
                ereport(elevel,
                                (errmsg("\"%s\": %u pages, %d rows sampled, %.0f estimated total rows",
                                                RelationGetRelationName(onerel),
-                                               onerel->rd_nblocks, numrows, *totalrows)));
+                                               totalblocks, numrows, *totalrows)));
 
                return numrows;
        }
@@ -772,10 +774,9 @@ acquire_sample_rows(Relation onerel, HeapTuple *rows, int targrows,
 pageloop:;
 
                /*
-                * Have we fallen off the end of the relation?  (We rely on
-                * heap_beginscan to have updated rd_nblocks.)
+                * Have we fallen off the end of the relation?
                 */
-               if (targblock >= onerel->rd_nblocks)
+               if (targblock >= totalblocks)
                        break;
 
                /*
@@ -841,7 +842,7 @@ pageloop:;
        /*
         * Estimate total number of valid rows in relation.
         */
-       *totalrows = floor((double) onerel->rd_nblocks * tuplesperpage + 0.5);
+       *totalrows = floor((double) totalblocks * tuplesperpage + 0.5);
 
        /*
         * Emit some interesting relation info 
@@ -849,7 +850,7 @@ pageloop:;
        ereport(elevel,
                        (errmsg("\"%s\": %u pages, %d rows sampled, %.0f estimated total rows",
                                        RelationGetRelationName(onerel),
-                                       onerel->rd_nblocks, numrows, *totalrows)));
+                                       totalblocks, numrows, *totalrows)));
 
        return numrows;
 }
index de4499124d58a98729d7ccdc9d9c7336eccba7a7..0ff1b386b5b167a7313314c0323315d22782c87a 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.109 2004/04/06 16:39:30 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.110 2004/05/08 19:09:24 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -822,10 +822,6 @@ read_info(SeqTable elm, Relation rel, Buffer *buf)
        sequence_magic *sm;
        Form_pg_sequence seq;
 
-       if (rel->rd_nblocks > 1)
-               elog(ERROR, "invalid number of blocks in sequence \"%s\"",
-                        RelationGetRelationName(rel));
-
        *buf = ReadBuffer(rel, 0);
        if (!BufferIsValid(*buf))
                elog(ERROR, "ReadBuffer failed");
index 760c10bcc80841e7fbb49dd0de0c470e785a40a0..342c87db574eb434c094c63a7431b3aeba3087e5 100644 (file)
@@ -13,7 +13,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.274 2004/02/12 05:39:55 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.275 2004/05/08 19:09:24 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2522,11 +2522,7 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
        /* truncate relation, if needed */
        if (blkno < nblocks)
        {
-               if (onerel->rd_smgr == NULL)
-                       onerel->rd_smgr = smgropen(onerel->rd_node);
-               blkno = smgrtruncate(onerel->rd_smgr, blkno);
-               onerel->rd_nblocks = blkno;             /* update relcache immediately */
-               onerel->rd_targblock = InvalidBlockNumber;
+               RelationTruncate(onerel, blkno);
                vacrelstats->rel_pages = blkno; /* set new number of blocks */
        }
 
@@ -2594,11 +2590,7 @@ vacuum_heap(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages)
                                (errmsg("\"%s\": truncated %u to %u pages",
                                                RelationGetRelationName(onerel),
                                                vacrelstats->rel_pages, relblocks)));
-               if (onerel->rd_smgr == NULL)
-                       onerel->rd_smgr = smgropen(onerel->rd_node);
-               relblocks = smgrtruncate(onerel->rd_smgr, relblocks);
-               onerel->rd_nblocks = relblocks; /* update relcache immediately */
-               onerel->rd_targblock = InvalidBlockNumber;
+               RelationTruncate(onerel, relblocks);
                vacrelstats->rel_pages = relblocks;             /* set new number of
                                                                                                 * blocks */
        }
index 46920c0009b4987d9e8a6263370fc8d7f46adb78..af1b646be467e619a558510d3fd6752ad2374f6d 100644 (file)
@@ -31,7 +31,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.39 2004/04/25 23:50:54 neilc Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.40 2004/05/08 19:09:25 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -738,11 +738,7 @@ lazy_truncate_heap(Relation onerel, LVRelStats *vacrelstats)
        /*
         * Do the physical truncation.
         */
-       if (onerel->rd_smgr == NULL)
-               onerel->rd_smgr = smgropen(onerel->rd_node);
-       new_rel_pages = smgrtruncate(onerel->rd_smgr, new_rel_pages);
-       onerel->rd_nblocks = new_rel_pages; /* update relcache immediately */
-       onerel->rd_targblock = InvalidBlockNumber;
+       RelationTruncate(onerel, new_rel_pages);
        vacrelstats->rel_pages = new_rel_pages;         /* save new number of
                                                                                                 * blocks */
 
index 64f5e5ad40a0afd7c3775839c9c0be71f10a41c7..4f6772564a8df76148624befcdb5997c7a723138 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.164 2004/04/25 23:50:54 neilc Exp $
+ *       $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.165 2004/05/08 19:09:25 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -98,8 +98,6 @@ static void write_buffer(Buffer buffer, bool unpin);
  *
  * Assume when this function is called, that reln has been
  *             opened already.
- *
- * Note: a side effect of a P_NEW call is to update reln->rd_nblocks.
  */
 Buffer
 ReadBuffer(Relation reln, BlockNumber blockNum)
@@ -129,14 +127,14 @@ ReadBufferInternal(Relation reln, BlockNumber blockNum,
        if (reln->rd_smgr == NULL)
                reln->rd_smgr = smgropen(reln->rd_node);
 
+       /* Substitute proper block number if caller asked for P_NEW */
+       if (isExtend)
+               blockNum = smgrnblocks(reln->rd_smgr);
+
        if (isLocalBuf)
        {
                ReadLocalBufferCount++;
                pgstat_count_buffer_read(&reln->pgstat_info, reln);
-               /* Substitute proper block number if caller asked for P_NEW */
-               if (isExtend)
-                       blockNum = reln->rd_nblocks;
-
                bufHdr = LocalBufferAlloc(reln, blockNum, &found);
                if (found)
                        LocalBufferHitCount++;
@@ -145,13 +143,6 @@ ReadBufferInternal(Relation reln, BlockNumber blockNum,
        {
                ReadBufferCount++;
                pgstat_count_buffer_read(&reln->pgstat_info, reln);
-               /* Substitute proper block number if caller asked for P_NEW */
-               if (isExtend)
-               {
-                       /* must be sure we have accurate file length! */
-                       blockNum = reln->rd_nblocks = smgrnblocks(reln->rd_smgr);
-               }
-
                /*
                 * lookup the buffer.  IO_IN_PROGRESS is set if the requested
                 * block is not currently in memory.
@@ -196,8 +187,6 @@ ReadBufferInternal(Relation reln, BlockNumber blockNum,
                /* new buffers are zero-filled */
                MemSet((char *) MAKE_PTR(bufHdr->data), 0, BLCKSZ);
                smgrextend(reln->rd_smgr, blockNum, (char *) MAKE_PTR(bufHdr->data));
-               /* After successful extend, increment relation length */
-               reln->rd_nblocks++;
        }
        else
        {
@@ -1085,55 +1074,36 @@ FlushBuffer(BufferDesc *buf, SMgrRelation reln)
 /*
  * RelationGetNumberOfBlocks
  *             Determines the current number of pages in the relation.
- *             Side effect: relation->rd_nblocks is updated.
  */
 BlockNumber
 RelationGetNumberOfBlocks(Relation relation)
 {
-       /*
-        * relation->rd_nblocks should be accurate already if the relation is
-        * new or temp, because no one else should be modifying it.  Otherwise
-        * we need to ask the smgr for the current physical file length.
-        *
-        * Don't call smgr on a view or a composite type, either.
-        */
-       if (relation->rd_rel->relkind == RELKIND_VIEW ||
-               relation->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
-               relation->rd_nblocks = 0;
-       else if (!relation->rd_isnew && !relation->rd_istemp)
-       {
-               /* Open it at the smgr level if not already done */
-               if (relation->rd_smgr == NULL)
-                       relation->rd_smgr = smgropen(relation->rd_node);
-
-               relation->rd_nblocks = smgrnblocks(relation->rd_smgr);
-       }
+       /* Open it at the smgr level if not already done */
+       if (relation->rd_smgr == NULL)
+               relation->rd_smgr = smgropen(relation->rd_node);
 
-       return relation->rd_nblocks;
+       return smgrnblocks(relation->rd_smgr);
 }
 
 /*
- * RelationUpdateNumberOfBlocks
- *             Forcibly update relation->rd_nblocks.
+ * RelationTruncate
+ *             Physically truncate a relation to the specified number of blocks.
  *
- * If the relcache drops an entry for a temp relation, it must call this
- * routine after recreating the relcache entry, so that rd_nblocks is
- * re-sync'd with reality.  See RelationGetNumberOfBlocks.
+ * Caller should already have done something to flush any buffered pages
+ * that are to be dropped.
  */
 void
-RelationUpdateNumberOfBlocks(Relation relation)
+RelationTruncate(Relation rel, BlockNumber nblocks)
 {
-       if (relation->rd_rel->relkind == RELKIND_VIEW ||
-               relation->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
-               relation->rd_nblocks = 0;
-       else
-       {
-               /* Open it at the smgr level if not already done */
-               if (relation->rd_smgr == NULL)
-                       relation->rd_smgr = smgropen(relation->rd_node);
+       /* Open it at the smgr level if not already done */
+       if (rel->rd_smgr == NULL)
+               rel->rd_smgr = smgropen(rel->rd_node);
 
-               relation->rd_nblocks = smgrnblocks(relation->rd_smgr);
-       }
+       /* Make sure rd_targblock isn't pointing somewhere past end */
+       rel->rd_targblock = InvalidBlockNumber;
+
+       /* Do the real work */
+       smgrtruncate(rel->rd_smgr, nblocks);
 }
 
 /* ---------------------------------------------------------------------
index 85ad6ffe78867490ac8ad45a0c75991dbe351c35..0e4a31745fda0096218b549cd1e006c7bed8d3c5 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.201 2004/04/01 21:28:45 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.202 2004/05/08 19:09:25 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -889,17 +889,6 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo,
        RelationCacheInsert(relation);
        MemoryContextSwitchTo(oldcxt);
 
-       /*
-        * If it's a temp rel, RelationGetNumberOfBlocks will assume that
-        * rd_nblocks is correct.  Must forcibly update the block count when
-        * creating the relcache entry.  But if we are doing a rebuild, don't
-        * do this yet; leave it to RelationClearRelation to do at the end.
-        * (Otherwise, an elog in RelationUpdateNumberOfBlocks would leave us
-        * with inconsistent relcache state.)
-        */
-       if (relation->rd_istemp && oldrelation == NULL)
-               RelationUpdateNumberOfBlocks(relation);
-
        return relation;
 }
 
@@ -1583,9 +1572,7 @@ RelationReloadClassinfo(Relation relation)
        memcpy((char *) relation->rd_rel, (char *) relp, CLASS_TUPLE_SIZE);
        relation->rd_node.relNode = relp->relfilenode;
        heap_freetuple(pg_class_tuple);
-       /* Must adjust number of blocks after we know the new relfilenode */
        relation->rd_targblock = InvalidBlockNumber;
-       RelationUpdateNumberOfBlocks(relation);
        /* Okay, now it's valid again */
        relation->rd_isnailed = 1;
 }
@@ -1620,29 +1607,26 @@ RelationClearRelation(Relation relation, bool rebuild)
 
        /*
         * Never, never ever blow away a nailed-in system relation, because
-        * we'd be unable to recover.  However, we must update rd_nblocks and
-        * reset rd_targblock, in case we got called because of a relation
-        * cache flush that was triggered by VACUUM.  If it's a nailed index,
-        * then we need to re-read the pg_class row to see if its relfilenode
-        * changed.  We can't necessarily do that here, because we might be in
-        * a failed transaction.  We assume it's okay to do it if there are open
-        * references to the relcache entry (cf notes for AtEOXact_RelationCache).
-        * Otherwise just mark the entry as possibly invalid, and it'll be fixed
-        * when next opened.
+        * we'd be unable to recover.  However, we must reset rd_targblock, in
+        * case we got called because of a relation cache flush that was triggered
+        * by VACUUM.
+        *
+        * If it's a nailed index, then we need to re-read the pg_class row to see
+        * if its relfilenode changed.  We can't necessarily do that here, because
+        * we might be in a failed transaction.  We assume it's okay to do it if
+        * there are open references to the relcache entry (cf notes for
+        * AtEOXact_RelationCache).  Otherwise just mark the entry as possibly
+        * invalid, and it'll be fixed when next opened.
         */
        if (relation->rd_isnailed)
        {
+               relation->rd_targblock = InvalidBlockNumber;
                if (relation->rd_rel->relkind == RELKIND_INDEX)
                {
                        relation->rd_isnailed = 2;      /* needs to be revalidated */
                        if (relation->rd_refcnt > 1)
                                RelationReloadClassinfo(relation);
                }
-               else
-               {
-                       relation->rd_targblock = InvalidBlockNumber;
-                       RelationUpdateNumberOfBlocks(relation);
-               }
                return;
        }
 
@@ -1746,15 +1730,6 @@ RelationClearRelation(Relation relation, bool rebuild)
                        if (old_rulescxt)
                                MemoryContextDelete(old_rulescxt);
                }
-
-               /*
-                * Update rd_nblocks.  This is kind of expensive, but I think we
-                * must do it in case relation has been truncated... we definitely
-                * must do it if the rel is new or temp, since
-                * RelationGetNumberOfBlocks will subsequently assume that the
-                * block count is correct.
-                */
-               RelationUpdateNumberOfBlocks(relation);
        }
 }
 
index 746b795b26eaf5f749056419f1ae592cb06f0ae0..b6ca7e43a62d87f7569effa770a39d165124f432 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/access/relscan.h,v 1.34 2003/11/29 22:40:55 pgsql Exp $
+ * $PostgreSQL: pgsql/src/include/access/relscan.h,v 1.35 2004/05/08 19:09:25 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -25,6 +25,7 @@ typedef struct HeapScanDescData
        Snapshot        rs_snapshot;    /* snapshot to see */
        int                     rs_nkeys;               /* number of scan keys */
        ScanKey         rs_key;                 /* array of scan key descriptors */
+       BlockNumber rs_nblocks;         /* number of blocks to scan */
 
        /* scan current state */
        HeapTupleData rs_ctup;          /* current tuple in scan, if any */
index 1cd16a515342582d0d1b38323a43a2bc2df80599..0aab9ad24f4466d39e3a2354cae535d0d031ad73 100644 (file)
@@ -7,7 +7,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/bufmgr.h,v 1.78 2004/04/25 23:50:58 neilc Exp $
+ * $PostgreSQL: pgsql/src/include/storage/bufmgr.h,v 1.79 2004/05/08 19:09:25 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -156,7 +156,7 @@ extern void AtEOXact_Buffers(bool isCommit);
 extern void FlushBufferPool(void);
 extern BlockNumber BufferGetBlockNumber(Buffer buffer);
 extern BlockNumber RelationGetNumberOfBlocks(Relation relation);
-extern void RelationUpdateNumberOfBlocks(Relation relation);
+extern void RelationTruncate(Relation rel, BlockNumber nblocks);
 extern int     FlushRelationBuffers(Relation rel, BlockNumber firstDelBlock);
 extern void DropRelationBuffers(Relation rel);
 extern void DropRelFileNodeBuffers(RelFileNode rnode, bool istemp);
index 8532c5a737abf689a959cc904375167881e2b827..e5008e56ea5276c42948d02d15eae7bc2a96ee0d 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/utils/rel.h,v 1.73 2004/02/10 01:55:27 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/utils/rel.h,v 1.74 2004/05/08 19:09:25 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -107,7 +107,6 @@ typedef struct RelationData
        RelFileNode rd_node;            /* relation physical identifier */
        /* use "struct" here to avoid needing to include smgr.h: */
        struct SMgrRelationData *rd_smgr; /* cached file handle, or NULL */
-       BlockNumber rd_nblocks;         /* number of blocks in rel */
        BlockNumber rd_targblock;       /* current insertion target block, or
                                                                 * InvalidBlockNumber */
        int                     rd_refcnt;              /* reference count */