31
31
*
32
32
*
33
33
* IDENTIFICATION
34
- * $Header: /cvsroot/pgsql/src/backend/commands/vacuumlazy.c,v 1.2 2001/07/15 22:48:17 tgl Exp $
34
+ * $Header: /cvsroot/pgsql/src/backend/commands/vacuumlazy.c,v 1.3 2001/07/18 00:46:25 tgl Exp $
35
35
*
36
36
*-------------------------------------------------------------------------
37
37
*/
@@ -101,6 +101,7 @@ static TransactionId XmaxRecent;
101
101
static void lazy_scan_heap (Relation onerel , LVRelStats * vacrelstats ,
102
102
Relation * Irel , int nindexes );
103
103
static void lazy_vacuum_heap (Relation onerel , LVRelStats * vacrelstats );
104
+ static void lazy_scan_index (Relation indrel , LVRelStats * vacrelstats );
104
105
static void lazy_vacuum_index (Relation indrel , LVRelStats * vacrelstats );
105
106
static int lazy_vacuum_page (Relation onerel , BlockNumber blkno , Buffer buffer ,
106
107
int tupindex , LVRelStats * vacrelstats );
@@ -113,6 +114,7 @@ static void lazy_record_dead_tuple(LVRelStats *vacrelstats,
113
114
static void lazy_record_free_space (LVRelStats * vacrelstats ,
114
115
BlockNumber page , Size avail );
115
116
static bool lazy_tid_reaped (ItemPointer itemptr , void * state );
117
+ static bool dummy_tid_reaped (ItemPointer itemptr , void * state );
116
118
static void lazy_update_fsm (Relation onerel , LVRelStats * vacrelstats );
117
119
static int vac_cmp_itemptr (const void * left , const void * right );
118
120
@@ -197,6 +199,7 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
197
199
tups_vacuumed ,
198
200
nkeep ,
199
201
nunused ;
202
+ bool did_vacuum_index = false;
200
203
int i ;
201
204
VacRUsage ru0 ;
202
205
@@ -235,6 +238,7 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
235
238
/* Remove index entries */
236
239
for (i = 0 ; i < nindexes ; i ++ )
237
240
lazy_vacuum_index (Irel [i ], vacrelstats );
241
+ did_vacuum_index = true;
238
242
/* Remove tuples from heap */
239
243
lazy_vacuum_heap (onerel , vacrelstats );
240
244
/* Forget the now-vacuumed tuples, and press on */
@@ -378,6 +382,9 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
378
382
ReleaseBuffer (buf );
379
383
}
380
384
385
+ /* save stats for use later */
386
+ vacrelstats -> rel_tuples = num_tuples ;
387
+
381
388
/* If any tuples need to be deleted, perform final vacuum cycle */
382
389
/* XXX put a threshold on min nuber of tuples here? */
383
390
if (vacrelstats -> num_dead_tuples > 0 )
@@ -388,9 +395,12 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
388
395
/* Remove tuples from heap */
389
396
lazy_vacuum_heap (onerel , vacrelstats );
390
397
}
391
-
392
- /* save stats for use later */
393
- vacrelstats -> rel_tuples = num_tuples ;
398
+ else if (! did_vacuum_index )
399
+ {
400
+ /* Scan indexes just to update pg_class statistics about them */
401
+ for (i = 0 ; i < nindexes ; i ++ )
402
+ lazy_scan_index (Irel [i ], vacrelstats );
403
+ }
394
404
395
405
elog (MESSAGE_LEVEL , "Pages %u: Changed %u, Empty %u; \
396
406
Tup %.0f: Vac %.0f, Keep %.0f, UnUsed %.0f.\n\tTotal %s" ,
@@ -495,6 +505,68 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
495
505
return tupindex ;
496
506
}
497
507
508
+ /*
509
+ * lazy_scan_index() -- scan one index relation to update pg_class statistic.
510
+ *
511
+ * We use this when we have no deletions to do.
512
+ */
513
+ static void
514
+ lazy_scan_index (Relation indrel , LVRelStats * vacrelstats )
515
+ {
516
+ IndexBulkDeleteResult * stats ;
517
+ VacRUsage ru0 ;
518
+
519
+ vac_init_rusage (& ru0 );
520
+
521
+ /*
522
+ * If the index is not partial, skip the scan, and just assume it
523
+ * has the same number of tuples as the heap.
524
+ */
525
+ if (! vac_is_partial_index (indrel ))
526
+ {
527
+ vac_update_relstats (RelationGetRelid (indrel ),
528
+ RelationGetNumberOfBlocks (indrel ),
529
+ vacrelstats -> rel_tuples ,
530
+ false);
531
+ return ;
532
+ }
533
+
534
+ /*
535
+ * If index is unsafe for concurrent access, must lock it;
536
+ * but a shared lock should be sufficient.
537
+ */
538
+ if (! indrel -> rd_am -> amconcurrent )
539
+ LockRelation (indrel , AccessShareLock );
540
+
541
+ /*
542
+ * Even though we're not planning to delete anything, use the
543
+ * ambulkdelete call, so that the scan happens within the index AM
544
+ * for more speed.
545
+ */
546
+ stats = index_bulk_delete (indrel , dummy_tid_reaped , NULL );
547
+
548
+ /*
549
+ * Release lock acquired above.
550
+ */
551
+ if (! indrel -> rd_am -> amconcurrent )
552
+ UnlockRelation (indrel , AccessShareLock );
553
+
554
+ if (!stats )
555
+ return ;
556
+
557
+ /* now update statistics in pg_class */
558
+ vac_update_relstats (RelationGetRelid (indrel ),
559
+ stats -> num_pages , stats -> num_index_tuples ,
560
+ false);
561
+
562
+ elog (MESSAGE_LEVEL , "Index %s: Pages %u; Tuples %.0f.\n\t%s" ,
563
+ RelationGetRelationName (indrel ),
564
+ stats -> num_pages , stats -> num_index_tuples ,
565
+ vac_show_rusage (& ru0 ));
566
+
567
+ pfree (stats );
568
+ }
569
+
498
570
/*
499
571
* lazy_vacuum_index() -- vacuum one index relation.
500
572
*
@@ -955,6 +1027,15 @@ lazy_tid_reaped(ItemPointer itemptr, void *state)
955
1027
return (res != NULL );
956
1028
}
957
1029
1030
+ /*
1031
+ * Dummy version for lazy_scan_index.
1032
+ */
1033
+ static bool
1034
+ dummy_tid_reaped (ItemPointer itemptr , void * state )
1035
+ {
1036
+ return false;
1037
+ }
1038
+
958
1039
/*
959
1040
* Update the shared Free Space Map with the info we now have about
960
1041
* free space in the relation, discarding any old info the map may have.
0 commit comments