mirror of
https://github.com/postgres/postgres.git
synced 2025-04-27 22:56:53 +03:00
Comments and doc fixes for commit 40d964ec99.
Reported-by: Justin Pryzby Author: Justin Pryzby, with few changes by me Reviewed-by: Amit Kapila and Sawada Masahiko Discussion: https://postgr.es/m/20200322021801.GB2563@telsasoft.com
This commit is contained in:
parent
826ee1a019
commit
a6fea120a7
@ -232,15 +232,15 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ <replaceable class="paramet
|
|||||||
<term><literal>PARALLEL</literal></term>
|
<term><literal>PARALLEL</literal></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Perform vacuum index and cleanup index phases of <command>VACUUM</command>
|
Perform index vacuum and index cleanup phases of <command>VACUUM</command>
|
||||||
in parallel using <replaceable class="parameter">integer</replaceable>
|
in parallel using <replaceable class="parameter">integer</replaceable>
|
||||||
background workers (for the detail of each vacuum phases, please
|
background workers (for the details of each vacuum phase, please
|
||||||
refer to <xref linkend="vacuum-phases"/>). If the
|
refer to <xref linkend="vacuum-phases"/>). If the
|
||||||
<literal>PARALLEL</literal> option is omitted, then
|
<literal>PARALLEL</literal> option is omitted, then the number of workers
|
||||||
<command>VACUUM</command> decides the number of workers based on number
|
is determined based on the number of indexes that support parallel vacuum
|
||||||
of indexes that support parallel vacuum operation on the relation which
|
operation on the relation, and is further limited by <xref
|
||||||
is further limited by <xref linkend="guc-max-parallel-workers-maintenance"/>.
|
linkend="guc-max-parallel-workers-maintenance"/>.
|
||||||
The index can participate in a parallel vacuum if and only if the size
|
An index can participate in parallel vacuum if and only if the size
|
||||||
of the index is more than <xref linkend="guc-min-parallel-index-scan-size"/>.
|
of the index is more than <xref linkend="guc-min-parallel-index-scan-size"/>.
|
||||||
Please note that it is not guaranteed that the number of parallel workers
|
Please note that it is not guaranteed that the number of parallel workers
|
||||||
specified in <replaceable class="parameter">integer</replaceable> will
|
specified in <replaceable class="parameter">integer</replaceable> will
|
||||||
@ -248,7 +248,7 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ <replaceable class="paramet
|
|||||||
workers than specified, or even with no workers at all. Only one worker
|
workers than specified, or even with no workers at all. Only one worker
|
||||||
can be used per index. So parallel workers are launched only when there
|
can be used per index. So parallel workers are launched only when there
|
||||||
are at least <literal>2</literal> indexes in the table. Workers for
|
are at least <literal>2</literal> indexes in the table. Workers for
|
||||||
vacuum launches before starting each phase and exit at the end of
|
vacuum are launched before the start of each phase and exit at the end of
|
||||||
the phase. These behaviors might change in a future release. This
|
the phase. These behaviors might change in a future release. This
|
||||||
option can't be used with the <literal>FULL</literal> option.
|
option can't be used with the <literal>FULL</literal> option.
|
||||||
</para>
|
</para>
|
||||||
@ -358,8 +358,8 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ <replaceable class="paramet
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The <option>PARALLEL</option> option is used only for vacuum purpose.
|
The <option>PARALLEL</option> option is used only for vacuum purposes.
|
||||||
Even if this option is specified with <option>ANALYZE</option> option
|
If this option is specified with the <option>ANALYZE</option> option,
|
||||||
it does not affect <option>ANALYZE</option>.
|
it does not affect <option>ANALYZE</option>.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@ -367,7 +367,7 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ <replaceable class="paramet
|
|||||||
<command>VACUUM</command> causes a substantial increase in I/O traffic,
|
<command>VACUUM</command> causes a substantial increase in I/O traffic,
|
||||||
which might cause poor performance for other active sessions. Therefore,
|
which might cause poor performance for other active sessions. Therefore,
|
||||||
it is sometimes advisable to use the cost-based vacuum delay feature. For
|
it is sometimes advisable to use the cost-based vacuum delay feature. For
|
||||||
parallel vacuum, each worker sleeps proportional to the work done by that
|
parallel vacuum, each worker sleeps in proportion to the work done by that
|
||||||
worker. See <xref linkend="runtime-config-resource-vacuum-cost"/> for
|
worker. See <xref linkend="runtime-config-resource-vacuum-cost"/> for
|
||||||
details.
|
details.
|
||||||
</para>
|
</para>
|
||||||
|
@ -208,7 +208,7 @@ typedef struct LVShared
|
|||||||
* live tuples in the index vacuum case or the new live tuples in the
|
* live tuples in the index vacuum case or the new live tuples in the
|
||||||
* index cleanup case.
|
* index cleanup case.
|
||||||
*
|
*
|
||||||
* estimated_count is true if the reltuples is an estimated value.
|
* estimated_count is true if reltuples is an estimated value.
|
||||||
*/
|
*/
|
||||||
double reltuples;
|
double reltuples;
|
||||||
bool estimated_count;
|
bool estimated_count;
|
||||||
@ -232,8 +232,8 @@ typedef struct LVShared
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Number of active parallel workers. This is used for computing the
|
* Number of active parallel workers. This is used for computing the
|
||||||
* minimum threshold of the vacuum cost balance for a worker to go for the
|
* minimum threshold of the vacuum cost balance before a worker sleeps for
|
||||||
* delay.
|
* cost-based delay.
|
||||||
*/
|
*/
|
||||||
pg_atomic_uint32 active_nworkers;
|
pg_atomic_uint32 active_nworkers;
|
||||||
|
|
||||||
@ -732,7 +732,7 @@ vacuum_log_cleanup_info(Relation rel, LVRelStats *vacrelstats)
|
|||||||
* to reclaim dead line pointers.
|
* to reclaim dead line pointers.
|
||||||
*
|
*
|
||||||
* If the table has at least two indexes, we execute both index vacuum
|
* If the table has at least two indexes, we execute both index vacuum
|
||||||
* and index cleanup with parallel workers unless the parallel vacuum is
|
* and index cleanup with parallel workers unless parallel vacuum is
|
||||||
* disabled. In a parallel vacuum, we enter parallel mode and then
|
* disabled. In a parallel vacuum, we enter parallel mode and then
|
||||||
* create both the parallel context and the DSM segment before starting
|
* create both the parallel context and the DSM segment before starting
|
||||||
* heap scan so that we can record dead tuples to the DSM segment. All
|
* heap scan so that we can record dead tuples to the DSM segment. All
|
||||||
@ -809,8 +809,8 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats,
|
|||||||
vacrelstats->latestRemovedXid = InvalidTransactionId;
|
vacrelstats->latestRemovedXid = InvalidTransactionId;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the state for a parallel vacuum. As of now, only one worker
|
* Initialize state for a parallel vacuum. As of now, only one worker can
|
||||||
* can be used for an index, so we invoke parallelism only if there are at
|
* be used for an index, so we invoke parallelism only if there are at
|
||||||
* least two indexes on a table.
|
* least two indexes on a table.
|
||||||
*/
|
*/
|
||||||
if (params->nworkers >= 0 && vacrelstats->useindex && nindexes > 1)
|
if (params->nworkers >= 0 && vacrelstats->useindex && nindexes > 1)
|
||||||
@ -837,7 +837,7 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate the space for dead tuples in case the parallel vacuum is not
|
* Allocate the space for dead tuples in case parallel vacuum is not
|
||||||
* initialized.
|
* initialized.
|
||||||
*/
|
*/
|
||||||
if (!ParallelVacuumIsActive(lps))
|
if (!ParallelVacuumIsActive(lps))
|
||||||
@ -2215,7 +2215,7 @@ parallel_vacuum_index(Relation *Irel, IndexBulkDeleteResult **stats,
|
|||||||
shared_indstats = get_indstats(lvshared, idx);
|
shared_indstats = get_indstats(lvshared, idx);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Skip processing indexes that doesn't participate in parallel
|
* Skip processing indexes that don't participate in parallel
|
||||||
* operation
|
* operation
|
||||||
*/
|
*/
|
||||||
if (shared_indstats == NULL ||
|
if (shared_indstats == NULL ||
|
||||||
@ -2312,12 +2312,12 @@ vacuum_one_index(Relation indrel, IndexBulkDeleteResult **stats,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy the index bulk-deletion result returned from ambulkdelete and
|
* Copy the index bulk-deletion result returned from ambulkdelete and
|
||||||
* amvacuumcleanup to the DSM segment if it's the first time to get it
|
* amvacuumcleanup to the DSM segment if it's the first cycle because they
|
||||||
* from them, because they allocate it locally and it's possible that an
|
* allocate locally and it's possible that an index will be vacuumed by a
|
||||||
* index will be vacuumed by the different vacuum process at the next
|
* different vacuum process the next cycle. Copying the result normally
|
||||||
* time. The copying of the result normally happens only after the first
|
* happens only the first time an index is vacuumed. For any additional
|
||||||
* time of index vacuuming. From the second time, we pass the result on
|
* vacuum pass, we directly point to the result on the DSM segment and
|
||||||
* the DSM segment so that they then update it directly.
|
* pass it to vacuum index APIs so that workers can update it directly.
|
||||||
*
|
*
|
||||||
* Since all vacuum workers write the bulk-deletion result at different
|
* Since all vacuum workers write the bulk-deletion result at different
|
||||||
* slots we can write them without locking.
|
* slots we can write them without locking.
|
||||||
@ -2328,8 +2328,8 @@ vacuum_one_index(Relation indrel, IndexBulkDeleteResult **stats,
|
|||||||
shared_indstats->updated = true;
|
shared_indstats->updated = true;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now that the stats[idx] points to the DSM segment, we don't need
|
* Now that stats[idx] points to the DSM segment, we don't need the
|
||||||
* the locally allocated results.
|
* locally allocated results.
|
||||||
*/
|
*/
|
||||||
pfree(*stats);
|
pfree(*stats);
|
||||||
*stats = bulkdelete_res;
|
*stats = bulkdelete_res;
|
||||||
@ -2449,7 +2449,7 @@ lazy_vacuum_index(Relation indrel, IndexBulkDeleteResult **stats,
|
|||||||
* lazy_cleanup_index() -- do post-vacuum cleanup for one index relation.
|
* lazy_cleanup_index() -- do post-vacuum cleanup for one index relation.
|
||||||
*
|
*
|
||||||
* reltuples is the number of heap tuples and estimated_count is true
|
* reltuples is the number of heap tuples and estimated_count is true
|
||||||
* if the reltuples is an estimated value.
|
* if reltuples is an estimated value.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
lazy_cleanup_index(Relation indrel,
|
lazy_cleanup_index(Relation indrel,
|
||||||
@ -3050,9 +3050,9 @@ heap_page_is_all_visible(Relation rel, Buffer buf,
|
|||||||
/*
|
/*
|
||||||
* Compute the number of parallel worker processes to request. Both index
|
* Compute the number of parallel worker processes to request. Both index
|
||||||
* vacuum and index cleanup can be executed with parallel workers. The index
|
* vacuum and index cleanup can be executed with parallel workers. The index
|
||||||
* is eligible for parallel vacuum iff it's size is greater than
|
* is eligible for parallel vacuum iff its size is greater than
|
||||||
* min_parallel_index_scan_size as invoking workers for very small indexes
|
* min_parallel_index_scan_size as invoking workers for very small indexes
|
||||||
* can hurt the performance.
|
* can hurt performance.
|
||||||
*
|
*
|
||||||
* nrequested is the number of parallel workers that user requested. If
|
* nrequested is the number of parallel workers that user requested. If
|
||||||
* nrequested is 0, we compute the parallel degree based on nindexes, that is
|
* nrequested is 0, we compute the parallel degree based on nindexes, that is
|
||||||
@ -3071,7 +3071,7 @@ compute_parallel_vacuum_workers(Relation *Irel, int nindexes, int nrequested,
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We don't allow to perform parallel operation in standalone backend or
|
* We don't allow performing parallel operation in standalone backend or
|
||||||
* when parallelism is disabled.
|
* when parallelism is disabled.
|
||||||
*/
|
*/
|
||||||
if (!IsUnderPostmaster || max_parallel_maintenance_workers == 0)
|
if (!IsUnderPostmaster || max_parallel_maintenance_workers == 0)
|
||||||
@ -3138,13 +3138,13 @@ prepare_index_statistics(LVShared *lvshared, bool *can_parallel_vacuum,
|
|||||||
if (!can_parallel_vacuum[i])
|
if (!can_parallel_vacuum[i])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Set NOT NULL as this index do support parallelism */
|
/* Set NOT NULL as this index does support parallelism */
|
||||||
lvshared->bitmap[i >> 3] |= 1 << (i & 0x07);
|
lvshared->bitmap[i >> 3] |= 1 << (i & 0x07);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Update index statistics in pg_class if the statistics is accurate.
|
* Update index statistics in pg_class if the statistics are accurate.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
update_index_statistics(Relation *Irel, IndexBulkDeleteResult **stats,
|
update_index_statistics(Relation *Irel, IndexBulkDeleteResult **stats,
|
||||||
@ -3174,7 +3174,7 @@ update_index_statistics(Relation *Irel, IndexBulkDeleteResult **stats,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* This function prepares and returns parallel vacuum state if we can launch
|
* This function prepares and returns parallel vacuum state if we can launch
|
||||||
* even one worker. This function is responsible to enter parallel mode,
|
* even one worker. This function is responsible for entering parallel mode,
|
||||||
* create a parallel context, and then initialize the DSM segment.
|
* create a parallel context, and then initialize the DSM segment.
|
||||||
*/
|
*/
|
||||||
static LVParallelState *
|
static LVParallelState *
|
||||||
@ -3345,8 +3345,8 @@ begin_parallel_vacuum(Oid relid, Relation *Irel, LVRelStats *vacrelstats,
|
|||||||
/*
|
/*
|
||||||
* Destroy the parallel context, and end parallel mode.
|
* Destroy the parallel context, and end parallel mode.
|
||||||
*
|
*
|
||||||
* Since writes are not allowed during the parallel mode, so we copy the
|
* Since writes are not allowed during parallel mode, copy the
|
||||||
* updated index statistics from DSM in local memory and then later use that
|
* updated index statistics from DSM into local memory and then later use that
|
||||||
* to update the index statistics. One might think that we can exit from
|
* to update the index statistics. One might think that we can exit from
|
||||||
* parallel mode, update the index statistics and then destroy parallel
|
* parallel mode, update the index statistics and then destroy parallel
|
||||||
* context, but that won't be safe (see ExitParallelMode).
|
* context, but that won't be safe (see ExitParallelMode).
|
||||||
@ -3452,7 +3452,7 @@ skip_parallel_vacuum_index(Relation indrel, LVShared *lvshared)
|
|||||||
* Perform work within a launched parallel process.
|
* Perform work within a launched parallel process.
|
||||||
*
|
*
|
||||||
* Since parallel vacuum workers perform only index vacuum or index cleanup,
|
* Since parallel vacuum workers perform only index vacuum or index cleanup,
|
||||||
* we don't need to report the progress information.
|
* we don't need to report progress information.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
parallel_vacuum_main(dsm_segment *seg, shm_toc *toc)
|
parallel_vacuum_main(dsm_segment *seg, shm_toc *toc)
|
||||||
|
@ -505,7 +505,7 @@ ReinitializeParallelDSM(ParallelContext *pcxt)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Reinitialize parallel workers for a parallel context such that we could
|
* Reinitialize parallel workers for a parallel context such that we could
|
||||||
* launch the different number of workers. This is required for cases where
|
* launch a different number of workers. This is required for cases where
|
||||||
* we need to reuse the same DSM segment, but the number of workers can
|
* we need to reuse the same DSM segment, but the number of workers can
|
||||||
* vary from run-to-run.
|
* vary from run-to-run.
|
||||||
*/
|
*/
|
||||||
|
@ -2036,23 +2036,23 @@ vacuum_delay_point(void)
|
|||||||
/*
|
/*
|
||||||
* Computes the vacuum delay for parallel workers.
|
* Computes the vacuum delay for parallel workers.
|
||||||
*
|
*
|
||||||
* The basic idea of a cost-based vacuum delay for parallel vacuum is to allow
|
* The basic idea of a cost-based delay for parallel vacuum is to allow each
|
||||||
* each worker to sleep proportional to the work done by it. We achieve this
|
* worker to sleep in proportion to the share of work it's done. We achieve this
|
||||||
* by allowing all parallel vacuum workers including the leader process to
|
* by allowing all parallel vacuum workers including the leader process to
|
||||||
* have a shared view of cost related parameters (mainly VacuumCostBalance).
|
* have a shared view of cost related parameters (mainly VacuumCostBalance).
|
||||||
* We allow each worker to update it as and when it has incurred any cost and
|
* We allow each worker to update it as and when it has incurred any cost and
|
||||||
* then based on that decide whether it needs to sleep. We compute the time
|
* then based on that decide whether it needs to sleep. We compute the time
|
||||||
* to sleep for a worker based on the cost it has incurred
|
* to sleep for a worker based on the cost it has incurred
|
||||||
* (VacuumCostBalanceLocal) and then reduce the VacuumSharedCostBalance by
|
* (VacuumCostBalanceLocal) and then reduce the VacuumSharedCostBalance by
|
||||||
* that amount. This avoids letting the workers sleep who have done less or
|
* that amount. This avoids putting to sleep those workers which have done less
|
||||||
* no I/O as compared to other workers and therefore can ensure that workers
|
* I/O than other workers and therefore ensure that workers
|
||||||
* who are doing more I/O got throttled more.
|
* which are doing more I/O got throttled more.
|
||||||
*
|
*
|
||||||
* We allow any worker to sleep only if it has performed the I/O above a
|
* We allow a worker to sleep only if it has performed I/O above a certain
|
||||||
* certain threshold, which is calculated based on the number of active
|
* threshold, which is calculated based on the number of active workers
|
||||||
* workers (VacuumActiveNWorkers), and the overall cost balance is more than
|
* (VacuumActiveNWorkers), and the overall cost balance is more than
|
||||||
* VacuumCostLimit set by the system. The testing reveals that we achieve
|
* VacuumCostLimit set by the system. Testing reveals that we achieve
|
||||||
* the required throttling if we allow a worker that has done more than 50%
|
* the required throttling if we force a worker that has done more than 50%
|
||||||
* of its share of work to sleep.
|
* of its share of work to sleep.
|
||||||
*/
|
*/
|
||||||
static double
|
static double
|
||||||
|
@ -225,7 +225,7 @@ typedef struct VacuumParams
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* The number of parallel vacuum workers. 0 by default which means choose
|
* The number of parallel vacuum workers. 0 by default which means choose
|
||||||
* based on the number of indexes. -1 indicates a parallel vacuum is
|
* based on the number of indexes. -1 indicates parallel vacuum is
|
||||||
* disabled.
|
* disabled.
|
||||||
*/
|
*/
|
||||||
int nworkers;
|
int nworkers;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user