From 560df7cb72a550d813ca1152f2732bde20df6fa2 Mon Sep 17 00:00:00 2001 From: Dilip Kumar Date: Sun, 27 Oct 2019 16:19:51 +0530 Subject: [PATCH 1/2] compute total cost delay --- src/backend/access/heap/vacuumlazy.c | 59 ++++++++++++++++++++++++++++++++++++ src/backend/commands/vacuum.c | 1 + src/backend/utils/init/globals.c | 2 +- src/include/miscadmin.h | 1 + 4 files changed, 62 insertions(+), 1 deletion(-) diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c index 02040c8..d7e99d7 100644 --- a/src/backend/access/heap/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -137,6 +137,7 @@ #define PARALLEL_VACUUM_KEY_SHARED 1 #define PARALLEL_VACUUM_KEY_DEAD_TUPLES 2 #define PARALLEL_VACUUM_KEY_QUERY_TEXT 3 +#define PARALLEL_VACUUM_KEY_COST_DELAY 4 /* * PARALLEL_VACUUM_DISABLE_LEADER_PARTICIPATION disables the leader's @@ -247,6 +248,13 @@ typedef struct LVSharedIndStats #define GetIndexBulkDeleteResult(s) \ ((IndexBulkDeleteResult *)((char *)(s) + sizeof(LVSharedIndStats))) +typedef struct LVCostDelay +{ + pg_atomic_uint32 nslot; + double vaccostdelay[FLEXIBLE_ARRAY_MEMBER]; +} LVCostDelay; +#define SizeOfLVCostDelay offsetof(LVCostDelay, vaccostdelay) + sizeof(double) + /* Struct for parallel lazy vacuum */ typedef struct LVParallelState { @@ -255,6 +263,8 @@ typedef struct LVParallelState /* Shared information among parallel vacuum workers */ LVShared *lvshared; + /* Shared cost delay. */ + LVCostDelay *lvcostdelay; /* * Always true except for a debugging case where * PARALLEL_VACUUM_DISABLE_LEADER_PARTICIPATION are defined. @@ -746,6 +756,7 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, parallel_workers = compute_parallel_workers(Irel, nindexes, params->nworkers); + VacuumCostTotalDelay = 0; if (parallel_workers > 0) { /* @@ -1722,6 +1733,8 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, vacrelstats->scanned_pages, nblocks), errdetail_internal("%s", buf.data))); pfree(buf.data); + + elog(LOG, "Total cost delay = %lf", VacuumCostTotalDelay); } @@ -1956,6 +1969,9 @@ lazy_parallel_vacuum_or_cleanup_indexes(LVRelStats *vacrelstats, Relation *Irel, int nindexes, IndexBulkDeleteResult **stats, LVParallelState *lps) { + int i; + double costdelay; + Assert(!IsParallelWorker()); Assert(ParallelVacuumIsActive(lps)); Assert(nindexes > 0); @@ -1976,6 +1992,14 @@ lazy_parallel_vacuum_or_cleanup_indexes(LVRelStats *vacrelstats, Relation *Irel, lps->pcxt->nworkers_launched, lps->pcxt->nworkers))); /* + * Remember the total delay so far and set the VacuumCostTotalDelay so that + * we can get the leader contribution in total delay in index vacuuming + * phase. + */ + costdelay = VacuumCostTotalDelay; + VacuumCostTotalDelay = 0; + + /* * Join as parallel workers. The leader process alone does that in case where * no workers launched. */ @@ -1986,6 +2010,22 @@ lazy_parallel_vacuum_or_cleanup_indexes(LVRelStats *vacrelstats, Relation *Irel, /* Wait for all vacuum workers to finish */ WaitForParallelWorkersToFinish(lps->pcxt); + /* Collect all the delay from wrokers and add to total delay. */ + for (i = 0; i < lps->pcxt->nworkers_launched; i++) + { + VacuumCostTotalDelay += lps->lvcostdelay->vaccostdelay[i]; + } + + /* + * Compute the average cost delay. + */ + if (lps->leaderparticipates) + VacuumCostTotalDelay /= (lps->pcxt->nworkers_launched + 1); + else + VacuumCostTotalDelay /= lps->pcxt->nworkers_launched; + + VacuumCostTotalDelay += costdelay; + /* * We need to reinitialize the parallel context as no more index vacuuming and * index cleanup will be performed after that. @@ -2943,10 +2983,12 @@ begin_parallel_vacuum(LVRelStats *vacrelstats, Oid relid, BlockNumber nblocks, ParallelContext *pcxt; LVShared *shared; LVDeadTuples *dead_tuples; + LVCostDelay *costdelay; long maxtuples; char *sharedquery; Size est_shared; Size est_deadtuples; + Size est_costdelay; int querylen; int i; @@ -3016,6 +3058,14 @@ begin_parallel_vacuum(LVRelStats *vacrelstats, Oid relid, BlockNumber nblocks, memcpy(sharedquery, debug_query_string, querylen + 1); sharedquery[querylen] = '\0'; shm_toc_insert(pcxt->toc, PARALLEL_VACUUM_KEY_QUERY_TEXT, sharedquery); + + /* Vacuum cost balance. */ + est_costdelay = MAXALIGN(add_size(SizeOfLVCostDelay, + mul_size(sizeof(int), nrequested))); + costdelay = (LVCostDelay *) shm_toc_allocate(pcxt->toc, est_costdelay); + pg_atomic_init_u32(&(costdelay->nslot), 0); + shm_toc_insert(pcxt->toc, PARALLEL_VACUUM_KEY_COST_DELAY, costdelay); + lps->lvcostdelay = costdelay; return lps; } @@ -3145,8 +3195,10 @@ heap_parallel_vacuum_main(dsm_segment *seg, shm_toc *toc) Relation *indrels; LVShared *lvshared; LVDeadTuples *dead_tuples; + LVCostDelay *costdelay; int nindexes; char *sharedquery; + int slot; IndexBulkDeleteResult **stats; lvshared = (LVShared *) shm_toc_lookup(toc, PARALLEL_VACUUM_KEY_SHARED, @@ -3180,6 +3232,11 @@ heap_parallel_vacuum_main(dsm_segment *seg, shm_toc *toc) dead_tuples = (LVDeadTuples *) shm_toc_lookup(toc, PARALLEL_VACUUM_KEY_DEAD_TUPLES, false); + + costdelay = (LVCostDelay *) shm_toc_lookup(toc, + PARALLEL_VACUUM_KEY_COST_DELAY, + false); + slot = pg_atomic_fetch_add_u32(&(costdelay->nslot), 1); /* Set cost-based vacuum delay */ VacuumCostActive = (VacuumCostDelay > 0); @@ -3198,6 +3255,8 @@ heap_parallel_vacuum_main(dsm_segment *seg, shm_toc *toc) vacuum_or_cleanup_indexes_worker(indrels, nindexes, stats, lvshared, dead_tuples); + /* update the total delay in the shared location. */ + costdelay->vaccostdelay[slot] = VacuumCostTotalDelay; vac_close_indexes(nindexes, indrels, RowExclusiveLock); table_close(onerel, ShareUpdateExclusiveLock); } diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 9ada501..56fdefd 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2010,6 +2010,7 @@ vacuum_delay_point(void) /* update balance values for workers */ AutoVacuumUpdateDelay(); + VacuumCostTotalDelay += msec; /* Might have gotten an interrupt while sleeping */ CHECK_FOR_INTERRUPTS(); } diff --git a/src/backend/utils/init/globals.c b/src/backend/utils/init/globals.c index 3bf96de..a5a1129 100644 --- a/src/backend/utils/init/globals.c +++ b/src/backend/utils/init/globals.c @@ -139,7 +139,7 @@ int VacuumCostPageMiss = 10; int VacuumCostPageDirty = 20; int VacuumCostLimit = 200; double VacuumCostDelay = 0; - +double VacuumCostTotalDelay = 0; int VacuumPageHit = 0; int VacuumPageMiss = 0; int VacuumPageDirty = 0; diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h index bc6e03f..ab1c0ce 100644 --- a/src/include/miscadmin.h +++ b/src/include/miscadmin.h @@ -251,6 +251,7 @@ extern int VacuumCostPageMiss; extern int VacuumCostPageDirty; extern int VacuumCostLimit; extern double VacuumCostDelay; +extern double VacuumCostTotalDelay; extern int VacuumPageHit; extern int VacuumPageMiss; -- 1.8.3.1