1313 *
1414 *
1515 * IDENTIFICATION
16- * $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.382 2008/12/03 13:05:22 heikki Exp $
16+ * $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.383 2008/12/17 09:15:02 heikki Exp $
1717 *
1818 *-------------------------------------------------------------------------
1919 */
@@ -216,7 +216,7 @@ static List *get_rel_oids(Oid relid, const RangeVar *vacrel,
216216 const char * stmttype );
217217static void vac_truncate_clog (TransactionId frozenXID );
218218static void vacuum_rel (Oid relid , VacuumStmt * vacstmt , bool do_toast ,
219- bool for_wraparound );
219+ bool for_wraparound , bool * scanned_all );
220220static void full_vacuum_rel (Relation onerel , VacuumStmt * vacstmt );
221221static void scan_heap (VRelStats * vacrelstats , Relation onerel ,
222222 VacPageList vacuum_pages , VacPageList fraged_pages );
@@ -436,9 +436,11 @@ vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
436436 foreach (cur , relations )
437437 {
438438 Oid relid = lfirst_oid (cur );
439+ bool scanned_all = false;
439440
440441 if (vacstmt -> vacuum )
441- vacuum_rel (relid , vacstmt , do_toast , for_wraparound );
442+ vacuum_rel (relid , vacstmt , do_toast , for_wraparound ,
443+ & scanned_all );
442444
443445 if (vacstmt -> analyze )
444446 {
@@ -460,7 +462,7 @@ vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
460462 else
461463 old_context = MemoryContextSwitchTo (anl_context );
462464
463- analyze_rel (relid , vacstmt , vac_strategy );
465+ analyze_rel (relid , vacstmt , vac_strategy , ! scanned_all );
464466
465467 if (use_own_xacts )
466468 {
@@ -756,21 +758,9 @@ vac_update_relstats(Relation relation,
756758 dirty = true;
757759 }
758760
759- /*
760- * If anything changed, write out the tuple. Even if nothing changed,
761- * force relcache invalidation so all backends reset their rd_targblock
762- * --- otherwise it might point to a page we truncated away.
763- */
761+ /* If anything changed, write out the tuple. */
764762 if (dirty )
765- {
766763 heap_inplace_update (rd , ctup );
767- /* the above sends a cache inval message */
768- }
769- else
770- {
771- /* no need to change tuple, but force relcache inval anyway */
772- CacheInvalidateRelcacheByTuple (ctup );
773- }
774764
775765 heap_close (rd , RowExclusiveLock );
776766}
@@ -986,10 +976,14 @@ vac_truncate_clog(TransactionId frozenXID)
986976 * many small transactions. Otherwise, two-phase locking would require
987977 * us to lock the entire database during one pass of the vacuum cleaner.
988978 *
979+ * We'll return true in *scanned_all if the vacuum scanned all heap
980+ * pages, and updated pg_class.
981+ *
989982 * At entry and exit, we are not inside a transaction.
990983 */
991984static void
992- vacuum_rel (Oid relid , VacuumStmt * vacstmt , bool do_toast , bool for_wraparound )
985+ vacuum_rel (Oid relid , VacuumStmt * vacstmt , bool do_toast , bool for_wraparound ,
986+ bool * scanned_all )
993987{
994988 LOCKMODE lmode ;
995989 Relation onerel ;
@@ -998,6 +992,9 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound)
998992 Oid save_userid ;
999993 bool save_secdefcxt ;
1000994
995+ if (scanned_all )
996+ * scanned_all = false;
997+
1001998 /* Begin a transaction for vacuuming this relation */
1002999 StartTransactionCommand ();
10031000
@@ -1162,7 +1159,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound)
11621159 if (vacstmt -> full )
11631160 full_vacuum_rel (onerel , vacstmt );
11641161 else
1165- lazy_vacuum_rel (onerel , vacstmt , vac_strategy );
1162+ lazy_vacuum_rel (onerel , vacstmt , vac_strategy , scanned_all );
11661163
11671164 /* Restore userid */
11681165 SetUserIdAndContext (save_userid , save_secdefcxt );
@@ -1184,7 +1181,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound)
11841181 * totally unimportant for toast relations.
11851182 */
11861183 if (toast_relid != InvalidOid )
1187- vacuum_rel (toast_relid , vacstmt , false, for_wraparound );
1184+ vacuum_rel (toast_relid , vacstmt , false, for_wraparound , NULL );
11881185
11891186 /*
11901187 * Now release the session-level lock on the master table.
@@ -1296,7 +1293,7 @@ full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt)
12961293
12971294 /* report results to the stats collector, too */
12981295 pgstat_report_vacuum (RelationGetRelid (onerel ), onerel -> rd_rel -> relisshared ,
1299- vacstmt -> analyze , vacrelstats -> rel_tuples );
1296+ true, vacstmt -> analyze , vacrelstats -> rel_tuples );
13001297}
13011298
13021299
@@ -2866,6 +2863,10 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
28662863 if (blkno < nblocks )
28672864 {
28682865 RelationTruncate (onerel , blkno );
2866+
2867+ /* force relcache inval so all backends reset their rd_targblock */
2868+ CacheInvalidateRelcache (onerel );
2869+
28692870 vacrelstats -> rel_pages = blkno ; /* set new number of blocks */
28702871 }
28712872
@@ -3286,6 +3287,10 @@ vacuum_heap(VRelStats *vacrelstats, Relation onerel, VacPageList vacuum_pages)
32863287 RelationGetRelationName (onerel ),
32873288 vacrelstats -> rel_pages , relblocks )));
32883289 RelationTruncate (onerel , relblocks );
3290+
3291+ /* force relcache inval so all backends reset their rd_targblock */
3292+ CacheInvalidateRelcache (onerel );
3293+
32893294 vacrelstats -> rel_pages = relblocks ; /* set new number of blocks */
32903295 }
32913296}
0 commit comments