Fix vac_update_relstats to ensure it always sends a relcache inval message,
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 8 Mar 2007 17:03:31 +0000 (17:03 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 8 Mar 2007 17:03:31 +0000 (17:03 +0000)
even if none of the fields in the pg_class row change.  This behavior is
necessary to ensure other backends flush rd_targblock values that might
point to truncated-away pages.  We got this right pre-8.2 but it was broken
by overoptimistic change to not write out the pg_class row if unchanged.
Per report from Pavan Deolasee.

src/backend/commands/vacuum.c

index 804897821ce976c1934d70f718debd4c01d854bd..d13090ebf726f7f669e4823b4d1f2f95489a5477 100644 (file)
@@ -13,7 +13,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.346 2007/02/15 23:23:22 alvherre Exp $
+ *   $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.347 2007/03/08 17:03:31 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -715,10 +715,20 @@ vac_update_relstats(Oid relid, BlockNumber num_pages, double num_tuples,
    }
 
    /*
-    * If anything changed, write out the tuple
+    * If anything changed, write out the tuple.  Even if nothing changed,
+    * force relcache invalidation so all backends reset their rd_targblock
+    * --- otherwise it might point to a page we truncated away.
     */
    if (dirty)
+   {
        heap_inplace_update(rd, ctup);
+       /* the above sends a cache inval message */
+   }
+   else
+   {
+       /* no need to change tuple, but force relcache inval anyway */
+       CacheInvalidateRelcacheByTuple(ctup);
+   }
 
    heap_close(rd, RowExclusiveLock);
 }