OSDN Git Service

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 ca08261..98b4cc3 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 bff8458..894980b 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 57074a0..ededa62 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 51b7d31..94f1fd2 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 6a994aa..d6d3879 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 bd82a96..d388f52 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 de44991..0ff1b38 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 760c10b..342c87d 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 46920c0..af1b646 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 64f5e5a..4f67725 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 85ad6ff..0e4a317 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 746b795..b6ca7e4 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 1cd16a5..0aab9ad 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 8532c5a..e5008e5 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 */