1313 *
1414 *
1515 * IDENTIFICATION
16- * $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.379 2008/10/31 15:05:00 heikki Exp $
16+ * $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.380 2008/11/10 00:49:37 tgl Exp $
1717 *
1818 *-------------------------------------------------------------------------
1919 */
@@ -664,6 +664,11 @@ vacuum_set_xid_limits(int freeze_min_age, bool sharedRel,
664664 *pg_class would've been obsoleted. Of course, this only works for
665665 *fixed-size never-null columns, but these are.
666666 *
667+ *Note another assumption: that two VACUUMs/ANALYZEs on a table can't
668+ *run in parallel, nor can VACUUM/ANALYZE run in parallel with a
669+ *schema alteration such as adding an index, rule, or trigger. Otherwise
670+ *our updates of relhasindex etc might overwrite uncommitted updates.
671+ *
667672 *Another reason for doing it this way is that when we are in a lazy
668673 *VACUUM and have PROC_IN_VACUUM set, we mustn't do any updates ---
669674 *somebody vacuuming pg_class might think they could delete a tuple
@@ -673,9 +678,11 @@ vacuum_set_xid_limits(int freeze_min_age, bool sharedRel,
673678 *ANALYZE.
674679 */
675680void
676- vac_update_relstats (Oid relid ,BlockNumber num_pages ,double num_tuples ,
681+ vac_update_relstats (Relation relation ,
682+ BlockNumber num_pages ,double num_tuples ,
677683bool hasindex ,TransactionId frozenxid )
678684{
685+ Oid relid = RelationGetRelid (relation );
679686Relation rd ;
680687HeapTuple ctup ;
681688Form_pg_class pgcform ;
@@ -724,6 +731,18 @@ vac_update_relstats(Oid relid, BlockNumber num_pages, double num_tuples,
724731}
725732}
726733
734+ /* We also clear relhasrules and relhastriggers if needed */
735+ if (pgcform -> relhasrules && relation -> rd_rules == NULL )
736+ {
737+ pgcform -> relhasrules = false;
738+ dirty = true;
739+ }
740+ if (pgcform -> relhastriggers && relation -> trigdesc == NULL )
741+ {
742+ pgcform -> relhastriggers = false;
743+ dirty = true;
744+ }
745+
727746/*
728747 * relfrozenxid should never go backward. Caller can pass
729748 * InvalidTransactionId if it has no new data.
@@ -1269,9 +1288,9 @@ full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt)
12691288FreeSpaceMapVacuum (onerel );
12701289
12711290/* update statistics in pg_class */
1272- vac_update_relstats (RelationGetRelid ( onerel ), vacrelstats -> rel_pages ,
1273- vacrelstats -> rel_tuples ,vacrelstats -> hasindex ,
1274- FreezeLimit );
1291+ vac_update_relstats (onerel ,
1292+ vacrelstats -> rel_pages ,vacrelstats -> rel_tuples ,
1293+ vacrelstats -> hasindex , FreezeLimit );
12751294
12761295/* report results to the stats collector, too */
12771296pgstat_report_vacuum (RelationGetRelid (onerel ),onerel -> rd_rel -> relisshared ,
@@ -3315,7 +3334,7 @@ scan_index(Relation indrel, double num_tuples)
33153334return ;
33163335
33173336/* now update statistics in pg_class */
3318- vac_update_relstats (RelationGetRelid ( indrel ) ,
3337+ vac_update_relstats (indrel ,
33193338stats -> num_pages ,stats -> num_index_tuples ,
33203339false,InvalidTransactionId );
33213340
@@ -3385,7 +3404,7 @@ vacuum_index(VacPageList vacpagelist, Relation indrel,
33853404return ;
33863405
33873406/* now update statistics in pg_class */
3388- vac_update_relstats (RelationGetRelid ( indrel ) ,
3407+ vac_update_relstats (indrel ,
33893408stats -> num_pages ,stats -> num_index_tuples ,
33903409false,InvalidTransactionId );
33913410