1
0
mirror of https://github.com/postgres/postgres.git synced 2025-09-11 00:12:06 +03:00

Add cost-based vacuum delay time to progress views.

This commit adds the amount of time spent sleeping due to
cost-based delay to the pg_stat_progress_vacuum and
pg_stat_progress_analyze system views.  A new configuration
parameter named track_cost_delay_timing, which is off by default,
controls whether this information is gathered.  For vacuum, the
reported value includes the sleep time of any associated parallel
workers.  However, parallel workers only report their sleep time
once per second to avoid overloading the leader process.

Bumps catversion.

Author: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Co-authored-by: Nathan Bossart <nathandbossart@gmail.com>
Reviewed-by: Sami Imseih <samimseih@gmail.com>
Reviewed-by: Robert Haas <robertmhaas@gmail.com>
Reviewed-by: Masahiko Sawada <sawada.mshk@gmail.com>
Reviewed-by: Masahiro Ikeda <ikedamsh@oss.nttdata.com>
Reviewed-by: Dilip Kumar <dilipbalaut@gmail.com>
Reviewed-by: Sergei Kornilov <sk@zsrv.org>
Discussion: https://postgr.es/m/ZmaXmWDL829fzAVX%40ip-10-97-1-34.eu-west-3.compute.internal
This commit is contained in:
Nathan Bossart
2025-02-11 16:38:14 -06:00
parent e5b0b0ce15
commit bb8dff9995
11 changed files with 144 additions and 5 deletions

View File

@@ -39,6 +39,7 @@
#include "catalog/pg_inherits.h"
#include "commands/cluster.h"
#include "commands/defrem.h"
#include "commands/progress.h"
#include "commands/vacuum.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
@@ -59,6 +60,12 @@
#include "utils/snapmgr.h"
#include "utils/syscache.h"
/*
* Minimum interval for cost-based vacuum delay reports from a parallel worker.
* This aims to avoid sending too many messages and waking up the leader too
* frequently.
*/
#define PARALLEL_VACUUM_DELAY_REPORT_INTERVAL_NS (NS_PER_S)
/*
* GUC parameters
@@ -70,6 +77,7 @@ int vacuum_multixact_freeze_table_age;
int vacuum_failsafe_age;
int vacuum_multixact_failsafe_age;
double vacuum_max_eager_freeze_failure_rate;
bool track_cost_delay_timing;
/*
* Variables for cost-based vacuum delay. The defaults differ between
@@ -80,6 +88,9 @@ double vacuum_max_eager_freeze_failure_rate;
double vacuum_cost_delay = 0;
int vacuum_cost_limit = 200;
/* Variable for reporting cost-based vacuum delay from parallel workers. */
int64 parallel_vacuum_worker_delay_ns = 0;
/*
* VacuumFailsafeActive is a defined as a global so that we can determine
* whether or not to re-enable cost-based vacuum delay when vacuuming a table.
@@ -2416,13 +2427,66 @@ vacuum_delay_point(bool is_analyze)
/* Nap if appropriate */
if (msec > 0)
{
instr_time delay_start;
if (msec > vacuum_cost_delay * 4)
msec = vacuum_cost_delay * 4;
if (track_cost_delay_timing)
INSTR_TIME_SET_CURRENT(delay_start);
pgstat_report_wait_start(WAIT_EVENT_VACUUM_DELAY);
pg_usleep(msec * 1000);
pgstat_report_wait_end();
if (track_cost_delay_timing)
{
instr_time delay_end;
instr_time delay;
INSTR_TIME_SET_CURRENT(delay_end);
INSTR_TIME_SET_ZERO(delay);
INSTR_TIME_ACCUM_DIFF(delay, delay_end, delay_start);
/*
* For parallel workers, we only report the delay time every once
* in a while to avoid overloading the leader with messages and
* interrupts.
*/
if (IsParallelWorker())
{
static instr_time last_report_time;
instr_time time_since_last_report;
Assert(!is_analyze);
/* Accumulate the delay time */
parallel_vacuum_worker_delay_ns += INSTR_TIME_GET_NANOSEC(delay);
/* Calculate interval since last report */
INSTR_TIME_SET_ZERO(time_since_last_report);
INSTR_TIME_ACCUM_DIFF(time_since_last_report, delay_end, last_report_time);
/* If we haven't reported in a while, do so now */
if (INSTR_TIME_GET_NANOSEC(time_since_last_report) >=
PARALLEL_VACUUM_DELAY_REPORT_INTERVAL_NS)
{
pgstat_progress_parallel_incr_param(PROGRESS_VACUUM_DELAY_TIME,
parallel_vacuum_worker_delay_ns);
/* Reset variables */
last_report_time = delay_end;
parallel_vacuum_worker_delay_ns = 0;
}
}
else if (is_analyze)
pgstat_progress_incr_param(PROGRESS_ANALYZE_DELAY_TIME,
INSTR_TIME_GET_NANOSEC(delay));
else
pgstat_progress_incr_param(PROGRESS_VACUUM_DELAY_TIME,
INSTR_TIME_GET_NANOSEC(delay));
}
/*
* We don't want to ignore postmaster death during very long vacuums
* with vacuum_cost_delay configured. We can't use the usual

View File

@@ -1094,6 +1094,11 @@ parallel_vacuum_main(dsm_segment *seg, shm_toc *toc)
InstrEndParallelQuery(&buffer_usage[ParallelWorkerNumber],
&wal_usage[ParallelWorkerNumber]);
/* Report any remaining cost-based vacuum delay time */
if (track_cost_delay_timing)
pgstat_progress_parallel_incr_param(PROGRESS_VACUUM_DELAY_TIME,
parallel_vacuum_worker_delay_ns);
TidStoreDetach(dead_items);
/* Pop the error context stack */