From c38ab16dbaf3bb8bfe56da5f2a79a6b975d40f13 Mon Sep 17 00:00:00 2001 From: Amit Kapila Date: Mon, 23 Dec 2019 15:37:09 +0530 Subject: [PATCH v41 3/4] Add FAST option to vacuum command. --- doc/src/sgml/ref/vacuum.sgml | 13 +++++++++ src/backend/access/heap/vacuumlazy.c | 43 +++++++++++++++++----------- src/backend/commands/vacuum.c | 9 ++++-- src/include/commands/vacuum.h | 3 +- src/test/regress/expected/vacuum.out | 3 ++ src/test/regress/sql/vacuum.sql | 4 +++ 6 files changed, 56 insertions(+), 19 deletions(-) diff --git a/doc/src/sgml/ref/vacuum.sgml b/doc/src/sgml/ref/vacuum.sgml index 9fee083233..b190cb0a98 100644 --- a/doc/src/sgml/ref/vacuum.sgml +++ b/doc/src/sgml/ref/vacuum.sgml @@ -35,6 +35,7 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ boolean ] TRUNCATE [ boolean ] PARALLEL [ integer ] + FAST [ boolean ] and table_and_columns is: @@ -250,6 +251,18 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ parameter set to zero. + + + + boolean diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c index 7231fa2923..74637c3a0e 100644 --- a/src/backend/access/heap/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -218,6 +218,13 @@ typedef struct LVShared */ pg_atomic_uint32 active_nworkers; + /* + * True if we forcibly disable cost-based vacuum delay during parallel + * index vacuum. This can be true when use specified the FAST vacuum + * option. + */ + bool fast; + /* * Variables to control parallel index vacuuming. We have a bitmap to * indicate which index has stats in shared memory. The set bit in the @@ -353,7 +360,7 @@ static void update_index_statistics(Relation *Irel, IndexBulkDeleteResult **stat int nindexes); static LVParallelState *begin_parallel_vacuum(Oid relid, Relation *Irel, LVRelStats *vacrelstats, BlockNumber nblocks, - int nindexes, int nrequested); + int nindexes, VacuumParams *params); static void end_parallel_vacuum(Relation *Irel, IndexBulkDeleteResult **stats, LVParallelState *lps, int nindexes); static LVSharedIndStats *get_indstats(LVShared *lvshared, int n); @@ -756,7 +763,7 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, if (params->nworkers >= 0 && vacrelstats->useindex) lps = begin_parallel_vacuum(RelationGetRelid(onerel), Irel, vacrelstats, nblocks, nindexes, - params->nworkers); + params); /* * Allocate the space for dead tuples in case the parallel vacuum is not @@ -2006,16 +2013,19 @@ lazy_parallel_vacuum_indexes(Relation *Irel, IndexBulkDeleteResult **stats, ReinitializeParallelDSM(lps->pcxt); } - /* Enable shared cost balance */ - VacuumSharedCostBalance = &(lps->lvshared->cost_balance); - VacuumActiveNWorkers = &(lps->lvshared->active_nworkers); + if (!lps->lvshared->fast) + { + /* Enable shared cost balance */ + VacuumSharedCostBalance = &(lps->lvshared->cost_balance); + VacuumActiveNWorkers = &(lps->lvshared->active_nworkers); - /* - * Set up shared cost balance and the number of active workers for - * vacuum delay. - */ - pg_atomic_write_u32(VacuumSharedCostBalance, VacuumCostBalance); - pg_atomic_write_u32(VacuumActiveNWorkers, 0); + /* + * Set up shared cost balance and the number of active workers for + * vacuum delay. + */ + pg_atomic_write_u32(VacuumSharedCostBalance, VacuumCostBalance); + pg_atomic_write_u32(VacuumActiveNWorkers, 0); + } /* * The number of workers can vary between bulkdelete and cleanup @@ -2034,7 +2044,7 @@ lazy_parallel_vacuum_indexes(Relation *Irel, IndexBulkDeleteResult **stats, VacuumCostBalance = 0; VacuumCostBalanceLocal = 0; } - else + else if (!lps->lvshared->fast) { /* * Disable shared cost balance if we are not able to launch @@ -3052,7 +3062,7 @@ update_index_statistics(Relation *Irel, IndexBulkDeleteResult **stats, */ static LVParallelState * begin_parallel_vacuum(Oid relid, Relation *Irel, LVRelStats *vacrelstats, - BlockNumber nblocks, int nindexes, int nrequested) + BlockNumber nblocks, int nindexes, VacuumParams *params) { LVParallelState *lps = NULL; ParallelContext *pcxt; @@ -3072,7 +3082,7 @@ begin_parallel_vacuum(Oid relid, Relation *Irel, LVRelStats *vacrelstats, * a parallel vacuum must be requested and there must be indexes on the * relation */ - Assert(nrequested >= 0); + Assert(params->nworkers >= 0); Assert(nindexes > 0); /* @@ -3080,7 +3090,7 @@ begin_parallel_vacuum(Oid relid, Relation *Irel, LVRelStats *vacrelstats, */ can_parallel_vacuum = (bool *) palloc0(sizeof(bool) * nindexes); parallel_workers = compute_parallel_vacuum_workers(Irel, nindexes, - nrequested, + params->nworkers, can_parallel_vacuum); /* Can't perform vacuum in parallel */ @@ -3158,6 +3168,7 @@ begin_parallel_vacuum(Oid relid, Relation *Irel, LVRelStats *vacrelstats, (nindexes_mwm > 0) ? maintenance_work_mem / Min(parallel_workers, nindexes_mwm) : maintenance_work_mem; + shared->fast = (params->options & VACOPT_FAST); /* * We need to care about alignment because we estimate the shared memory @@ -3347,7 +3358,7 @@ parallel_vacuum_main(dsm_segment *seg, shm_toc *toc) false); /* Set cost-based vacuum delay */ - VacuumCostActive = (VacuumCostDelay > 0); + VacuumCostActive = ((VacuumCostDelay > 0) && !(lvshared->fast)); VacuumCostBalance = 0; VacuumPageHit = 0; VacuumPageMiss = 0; diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 0672be27f1..3019a72325 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -101,6 +101,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel) bool verbose = false; bool skip_locked = false; bool analyze = false; + bool fast = false; bool freeze = false; bool full = false; bool disable_page_skipping = false; @@ -130,6 +131,8 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel) /* Parse options available on VACUUM */ else if (strcmp(opt->defname, "analyze") == 0) analyze = defGetBoolean(opt); + else if (strcmp(opt->defname, "fast") == 0) + fast = defGetBoolean(opt); else if (strcmp(opt->defname, "freeze") == 0) freeze = defGetBoolean(opt); else if (strcmp(opt->defname, "full") == 0) @@ -177,7 +180,8 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel) (analyze ? VACOPT_ANALYZE : 0) | (freeze ? VACOPT_FREEZE : 0) | (full ? VACOPT_FULL : 0) | - (disable_page_skipping ? VACOPT_DISABLE_PAGE_SKIPPING : 0); + (disable_page_skipping ? VACOPT_DISABLE_PAGE_SKIPPING : 0) | + (fast ? VACOPT_FAST : 0); /* sanity checks on options */ Assert(params.options & (VACOPT_VACUUM | VACOPT_ANALYZE)); @@ -416,7 +420,8 @@ vacuum(List *relations, VacuumParams *params, ListCell *cur; in_vacuum = true; - VacuumCostActive = (VacuumCostDelay > 0); + VacuumCostActive = ((VacuumCostDelay > 0) && + !(params->options & VACOPT_FAST)); VacuumCostBalance = 0; VacuumPageHit = 0; VacuumPageMiss = 0; diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 254a6bcda6..faed3f9718 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -183,7 +183,8 @@ typedef enum VacuumOption VACOPT_FULL = 1 << 4, /* FULL (non-concurrent) vacuum */ VACOPT_SKIP_LOCKED = 1 << 5, /* skip if cannot get lock */ VACOPT_SKIPTOAST = 1 << 6, /* don't process the TOAST table, if any */ - VACOPT_DISABLE_PAGE_SKIPPING = 1 << 7 /* don't skip any pages */ + VACOPT_DISABLE_PAGE_SKIPPING = 1 << 7, /* don't skip any pages */ + VACOPT_FAST = 1 << 8 /* disable vacuum delay */ } VacuumOption; /* diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index 8571133fe7..07c7b88a16 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -118,6 +118,9 @@ CREATE TEMPORARY TABLE tmp (a int PRIMARY KEY); CREATE INDEX tmp_idx1 ON tmp (a); VACUUM (PARALLEL 1) tmp; -- disables parallel vacuum option WARNING: disabling parallel option of vacuum on "tmp" --- cannot vacuum temporary tables in parallel +--test FAST option +UPDATE pvactst SET i = i WHERE i < 1000; +VACUUM (FAST) pvactst; RESET min_parallel_index_scan_size; DROP TABLE pvactst; -- INDEX_CLEANUP option diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index be4f55616e..6227ab9423 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -99,6 +99,10 @@ VACUUM (PARALLEL 2, FULL TRUE) pvactst; -- error, cannot use both PARALLEL and F CREATE TEMPORARY TABLE tmp (a int PRIMARY KEY); CREATE INDEX tmp_idx1 ON tmp (a); VACUUM (PARALLEL 1) tmp; -- disables parallel vacuum option + +--test FAST option +UPDATE pvactst SET i = i WHERE i < 1000; +VACUUM (FAST) pvactst; RESET min_parallel_index_scan_size; DROP TABLE pvactst; -- 2.23.0