1313 *
1414 *
1515 * IDENTIFICATION
16- * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.240 2002/09/23 20:43:41 tgl Exp $
16+ * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.241 2002/09/27 20:57:08 tgl Exp $
1717 *
1818 *-------------------------------------------------------------------------
1919 */
@@ -105,9 +105,6 @@ static intelevel = -1;
105105static TransactionId OldestXmin ;
106106static TransactionId FreezeLimit ;
107107
108- static TransactionId initialOldestXmin ;
109- static TransactionId initialFreezeLimit ;
110-
111108
112109/* non-export function prototypes */
113110static List * getrels (const RangeVar * vacrel ,const char * stmttype );
@@ -116,7 +113,7 @@ static void vac_update_dbstats(Oid dbid,
116113TransactionId frozenXID );
117114static void vac_truncate_clog (TransactionId vacuumXID ,
118115TransactionId frozenXID );
119- static void vacuum_rel (Oid relid ,VacuumStmt * vacstmt ,char expected_relkind );
116+ static bool vacuum_rel (Oid relid ,VacuumStmt * vacstmt ,char expected_relkind );
120117static void full_vacuum_rel (Relation onerel ,VacuumStmt * vacstmt );
121118static void scan_heap (VRelStats * vacrelstats ,Relation onerel ,
122119VacPageList vacuum_pages ,VacPageList fraged_pages );
@@ -160,6 +157,9 @@ vacuum(VacuumStmt *vacstmt)
160157{
161158const char * stmttype = vacstmt -> vacuum ?"VACUUM" :"ANALYZE" ;
162159MemoryContext anl_context = NULL ;
160+ TransactionId initialOldestXmin = InvalidTransactionId ;
161+ TransactionId initialFreezeLimit = InvalidTransactionId ;
162+ bool all_rels ;
163163List * vrl ,
164164* cur ;
165165
@@ -215,6 +215,9 @@ vacuum(VacuumStmt *vacstmt)
215215ALLOCSET_DEFAULT_INITSIZE ,
216216ALLOCSET_DEFAULT_MAXSIZE );
217217
218+ /* Assume we are processing everything unless one table is mentioned */
219+ all_rels = (vacstmt -> relation == NULL );
220+
218221/* Build list of relations to process (note this lives in vac_context) */
219222vrl = getrels (vacstmt -> relation ,stmttype );
220223
@@ -248,7 +251,7 @@ vacuum(VacuumStmt *vacstmt)
248251 */
249252if (vacstmt -> vacuum )
250253{
251- if (vacstmt -> relation == NULL )
254+ if (all_rels )
252255{
253256/*
254257 * It's a database-wide VACUUM.
@@ -271,7 +274,8 @@ vacuum(VacuumStmt *vacstmt)
271274 * recorded in pg_database.
272275 */
273276vacuum_set_xid_limits (vacstmt , false,
274- & initialOldestXmin ,& initialFreezeLimit );
277+ & initialOldestXmin ,
278+ & initialFreezeLimit );
275279}
276280
277281/* matches the StartTransaction in PostgresMain() */
@@ -286,7 +290,10 @@ vacuum(VacuumStmt *vacstmt)
286290Oid relid = (Oid )lfirsti (cur );
287291
288292if (vacstmt -> vacuum )
289- vacuum_rel (relid ,vacstmt ,RELKIND_RELATION );
293+ {
294+ if (!vacuum_rel (relid ,vacstmt ,RELKIND_RELATION ))
295+ all_rels = false;/* forget about updating dbstats */
296+ }
290297if (vacstmt -> analyze )
291298{
292299MemoryContext old_context = NULL ;
@@ -331,11 +338,11 @@ vacuum(VacuumStmt *vacstmt)
331338StartTransactionCommand (true);
332339
333340/*
334- * If wedid a database-wide VACUUM, update the database's
335- *pg_database row with info about thetransaction IDs used, and
336- * try to truncate pg_clog.
341+ * If wecompleted a database-wide VACUUM without skipping any
342+ *relations, update thedatabase's pg_database row with info
343+ *about the transaction IDs used, and try to truncate pg_clog.
337344 */
338- if (vacstmt -> relation == NULL )
345+ if (all_rels )
339346{
340347vac_update_dbstats (MyDatabaseId ,
341348initialOldestXmin ,initialFreezeLimit );
@@ -693,6 +700,11 @@ vac_truncate_clog(TransactionId vacuumXID, TransactionId frozenXID)
693700/*
694701 *vacuum_rel() -- vacuum one heap relation
695702 *
703+ *Returns TRUE if we actually processed the relation (or can ignore it
704+ *for some reason), FALSE if we failed to process it due to permissions
705+ *or other reasons. (A FALSE result really means that some data
706+ *may have been left unvacuumed, so we can't update XID stats.)
707+ *
696708 *Doing one heap at a time incurs extra overhead, since we need to
697709 *check that the heap exists again just before we vacuum it.The
698710 *reason that we do this is so that vacuuming can be spread across
@@ -701,13 +713,14 @@ vac_truncate_clog(TransactionId vacuumXID, TransactionId frozenXID)
701713 *
702714 *At entry and exit, we are not inside a transaction.
703715 */
704- static void
716+ static bool
705717vacuum_rel (Oid relid ,VacuumStmt * vacstmt ,char expected_relkind )
706718{
707719LOCKMODE lmode ;
708720Relation onerel ;
709721LockRelId onerelid ;
710722Oid toast_relid ;
723+ bool result ;
711724
712725/* Begin a transaction for vacuuming this relation */
713726StartTransactionCommand (true);
@@ -727,7 +740,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
7277400 ,0 ,0 ))
728741{
729742CommitTransactionCommand (true);
730- return ;
743+ return true; /* okay 'cause no data there */
731744}
732745
733746/*
@@ -759,7 +772,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
759772RelationGetRelationName (onerel ));
760773relation_close (onerel ,lmode );
761774CommitTransactionCommand (true);
762- return ;
775+ return false ;
763776}
764777
765778/*
@@ -772,7 +785,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
772785RelationGetRelationName (onerel ));
773786relation_close (onerel ,lmode );
774787CommitTransactionCommand (true);
775- return ;
788+ return false ;
776789}
777790
778791/*
@@ -786,7 +799,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
786799{
787800relation_close (onerel ,lmode );
788801CommitTransactionCommand (true);
789- return ;
802+ return true; /* assume no long-lived data in temp tables */
790803}
791804
792805/*
@@ -815,6 +828,8 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
815828else
816829lazy_vacuum_rel (onerel ,vacstmt );
817830
831+ result = true;/* did the vacuum */
832+
818833/* all done with this class, but hold lock until commit */
819834relation_close (onerel ,NoLock );
820835
@@ -831,12 +846,17 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
831846 * statistics are totally unimportant for toast relations.
832847 */
833848if (toast_relid != InvalidOid )
834- vacuum_rel (toast_relid ,vacstmt ,RELKIND_TOASTVALUE );
849+ {
850+ if (!vacuum_rel (toast_relid ,vacstmt ,RELKIND_TOASTVALUE ))
851+ result = false;/* failed to vacuum the TOAST table? */
852+ }
835853
836854/*
837855 * Now release the session-level lock on the master table.
838856 */
839857UnlockRelationForSession (& onerelid ,lmode );
858+
859+ return result ;
840860}
841861
842862