1
1
/*-------------------------------------------------------------------------
2
2
*
3
3
* vacuum.c
4
- * the postgres vacuum cleaner
4
+ * The postgres vacuum cleaner.
5
+ *
6
+ * This file includes the "full" version of VACUUM, as well as control code
7
+ * used by all three of full VACUUM, lazy VACUUM, and ANALYZE. See
8
+ * vacuumlazy.c and analyze.c for the rest of the code for the latter two.
9
+ *
5
10
*
6
11
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
7
12
* Portions Copyright (c) 1994, Regents of the University of California
8
13
*
9
14
*
10
15
* IDENTIFICATION
11
- * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.203 2001/07/12 04:11:13 tgl Exp $
16
+ * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.204 2001/07/13 22:55:59 tgl Exp $
12
17
*
13
18
*-------------------------------------------------------------------------
14
19
*/
15
20
#include "postgres.h"
16
21
17
- #include <fcntl.h>
18
22
#include <unistd.h>
19
- #include <sys/types.h>
20
- #include <sys/file.h>
21
- #include <sys/stat.h>
22
23
23
24
#include "access/genam.h"
24
25
#include "access/heapam.h"
25
26
#include "access/xlog.h"
26
27
#include "catalog/catalog.h"
27
28
#include "catalog/catname.h"
28
- #include "catalog/index.h"
29
29
#include "catalog/pg_index.h"
30
30
#include "commands/vacuum.h"
31
31
#include "executor/executor.h"
32
32
#include "miscadmin.h"
33
- #include "nodes/execnodes.h"
34
33
#include "storage/freespace.h"
35
34
#include "storage/sinval.h"
36
35
#include "storage/smgr.h"
37
36
#include "tcop/pquery.h"
38
- #include "tcop/tcopprot.h"
39
37
#include "utils/acl.h"
40
38
#include "utils/builtins.h"
41
39
#include "utils/fmgroids.h"
@@ -123,7 +121,7 @@ static void scan_heap(VRelStats *vacrelstats, Relation onerel,
123
121
VacPageList vacuum_pages , VacPageList fraged_pages );
124
122
static void repair_frag (VRelStats * vacrelstats , Relation onerel ,
125
123
VacPageList vacuum_pages , VacPageList fraged_pages ,
126
- int nindices , Relation * Irel );
124
+ int nindexes , Relation * Irel );
127
125
static void vacuum_heap (VRelStats * vacrelstats , Relation onerel ,
128
126
VacPageList vacpagelist );
129
127
static void vacuum_page (Relation onerel , Buffer buffer , VacPage vacpage );
@@ -135,8 +133,6 @@ static void vac_update_fsm(Relation onerel, VacPageList fraged_pages,
135
133
BlockNumber rel_pages );
136
134
static VacPage copy_vac_page (VacPage vacpage );
137
135
static void vpage_insert (VacPageList vacpagelist , VacPage vpnew );
138
- static void get_indices (Relation relation , int * nindices , Relation * * Irel );
139
- static void close_indices (int nindices , Relation * Irel );
140
136
static bool is_partial_index (Relation indrel );
141
137
static void * vac_bsearch (const void * key , const void * base ,
142
138
size_t nelem , size_t size ,
@@ -455,14 +451,6 @@ vac_update_relstats(Oid relid, BlockNumber num_pages, double num_tuples,
455
451
*/
456
452
457
453
458
- /* XXX Temporary placeholder */
459
- static void
460
- lazy_vacuum_rel (Relation onerel )
461
- {
462
- full_vacuum_rel (onerel );
463
- }
464
-
465
-
466
454
/*
467
455
* vacuum_rel() -- vacuum one heap relation
468
456
*
@@ -554,11 +542,17 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt)
554
542
555
543
/*
556
544
* Do the actual work --- either FULL or "lazy" vacuum
545
+ *
546
+ * XXX for the moment, lazy vac not supported unless CONCURRENT_VACUUM
557
547
*/
548
+ #ifdef CONCURRENT_VACUUM
558
549
if (vacstmt -> full )
559
550
full_vacuum_rel (onerel );
560
551
else
561
- lazy_vacuum_rel (onerel );
552
+ lazy_vacuum_rel (onerel , vacstmt );
553
+ #else
554
+ full_vacuum_rel (onerel );
555
+ #endif
562
556
563
557
/* all done with this class, but hold lock until commit */
564
558
heap_close (onerel , NoLock );
@@ -596,7 +590,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt)
596
590
/*
597
591
* full_vacuum_rel() -- perform FULL VACUUM for one heap relation
598
592
*
599
- * This routine vacuums a single heap, cleans out its indices , and
593
+ * This routine vacuums a single heap, cleans out its indexes , and
600
594
* updates its num_pages and num_tuples statistics.
601
595
*
602
596
* At entry, we have already established a transaction and opened
@@ -606,11 +600,11 @@ static void
606
600
full_vacuum_rel (Relation onerel )
607
601
{
608
602
VacPageListData vacuum_pages ; /* List of pages to vacuum and/or
609
- * clean indices */
603
+ * clean indexes */
610
604
VacPageListData fraged_pages ; /* List of pages with space enough
611
605
* for re-using */
612
606
Relation * Irel ;
613
- int32 nindices ,
607
+ int nindexes ,
614
608
i ;
615
609
VRelStats * vacrelstats ;
616
610
bool reindex = false;
@@ -633,15 +627,13 @@ full_vacuum_rel(Relation onerel)
633
627
vacuum_pages .num_pages = fraged_pages .num_pages = 0 ;
634
628
scan_heap (vacrelstats , onerel , & vacuum_pages , & fraged_pages );
635
629
636
- /* Now open all indices of the relation */
637
- nindices = 0 ;
638
- Irel = (Relation * ) NULL ;
639
- get_indices (onerel , & nindices , & Irel );
630
+ /* Now open all indexes of the relation */
631
+ vac_open_indexes (onerel , & nindexes , & Irel );
640
632
if (!Irel )
641
633
reindex = false;
642
634
else if (!RelationGetForm (onerel )-> relhasindex )
643
635
reindex = true;
644
- if (nindices > 0 )
636
+ if (nindexes > 0 )
645
637
vacrelstats -> hasindex = true;
646
638
647
639
#ifdef NOT_USED
@@ -651,7 +643,7 @@ full_vacuum_rel(Relation onerel)
651
643
*/
652
644
if (reindex )
653
645
{
654
- close_indices ( nindices , Irel );
646
+ vac_close_indexes ( nindexes , Irel );
655
647
Irel = (Relation * ) NULL ;
656
648
activate_indexes_of_a_table (RelationGetRelid (onerel ), false);
657
649
}
@@ -662,14 +654,14 @@ full_vacuum_rel(Relation onerel)
662
654
{
663
655
if (vacuum_pages .num_pages > 0 )
664
656
{
665
- for (i = 0 ; i < nindices ; i ++ )
657
+ for (i = 0 ; i < nindexes ; i ++ )
666
658
vacuum_index (& vacuum_pages , Irel [i ],
667
659
vacrelstats -> rel_tuples , 0 );
668
660
}
669
661
else
670
662
{
671
- /* just scan indices to update statistic */
672
- for (i = 0 ; i < nindices ; i ++ )
663
+ /* just scan indexes to update statistic */
664
+ for (i = 0 ; i < nindexes ; i ++ )
673
665
scan_index (Irel [i ], vacrelstats -> rel_tuples );
674
666
}
675
667
}
@@ -678,12 +670,12 @@ full_vacuum_rel(Relation onerel)
678
670
{
679
671
/* Try to shrink heap */
680
672
repair_frag (vacrelstats , onerel , & vacuum_pages , & fraged_pages ,
681
- nindices , Irel );
682
- close_indices ( nindices , Irel );
673
+ nindexes , Irel );
674
+ vac_close_indexes ( nindexes , Irel );
683
675
}
684
676
else
685
677
{
686
- close_indices ( nindices , Irel );
678
+ vac_close_indexes ( nindexes , Irel );
687
679
if (vacuum_pages .num_pages > 0 )
688
680
{
689
681
/* Clean pages from vacuum_pages list */
@@ -835,7 +827,7 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
835
827
itemid = PageGetItemId (page , offnum );
836
828
837
829
/*
838
- * Collect un-used items too - it's possible to have indices
830
+ * Collect un-used items too - it's possible to have indexes
839
831
* pointing here after crash.
840
832
*/
841
833
if (!ItemIdIsUsed (itemid ))
@@ -944,7 +936,7 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
944
936
}
945
937
946
938
/* mark it unused on the temp page */
947
- lpp = & ((( PageHeader ) tempPage ) -> pd_linp [ offnum - 1 ] );
939
+ lpp = PageGetItemId ( tempPage , offnum );
948
940
lpp -> lp_flags &= ~LP_USED ;
949
941
950
942
vacpage -> offsets [vacpage -> offsets_free ++ ] = offnum ;
@@ -1073,16 +1065,16 @@ Re-using: Free/Avail. Space %.0f/%.0f; EndEmpty/Avail. Pages %u/%u. %s",
1073
1065
* repair_frag() -- try to repair relation's fragmentation
1074
1066
*
1075
1067
* This routine marks dead tuples as unused and tries re-use dead space
1076
- * by moving tuples (and inserting indices if needed). It constructs
1077
- * Nvacpagelist list of free-ed pages (moved tuples) and clean indices
1068
+ * by moving tuples (and inserting indexes if needed). It constructs
1069
+ * Nvacpagelist list of free-ed pages (moved tuples) and clean indexes
1078
1070
* for them after committing (in hack-manner - without losing locks
1079
1071
* and freeing memory!) current transaction. It truncates relation
1080
1072
* if some end-blocks are gone away.
1081
1073
*/
1082
1074
static void
1083
1075
repair_frag (VRelStats * vacrelstats , Relation onerel ,
1084
1076
VacPageList vacuum_pages , VacPageList fraged_pages ,
1085
- int nindices , Relation * Irel )
1077
+ int nindexes , Relation * Irel )
1086
1078
{
1087
1079
TransactionId myXID ;
1088
1080
CommandId myCID ;
@@ -1884,7 +1876,7 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
1884
1876
* relation. Ideally we should do Commit/StartTransactionCommand
1885
1877
* here, relying on the session-level table lock to protect our
1886
1878
* exclusive access to the relation. However, that would require
1887
- * a lot of extra code to close and re-open the relation, indices ,
1879
+ * a lot of extra code to close and re-open the relation, indexes ,
1888
1880
* etc. For now, a quick hack: record status of current
1889
1881
* transaction as committed, and continue.
1890
1882
*/
@@ -1985,7 +1977,7 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
1985
1977
1986
1978
if (Nvacpagelist .num_pages > 0 )
1987
1979
{
1988
- /* vacuum indices again if needed */
1980
+ /* vacuum indexes again if needed */
1989
1981
if (Irel != (Relation * ) NULL )
1990
1982
{
1991
1983
VacPage * vpleft ,
@@ -2002,7 +1994,7 @@ repair_frag(VRelStats *vacrelstats, Relation onerel,
2002
1994
* vpright = vpsave ;
2003
1995
}
2004
1996
Assert (keep_tuples >= 0 );
2005
- for (i = 0 ; i < nindices ; i ++ )
1997
+ for (i = 0 ; i < nindexes ; i ++ )
2006
1998
vacuum_index (& Nvacpagelist , Irel [i ],
2007
1999
vacrelstats -> rel_tuples , keep_tuples );
2008
2000
}
@@ -2175,7 +2167,7 @@ vacuum_page(Relation onerel, Buffer buffer, VacPage vacpage)
2175
2167
START_CRIT_SECTION ();
2176
2168
for (i = 0 ; i < vacpage -> offsets_free ; i ++ )
2177
2169
{
2178
- itemid = & ((( PageHeader ) page ) -> pd_linp [ vacpage -> offsets [i ] - 1 ]);
2170
+ itemid = PageGetItemId ( page , vacpage -> offsets [i ]);
2179
2171
itemid -> lp_flags &= ~LP_USED ;
2180
2172
}
2181
2173
uncnt = PageRepairFragmentation (page , unused );
@@ -2244,9 +2236,9 @@ scan_index(Relation indrel, double num_tuples)
2244
2236
*
2245
2237
* Vpl is the VacPageList of the heap we're currently vacuuming.
2246
2238
* It's locked. Indrel is an index relation on the vacuumed heap.
2247
- * We don't set locks on the index relation here, since the indexed
2248
- * access methods support locking at different granularities.
2249
- * We let them handle it .
2239
+ *
2240
+ * We don't bother to set locks on the index relation here, since
2241
+ * the parent table is exclusive-locked already .
2250
2242
*
2251
2243
* Finally, we arrange to update the index relation's statistics in
2252
2244
* pg_class.
@@ -2555,19 +2547,19 @@ vac_cmp_vtlinks(const void *left, const void *right)
2555
2547
}
2556
2548
2557
2549
2558
- static void
2559
- get_indices (Relation relation , int * nindices , Relation * * Irel )
2550
+ void
2551
+ vac_open_indexes (Relation relation , int * nindexes , Relation * * Irel )
2560
2552
{
2561
2553
List * indexoidlist ,
2562
2554
* indexoidscan ;
2563
2555
int i ;
2564
2556
2565
2557
indexoidlist = RelationGetIndexList (relation );
2566
2558
2567
- * nindices = length (indexoidlist );
2559
+ * nindexes = length (indexoidlist );
2568
2560
2569
- if (* nindices > 0 )
2570
- * Irel = (Relation * ) palloc (* nindices * sizeof (Relation ));
2561
+ if (* nindexes > 0 )
2562
+ * Irel = (Relation * ) palloc (* nindexes * sizeof (Relation ));
2571
2563
else
2572
2564
* Irel = NULL ;
2573
2565
@@ -2584,14 +2576,14 @@ get_indices(Relation relation, int *nindices, Relation **Irel)
2584
2576
}
2585
2577
2586
2578
2587
- static void
2588
- close_indices (int nindices , Relation * Irel )
2579
+ void
2580
+ vac_close_indexes (int nindexes , Relation * Irel )
2589
2581
{
2590
2582
if (Irel == (Relation * ) NULL )
2591
2583
return ;
2592
2584
2593
- while (nindices -- )
2594
- index_close (Irel [nindices ]);
2585
+ while (nindexes -- )
2586
+ index_close (Irel [nindexes ]);
2595
2587
pfree (Irel );
2596
2588
}
2597
2589
@@ -2621,22 +2613,20 @@ is_partial_index(Relation indrel)
2621
2613
static bool
2622
2614
enough_space (VacPage vacpage , Size len )
2623
2615
{
2624
-
2625
2616
len = MAXALIGN (len );
2626
2617
2627
2618
if (len > vacpage -> free )
2628
2619
return false;
2629
2620
2630
- if ( vacpage -> offsets_used < vacpage -> offsets_free ) /* there are free
2631
- * itemid(s) */
2632
- return true; /* and len <= free_space */
2621
+ /* if there are free itemid(s) and len <= free_space... */
2622
+ if ( vacpage -> offsets_used < vacpage -> offsets_free )
2623
+ return true;
2633
2624
2634
- /* ok. noff_usd >= noff_free and so we'll have to allocate new itemid */
2635
- if (len + MAXALIGN ( sizeof (ItemIdData ) ) <= vacpage -> free )
2625
+ /* noff_used >= noff_free and so we'll have to allocate new itemid */
2626
+ if (len + sizeof (ItemIdData ) <= vacpage -> free )
2636
2627
return true;
2637
2628
2638
2629
return false;
2639
-
2640
2630
}
2641
2631
2642
2632
0 commit comments