aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/transam/parallel.c
diff options
context:
space:
mode:
authorAmit Kapila <akapila@postgresql.org>2020-01-20 07:57:49 +0530
committerAmit Kapila <akapila@postgresql.org>2020-01-20 07:57:49 +0530
commit40d964ec997f64227bc0ff5e058dc4a5770a70a9 (patch)
treeb1cd42a23dde30447f755edc5ee8cd0fe8d74c31 /src/backend/access/transam/parallel.c
parent44f1fc8df5dadbc5e80661660903aab4076d868f (diff)
downloadpostgresql-40d964ec997f64227bc0ff5e058dc4a5770a70a9.tar.gz
postgresql-40d964ec997f64227bc0ff5e058dc4a5770a70a9.zip
Allow vacuum command to process indexes in parallel.
This feature allows the vacuum to leverage multiple CPUs in order to process indexes. This enables us to perform index vacuuming and index cleanup with background workers. This adds a PARALLEL option to VACUUM command where the user can specify the number of workers that can be used to perform the command which is limited by the number of indexes on a table. Specifying zero as a number of workers will disable parallelism. This option can't be used with the FULL option. Each index is processed by at most one vacuum process. Therefore parallel vacuum can be used when the table has at least two indexes. The parallel degree is either specified by the user or determined based on the number of indexes that the table has, and further limited by max_parallel_maintenance_workers. The index can participate in parallel vacuum iff it's size is greater than min_parallel_index_scan_size. Author: Masahiko Sawada and Amit Kapila Reviewed-by: Dilip Kumar, Amit Kapila, Robert Haas, Tomas Vondra, Mahendra Singh and Sergei Kornilov Tested-by: Mahendra Singh and Prabhat Sahu Discussion: https://postgr.es/m/CAD21AoDTPMgzSkV4E3SFo1CH_x50bf5PqZFQf4jmqjk-C03BWg@mail.gmail.com https://postgr.es/m/CAA4eK1J-VoR9gzS5E75pcD-OH0mEyCdp8RihcwKrcuw7J-Q0+w@mail.gmail.com
Diffstat (limited to 'src/backend/access/transam/parallel.c')
-rw-r--r--src/backend/access/transam/parallel.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/src/backend/access/transam/parallel.c b/src/backend/access/transam/parallel.c
index f3e22549543..df06e7d1743 100644
--- a/src/backend/access/transam/parallel.c
+++ b/src/backend/access/transam/parallel.c
@@ -14,6 +14,7 @@
#include "postgres.h"
+#include "access/heapam.h"
#include "access/nbtree.h"
#include "access/parallel.h"
#include "access/session.h"
@@ -139,6 +140,9 @@ static const struct
},
{
"_bt_parallel_build_main", _bt_parallel_build_main
+ },
+ {
+ "parallel_vacuum_main", parallel_vacuum_main
}
};
@@ -174,6 +178,7 @@ CreateParallelContext(const char *library_name, const char *function_name,
pcxt = palloc0(sizeof(ParallelContext));
pcxt->subid = GetCurrentSubTransactionId();
pcxt->nworkers = nworkers;
+ pcxt->nworkers_to_launch = nworkers;
pcxt->library_name = pstrdup(library_name);
pcxt->function_name = pstrdup(function_name);
pcxt->error_context_stack = error_context_stack;
@@ -487,6 +492,23 @@ ReinitializeParallelDSM(ParallelContext *pcxt)
}
/*
+ * Reinitialize parallel workers for a parallel context such that we could
+ * launch the different number of workers. This is required for cases where
+ * we need to reuse the same DSM segment, but the number of workers can
+ * vary from run-to-run.
+ */
+void
+ReinitializeParallelWorkers(ParallelContext *pcxt, int nworkers_to_launch)
+{
+ /*
+ * The number of workers that need to be launched must be less than the
+ * number of workers with which the parallel context is initialized.
+ */
+ Assert(pcxt->nworkers >= nworkers_to_launch);
+ pcxt->nworkers_to_launch = nworkers_to_launch;
+}
+
+/*
* Launch parallel workers.
*/
void
@@ -498,7 +520,7 @@ LaunchParallelWorkers(ParallelContext *pcxt)
bool any_registrations_failed = false;
/* Skip this if we have no workers. */
- if (pcxt->nworkers == 0)
+ if (pcxt->nworkers == 0 || pcxt->nworkers_to_launch == 0)
return;
/* We need to be a lock group leader. */
@@ -533,7 +555,7 @@ LaunchParallelWorkers(ParallelContext *pcxt)
* fails. It wouldn't help much anyway, because registering the worker in
* no way guarantees that it will start up and initialize successfully.
*/
- for (i = 0; i < pcxt->nworkers; ++i)
+ for (i = 0; i < pcxt->nworkers_to_launch; ++i)
{
memcpy(worker.bgw_extra, &i, sizeof(int));
if (!any_registrations_failed &&