13
13
*
14
14
*
15
15
* 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 $
17
17
*
18
18
*-------------------------------------------------------------------------
19
19
*/
@@ -105,9 +105,6 @@ static int elevel = -1;
105
105
static TransactionId OldestXmin ;
106
106
static TransactionId FreezeLimit ;
107
107
108
- static TransactionId initialOldestXmin ;
109
- static TransactionId initialFreezeLimit ;
110
-
111
108
112
109
/* non-export function prototypes */
113
110
static List * getrels (const RangeVar * vacrel , const char * stmttype );
@@ -116,7 +113,7 @@ static void vac_update_dbstats(Oid dbid,
116
113
TransactionId frozenXID );
117
114
static void vac_truncate_clog (TransactionId vacuumXID ,
118
115
TransactionId 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 );
120
117
static void full_vacuum_rel (Relation onerel , VacuumStmt * vacstmt );
121
118
static void scan_heap (VRelStats * vacrelstats , Relation onerel ,
122
119
VacPageList vacuum_pages , VacPageList fraged_pages );
@@ -160,6 +157,9 @@ vacuum(VacuumStmt *vacstmt)
160
157
{
161
158
const char * stmttype = vacstmt -> vacuum ? "VACUUM" : "ANALYZE" ;
162
159
MemoryContext anl_context = NULL ;
160
+ TransactionId initialOldestXmin = InvalidTransactionId ;
161
+ TransactionId initialFreezeLimit = InvalidTransactionId ;
162
+ bool all_rels ;
163
163
List * vrl ,
164
164
* cur ;
165
165
@@ -215,6 +215,9 @@ vacuum(VacuumStmt *vacstmt)
215
215
ALLOCSET_DEFAULT_INITSIZE ,
216
216
ALLOCSET_DEFAULT_MAXSIZE );
217
217
218
+ /* Assume we are processing everything unless one table is mentioned */
219
+ all_rels = (vacstmt -> relation == NULL );
220
+
218
221
/* Build list of relations to process (note this lives in vac_context) */
219
222
vrl = getrels (vacstmt -> relation , stmttype );
220
223
@@ -248,7 +251,7 @@ vacuum(VacuumStmt *vacstmt)
248
251
*/
249
252
if (vacstmt -> vacuum )
250
253
{
251
- if (vacstmt -> relation == NULL )
254
+ if (all_rels )
252
255
{
253
256
/*
254
257
* It's a database-wide VACUUM.
@@ -271,7 +274,8 @@ vacuum(VacuumStmt *vacstmt)
271
274
* recorded in pg_database.
272
275
*/
273
276
vacuum_set_xid_limits (vacstmt , false,
274
- & initialOldestXmin , & initialFreezeLimit );
277
+ & initialOldestXmin ,
278
+ & initialFreezeLimit );
275
279
}
276
280
277
281
/* matches the StartTransaction in PostgresMain() */
@@ -286,7 +290,10 @@ vacuum(VacuumStmt *vacstmt)
286
290
Oid relid = (Oid ) lfirsti (cur );
287
291
288
292
if (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
+ }
290
297
if (vacstmt -> analyze )
291
298
{
292
299
MemoryContext old_context = NULL ;
@@ -331,11 +338,11 @@ vacuum(VacuumStmt *vacstmt)
331
338
StartTransactionCommand (true);
332
339
333
340
/*
334
- * If we did a database-wide VACUUM, update the database's
335
- * pg_database row with info about the transaction IDs used, and
336
- * try to truncate pg_clog.
341
+ * If we completed a database-wide VACUUM without skipping any
342
+ * relations, update the database's pg_database row with info
343
+ * about the transaction IDs used, and try to truncate pg_clog.
337
344
*/
338
- if (vacstmt -> relation == NULL )
345
+ if (all_rels )
339
346
{
340
347
vac_update_dbstats (MyDatabaseId ,
341
348
initialOldestXmin , initialFreezeLimit );
@@ -693,6 +700,11 @@ vac_truncate_clog(TransactionId vacuumXID, TransactionId frozenXID)
693
700
/*
694
701
* vacuum_rel() -- vacuum one heap relation
695
702
*
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
+ *
696
708
* Doing one heap at a time incurs extra overhead, since we need to
697
709
* check that the heap exists again just before we vacuum it. The
698
710
* reason that we do this is so that vacuuming can be spread across
@@ -701,13 +713,14 @@ vac_truncate_clog(TransactionId vacuumXID, TransactionId frozenXID)
701
713
*
702
714
* At entry and exit, we are not inside a transaction.
703
715
*/
704
- static void
716
+ static bool
705
717
vacuum_rel (Oid relid , VacuumStmt * vacstmt , char expected_relkind )
706
718
{
707
719
LOCKMODE lmode ;
708
720
Relation onerel ;
709
721
LockRelId onerelid ;
710
722
Oid toast_relid ;
723
+ bool result ;
711
724
712
725
/* Begin a transaction for vacuuming this relation */
713
726
StartTransactionCommand (true);
@@ -727,7 +740,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
727
740
0 , 0 , 0 ))
728
741
{
729
742
CommitTransactionCommand (true);
730
- return ;
743
+ return true; /* okay 'cause no data there */
731
744
}
732
745
733
746
/*
@@ -759,7 +772,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
759
772
RelationGetRelationName (onerel ));
760
773
relation_close (onerel , lmode );
761
774
CommitTransactionCommand (true);
762
- return ;
775
+ return false ;
763
776
}
764
777
765
778
/*
@@ -772,7 +785,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
772
785
RelationGetRelationName (onerel ));
773
786
relation_close (onerel , lmode );
774
787
CommitTransactionCommand (true);
775
- return ;
788
+ return false ;
776
789
}
777
790
778
791
/*
@@ -786,7 +799,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
786
799
{
787
800
relation_close (onerel , lmode );
788
801
CommitTransactionCommand (true);
789
- return ;
802
+ return true; /* assume no long-lived data in temp tables */
790
803
}
791
804
792
805
/*
@@ -815,6 +828,8 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
815
828
else
816
829
lazy_vacuum_rel (onerel , vacstmt );
817
830
831
+ result = true; /* did the vacuum */
832
+
818
833
/* all done with this class, but hold lock until commit */
819
834
relation_close (onerel , NoLock );
820
835
@@ -831,12 +846,17 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, char expected_relkind)
831
846
* statistics are totally unimportant for toast relations.
832
847
*/
833
848
if (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
+ }
835
853
836
854
/*
837
855
* Now release the session-level lock on the master table.
838
856
*/
839
857
UnlockRelationForSession (& onerelid , lmode );
858
+
859
+ return result ;
840
860
}
841
861
842
862
0 commit comments