commit ae501497308a3b245872fc667660a85befd7020d
Author: Mahendra Singh Thalor <mahi6run@gmail.com>
Date:   Fri Nov 8 15:07:22 2019 +0530

    Use parallel vacuum if force_parallel_mode is setted as regress
    
    When force_parallel_mode is setted as regress and parallel option
    is not given with vacuum, then all the work will be done by single
    worker(leader will not do any work).  If user give parallel option,
    then preference will be given to that parallel degree.

diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index a9d9f31..7f2914e 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -67,6 +67,7 @@
 #include "commands/progress.h"
 #include "commands/vacuum.h"
 #include "miscadmin.h"
+#include "optimizer/optimizer.h"
 #include "pgstat.h"
 #include "portability/instr_time.h"
 #include "postmaster/autovacuum.h"
@@ -79,6 +80,7 @@
 #include "utils/pg_rusage.h"
 #include "utils/timestamp.h"
 
+extern	bool    do_vacuum_using_only_single_worker;
 
 /*
  * Space/time tradeoff parameters: do these need to be user-tunable?
@@ -2943,6 +2945,15 @@ compute_parallel_workers(Relation *Irel, int nindexes, int nrequested)
 	leaderparticipates = false;
 #endif
 
+	/*
+	 * If force_parallel_mode is setted as regress, and parallel option is
+	 * not given with vacuum command, then all the vacuum work will be done by
+	 * single worker and leader will not participate.
+	 */
+	if (force_parallel_mode == FORCE_PARALLEL_REGRESS && nrequested == 1 &&
+		do_vacuum_using_only_single_worker)
+		leaderparticipates = false;
+
 	/* The leader process takes one index */
 	if (leaderparticipates)
 		nindexes_to_vacuum--;
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 905d173..a4dc8ba 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -40,6 +40,7 @@
 #include "commands/vacuum.h"
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
+#include "optimizer/optimizer.h"
 #include "pgstat.h"
 #include "postmaster/autovacuum.h"
 #include "postmaster/bgworker_internals.h"
@@ -62,6 +63,7 @@ int			vacuum_freeze_min_age;
 int			vacuum_freeze_table_age;
 int			vacuum_multixact_freeze_min_age;
 int			vacuum_multixact_freeze_table_age;
+bool    do_vacuum_using_only_single_worker = false;
 
 
 /* A few variables that don't seem worth passing around as parameters */
@@ -170,6 +172,20 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
 		(full ? VACOPT_FULL : 0) |
 		(disable_page_skipping ? VACOPT_DISABLE_PAGE_SKIPPING : 0);
 
+	/*
+	 * If force_parallel_mode is setted as regress and there is no parallel
+	 * option is specified with vacuum, then enable parallel vacuum and set
+	 * degree of parallel worker as 1.
+	 */
+	if (params.nworkers == -1 && !(params.options & VACOPT_FULL) &&
+		force_parallel_mode == FORCE_PARALLEL_REGRESS)
+	{
+		do_vacuum_using_only_single_worker = true;
+		params.nworkers = 1;
+	}
+	else
+		do_vacuum_using_only_single_worker = false;
+
 	/* sanity checks on options */
 	Assert(params.options & (VACOPT_VACUUM | VACOPT_ANALYZE));
 	Assert((params.options & VACOPT_VACUUM) ||
