@@ -149,26 +149,6 @@ typedef enum
149149VACUUM_ERRCB_PHASE_TRUNCATE
150150}VacErrPhase ;
151151
152- /*
153- * LVDeadItems stores TIDs whose index tuples are deleted by index vacuuming.
154- * Each TID points to an LP_DEAD line pointer from a heap page that has been
155- * processed by lazy_scan_prune.
156- *
157- * Also needed by lazy_vacuum_heap_rel, which marks the same LP_DEAD line
158- * pointers as LP_UNUSED during second heap pass.
159- */
160- typedef struct LVDeadItems
161- {
162- int max_items ;/* # slots allocated in array */
163- int num_items ;/* current # of entries */
164-
165- /* Sorted array of TIDs to delete from indexes */
166- ItemPointerData items [FLEXIBLE_ARRAY_MEMBER ];
167- }LVDeadItems ;
168-
169- #define MAXDEADITEMS (avail_mem ) \
170- (((avail_mem) - offsetof(LVDeadItems, items)) / sizeof(ItemPointerData))
171-
172152/*
173153 * Shared information among parallel workers. So this is allocated in the DSM
174154 * segment.
@@ -339,9 +319,15 @@ typedef struct LVRelState
339319VacErrPhase phase ;
340320
341321/*
342- * State managed by lazy_scan_heap() follows
322+ * State managed by lazy_scan_heap() follows.
323+ *
324+ * dead_items stores TIDs whose index tuples are deleted by index
325+ * vacuuming. Each TID points to an LP_DEAD line pointer from a heap page
326+ * that has been processed by lazy_scan_prune. Also needed by
327+ * lazy_vacuum_heap_rel, which marks the same LP_DEAD line pointers as
328+ * LP_UNUSED during second heap pass.
343329 */
344- LVDeadItems * dead_items ;/* TIDs whose index tuples we'll delete */
330+ VacDeadItems * dead_items ;/* TIDs whose index tuples we'll delete */
345331BlockNumber rel_pages ;/* total number of pages */
346332BlockNumber scanned_pages ;/* number of pages we examined */
347333BlockNumber pinskipped_pages ;/* # of pages skipped due to a pin */
@@ -434,11 +420,8 @@ static void lazy_truncate_heap(LVRelState *vacrel);
434420static BlockNumber count_nondeletable_pages (LVRelState * vacrel ,
435421bool * lock_waiter_detected );
436422static int dead_items_max_items (LVRelState * vacrel );
437- static inline Size max_items_to_alloc_size (int max_items );
438423static void dead_items_alloc (LVRelState * vacrel ,int nworkers );
439424static void dead_items_cleanup (LVRelState * vacrel );
440- static bool lazy_tid_reaped (ItemPointer itemptr ,void * state );
441- static int vac_cmp_itemptr (const void * left ,const void * right );
442425static bool heap_page_is_all_visible (LVRelState * vacrel ,Buffer buf ,
443426TransactionId * visibility_cutoff_xid ,bool * all_frozen );
444427static int parallel_vacuum_compute_workers (LVRelState * vacrel ,int nrequested ,
@@ -905,7 +888,7 @@ heap_vacuum_rel(Relation rel, VacuumParams *params,
905888static void
906889lazy_scan_heap (LVRelState * vacrel ,VacuumParams * params ,bool aggressive )
907890{
908- LVDeadItems * dead_items ;
891+ VacDeadItems * dead_items ;
909892BlockNumber nblocks ,
910893blkno ,
911894next_unskippable_block ,
@@ -2040,7 +2023,7 @@ lazy_scan_prune(LVRelState *vacrel,
20402023 */
20412024if (lpdead_items > 0 )
20422025{
2043- LVDeadItems * dead_items = vacrel -> dead_items ;
2026+ VacDeadItems * dead_items = vacrel -> dead_items ;
20442027ItemPointerData tmp ;
20452028
20462029Assert (!prunestate -> all_visible );
@@ -2404,7 +2387,7 @@ static int
24042387lazy_vacuum_heap_page (LVRelState * vacrel ,BlockNumber blkno ,Buffer buffer ,
24052388int index ,Buffer * vmbuffer )
24062389{
2407- LVDeadItems * dead_items = vacrel -> dead_items ;
2390+ VacDeadItems * dead_items = vacrel -> dead_items ;
24082391Page page = BufferGetPage (buffer );
24092392OffsetNumber unused [MaxHeapTuplesPerPage ];
24102393int uncnt = 0 ;
@@ -3019,11 +3002,8 @@ lazy_vacuum_one_index(Relation indrel, IndexBulkDeleteResult *istat,
30193002double reltuples ,LVRelState * vacrel )
30203003{
30213004IndexVacuumInfo ivinfo ;
3022- PGRUsage ru0 ;
30233005LVSavedErrInfo saved_err_info ;
30243006
3025- pg_rusage_init (& ru0 );
3026-
30273007ivinfo .index = indrel ;
30283008ivinfo .analyze_only = false;
30293009ivinfo .report_progress = false;
@@ -3045,13 +3025,7 @@ lazy_vacuum_one_index(Relation indrel, IndexBulkDeleteResult *istat,
30453025InvalidBlockNumber ,InvalidOffsetNumber );
30463026
30473027/* Do bulk deletion */
3048- istat = index_bulk_delete (& ivinfo ,istat ,lazy_tid_reaped ,
3049- (void * )vacrel -> dead_items );
3050-
3051- ereport (elevel ,
3052- (errmsg ("scanned index \"%s\" to remove %d row versions" ,
3053- vacrel -> indname ,vacrel -> dead_items -> num_items ),
3054- errdetail_internal ("%s" ,pg_rusage_show (& ru0 ))));
3028+ istat = vac_bulkdel_one_index (& ivinfo ,istat , (void * )vacrel -> dead_items );
30553029
30563030/* Revert to the previous phase information for error traceback */
30573031restore_vacuum_error_info (vacrel ,& saved_err_info );
@@ -3076,11 +3050,8 @@ lazy_cleanup_one_index(Relation indrel, IndexBulkDeleteResult *istat,
30763050LVRelState * vacrel )
30773051{
30783052IndexVacuumInfo ivinfo ;
3079- PGRUsage ru0 ;
30803053LVSavedErrInfo saved_err_info ;
30813054
3082- pg_rusage_init (& ru0 );
3083-
30843055ivinfo .index = indrel ;
30853056ivinfo .analyze_only = false;
30863057ivinfo .report_progress = false;
@@ -3102,24 +3073,7 @@ lazy_cleanup_one_index(Relation indrel, IndexBulkDeleteResult *istat,
31023073VACUUM_ERRCB_PHASE_INDEX_CLEANUP ,
31033074InvalidBlockNumber ,InvalidOffsetNumber );
31043075
3105- istat = index_vacuum_cleanup (& ivinfo ,istat );
3106-
3107- if (istat )
3108- {
3109- ereport (elevel ,
3110- (errmsg ("index \"%s\" now contains %.0f row versions in %u pages" ,
3111- RelationGetRelationName (indrel ),
3112- istat -> num_index_tuples ,
3113- istat -> num_pages ),
3114- errdetail ("%.0f index row versions were removed.\n"
3115- "%u index pages were newly deleted.\n"
3116- "%u index pages are currently deleted, of which %u are currently reusable.\n"
3117- "%s." ,
3118- istat -> tuples_removed ,
3119- istat -> pages_newly_deleted ,
3120- istat -> pages_deleted ,istat -> pages_free ,
3121- pg_rusage_show (& ru0 ))));
3122- }
3076+ istat = vac_cleanup_one_index (& ivinfo ,istat );
31233077
31243078/* Revert to the previous phase information for error traceback */
31253079restore_vacuum_error_info (vacrel ,& saved_err_info );
@@ -3481,19 +3435,6 @@ dead_items_max_items(LVRelState *vacrel)
34813435return (int )max_items ;
34823436}
34833437
3484- /*
3485- * Returns the total required space for VACUUM's dead_items array given a
3486- * max_items value returned by dead_items_max_items
3487- */
3488- static inline Size
3489- max_items_to_alloc_size (int max_items )
3490- {
3491- Assert (max_items >=MaxHeapTuplesPerPage );
3492- Assert (max_items <=MAXDEADITEMS (MaxAllocSize ));
3493-
3494- return offsetof(LVDeadItems ,items )+ sizeof (ItemPointerData )* max_items ;
3495- }
3496-
34973438/*
34983439 * Allocate dead_items (either using palloc, or in dynamic shared memory).
34993440 * Sets dead_items in vacrel for caller.
@@ -3504,7 +3445,7 @@ max_items_to_alloc_size(int max_items)
35043445static void
35053446dead_items_alloc (LVRelState * vacrel ,int nworkers )
35063447{
3507- LVDeadItems * dead_items ;
3448+ VacDeadItems * dead_items ;
35083449int max_items ;
35093450
35103451/*
@@ -3539,7 +3480,7 @@ dead_items_alloc(LVRelState *vacrel, int nworkers)
35393480
35403481/* Serial VACUUM case */
35413482max_items = dead_items_max_items (vacrel );
3542- dead_items = (LVDeadItems * )palloc (max_items_to_alloc_size (max_items ));
3483+ dead_items = (VacDeadItems * )palloc (vac_max_items_to_alloc_size (max_items ));
35433484dead_items -> max_items = max_items ;
35443485dead_items -> num_items = 0 ;
35453486
@@ -3565,74 +3506,6 @@ dead_items_cleanup(LVRelState *vacrel)
35653506parallel_vacuum_end (vacrel );
35663507}
35673508
3568- /*
3569- *lazy_tid_reaped() -- is a particular tid deletable?
3570- *
3571- *This has the right signature to be an IndexBulkDeleteCallback.
3572- *
3573- *Assumes dead_items array is sorted (in ascending TID order).
3574- */
3575- static bool
3576- lazy_tid_reaped (ItemPointer itemptr ,void * state )
3577- {
3578- LVDeadItems * dead_items = (LVDeadItems * )state ;
3579- int64 litem ,
3580- ritem ,
3581- item ;
3582- ItemPointer res ;
3583-
3584- litem = itemptr_encode (& dead_items -> items [0 ]);
3585- ritem = itemptr_encode (& dead_items -> items [dead_items -> num_items - 1 ]);
3586- item = itemptr_encode (itemptr );
3587-
3588- /*
3589- * Doing a simple bound check before bsearch() is useful to avoid the
3590- * extra cost of bsearch(), especially if dead items on the heap are
3591- * concentrated in a certain range. Since this function is called for
3592- * every index tuple, it pays to be really fast.
3593- */
3594- if (item < litem || item > ritem )
3595- return false;
3596-
3597- res = (ItemPointer )bsearch ((void * )itemptr ,
3598- (void * )dead_items -> items ,
3599- dead_items -> num_items ,
3600- sizeof (ItemPointerData ),
3601- vac_cmp_itemptr );
3602-
3603- return (res != NULL );
3604- }
3605-
3606- /*
3607- * Comparator routines for use with qsort() and bsearch().
3608- */
3609- static int
3610- vac_cmp_itemptr (const void * left ,const void * right )
3611- {
3612- BlockNumber lblk ,
3613- rblk ;
3614- OffsetNumber loff ,
3615- roff ;
3616-
3617- lblk = ItemPointerGetBlockNumber ((ItemPointer )left );
3618- rblk = ItemPointerGetBlockNumber ((ItemPointer )right );
3619-
3620- if (lblk < rblk )
3621- return -1 ;
3622- if (lblk > rblk )
3623- return 1 ;
3624-
3625- loff = ItemPointerGetOffsetNumber ((ItemPointer )left );
3626- roff = ItemPointerGetOffsetNumber ((ItemPointer )right );
3627-
3628- if (loff < roff )
3629- return -1 ;
3630- if (loff > roff )
3631- return 1 ;
3632-
3633- return 0 ;
3634- }
3635-
36363509/*
36373510 * Check if every tuple in the given page is visible to all current and future
36383511 * transactions. Also return the visibility_cutoff_xid which is the highest
@@ -3873,7 +3746,7 @@ parallel_vacuum_begin(LVRelState *vacrel, int nrequested)
38733746int nindexes = vacrel -> nindexes ;
38743747ParallelContext * pcxt ;
38753748LVShared * shared ;
3876- LVDeadItems * dead_items ;
3749+ VacDeadItems * dead_items ;
38773750LVParallelIndStats * pindstats ;
38783751BufferUsage * buffer_usage ;
38793752WalUsage * wal_usage ;
@@ -3927,7 +3800,7 @@ parallel_vacuum_begin(LVRelState *vacrel, int nrequested)
39273800
39283801/* Estimate size for dead_items -- PARALLEL_VACUUM_KEY_DEAD_ITEMS */
39293802max_items = dead_items_max_items (vacrel );
3930- est_dead_items_len = max_items_to_alloc_size (max_items );
3803+ est_dead_items_len = vac_max_items_to_alloc_size (max_items );
39313804shm_toc_estimate_chunk (& pcxt -> estimator ,est_dead_items_len );
39323805shm_toc_estimate_keys (& pcxt -> estimator ,1 );
39333806
@@ -4011,8 +3884,8 @@ parallel_vacuum_begin(LVRelState *vacrel, int nrequested)
40113884lps -> lvshared = shared ;
40123885
40133886/* Prepare the dead_items space */
4014- dead_items = (LVDeadItems * )shm_toc_allocate (pcxt -> toc ,
4015- est_dead_items_len );
3887+ dead_items = (VacDeadItems * )shm_toc_allocate (pcxt -> toc ,
3888+ est_dead_items_len );
40163889dead_items -> max_items = max_items ;
40173890dead_items -> num_items = 0 ;
40183891MemSet (dead_items -> items ,0 ,sizeof (ItemPointerData )* max_items );
@@ -4138,7 +4011,7 @@ parallel_vacuum_main(dsm_segment *seg, shm_toc *toc)
41384011Relation * indrels ;
41394012LVParallelIndStats * lvpindstats ;
41404013LVShared * lvshared ;
4141- LVDeadItems * dead_items ;
4014+ VacDeadItems * dead_items ;
41424015BufferUsage * buffer_usage ;
41434016WalUsage * wal_usage ;
41444017int nindexes ;
@@ -4183,9 +4056,9 @@ parallel_vacuum_main(dsm_segment *seg, shm_toc *toc)
41834056false);
41844057
41854058/* Set dead_items space (set as worker's vacrel dead_items below) */
4186- dead_items = (LVDeadItems * )shm_toc_lookup (toc ,
4187- PARALLEL_VACUUM_KEY_DEAD_ITEMS ,
4188- false);
4059+ dead_items = (VacDeadItems * )shm_toc_lookup (toc ,
4060+ PARALLEL_VACUUM_KEY_DEAD_ITEMS ,
4061+ false);
41894062
41904063/* Set cost-based vacuum delay */
41914064VacuumCostActive = (VacuumCostDelay > 0 );