mirror of
https://github.com/postgres/postgres.git
synced 2025-07-28 23:42:10 +03:00
Introduce autovacuum_vacuum_max_threshold.
One way autovacuum chooses tables to vacuum is by comparing the number of updated or deleted tuples with a value calculated using autovacuum_vacuum_threshold and autovacuum_vacuum_scale_factor. The threshold specifies the base value for comparison, and the scale factor specifies the fraction of the table size to add to it. This strategy ensures that smaller tables are vacuumed after fewer updates/deletes than larger tables, which is reasonable in many cases but can result in infrequent vacuums on very large tables. This is undesirable for a couple of reasons, such as very large tables incurring a huge amount of bloat between vacuums. This new parameter provides a way to set a limit on the value calculated with autovacuum_vacuum_threshold and autovacuum_vacuum_scale_factor so that very large tables are vacuumed more frequently. By default, it is set to 100,000,000 tuples, but it can be disabled by setting it to -1. It can also be adjusted for individual tables by changing storage parameters. Author: Nathan Bossart <nathandbossart@gmail.com> Co-authored-by: Frédéric Yhuel <frederic.yhuel@dalibo.com> Reviewed-by: Melanie Plageman <melanieplageman@gmail.com> Reviewed-by: Robert Haas <robertmhaas@gmail.com> Reviewed-by: Laurenz Albe <laurenz.albe@cybertec.at> Reviewed-by: Michael Banck <mbanck@gmx.net> Reviewed-by: Joe Conway <mail@joeconway.com> Reviewed-by: Sami Imseih <samimseih@gmail.com> Reviewed-by: David Rowley <dgrowleyml@gmail.com> Reviewed-by: wenhui qiu <qiuwenhuifx@gmail.com> Reviewed-by: Vinícius Abrahão <vinnix.bsd@gmail.com> Reviewed-by: Robert Treat <rob@xzilla.net> Reviewed-by: Alena Rybakina <a.rybakina@postgrespro.ru> Discussion: https://postgr.es/m/956435f8-3b2f-47a6-8756-8c54ded61802%40dalibo.com
This commit is contained in:
@ -231,6 +231,15 @@ static relopt_int intRelOpts[] =
|
||||
},
|
||||
-1, 0, INT_MAX
|
||||
},
|
||||
{
|
||||
{
|
||||
"autovacuum_vacuum_max_threshold",
|
||||
"Maximum number of tuple updates or deletes prior to vacuum",
|
||||
RELOPT_KIND_HEAP | RELOPT_KIND_TOAST,
|
||||
ShareUpdateExclusiveLock
|
||||
},
|
||||
-2, -1, INT_MAX
|
||||
},
|
||||
{
|
||||
{
|
||||
"autovacuum_vacuum_insert_threshold",
|
||||
@ -1843,6 +1852,8 @@ default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
|
||||
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, enabled)},
|
||||
{"autovacuum_vacuum_threshold", RELOPT_TYPE_INT,
|
||||
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_threshold)},
|
||||
{"autovacuum_vacuum_max_threshold", RELOPT_TYPE_INT,
|
||||
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_max_threshold)},
|
||||
{"autovacuum_vacuum_insert_threshold", RELOPT_TYPE_INT,
|
||||
offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_ins_threshold)},
|
||||
{"autovacuum_analyze_threshold", RELOPT_TYPE_INT,
|
||||
|
@ -120,6 +120,7 @@ int autovacuum_max_workers;
|
||||
int autovacuum_work_mem = -1;
|
||||
int autovacuum_naptime;
|
||||
int autovacuum_vac_thresh;
|
||||
int autovacuum_vac_max_thresh;
|
||||
double autovacuum_vac_scale;
|
||||
int autovacuum_vac_ins_thresh;
|
||||
double autovacuum_vac_ins_scale;
|
||||
@ -2895,6 +2896,8 @@ recheck_relation_needs_vacanalyze(Oid relid,
|
||||
* threshold. This threshold is calculated as
|
||||
*
|
||||
* threshold = vac_base_thresh + vac_scale_factor * reltuples
|
||||
* if (threshold > vac_max_thresh)
|
||||
* threshold = vac_max_thresh;
|
||||
*
|
||||
* For analyze, the analysis done is that the number of tuples inserted,
|
||||
* deleted and updated since the last analyze exceeds a threshold calculated
|
||||
@ -2933,6 +2936,7 @@ relation_needs_vacanalyze(Oid relid,
|
||||
|
||||
/* constants from reloptions or GUC variables */
|
||||
int vac_base_thresh,
|
||||
vac_max_thresh,
|
||||
vac_ins_base_thresh,
|
||||
anl_base_thresh;
|
||||
float4 vac_scale_factor,
|
||||
@ -2974,6 +2978,11 @@ relation_needs_vacanalyze(Oid relid,
|
||||
? relopts->vacuum_threshold
|
||||
: autovacuum_vac_thresh;
|
||||
|
||||
/* -1 is used to disable max threshold */
|
||||
vac_max_thresh = (relopts && relopts->vacuum_max_threshold >= -1)
|
||||
? relopts->vacuum_max_threshold
|
||||
: autovacuum_vac_max_thresh;
|
||||
|
||||
vac_ins_scale_factor = (relopts && relopts->vacuum_ins_scale_factor >= 0)
|
||||
? relopts->vacuum_ins_scale_factor
|
||||
: autovacuum_vac_ins_scale;
|
||||
@ -3047,6 +3056,9 @@ relation_needs_vacanalyze(Oid relid,
|
||||
reltuples = 0;
|
||||
|
||||
vacthresh = (float4) vac_base_thresh + vac_scale_factor * reltuples;
|
||||
if (vac_max_thresh >= 0 && vacthresh > (float4) vac_max_thresh)
|
||||
vacthresh = (float4) vac_max_thresh;
|
||||
|
||||
vacinsthresh = (float4) vac_ins_base_thresh + vac_ins_scale_factor * reltuples;
|
||||
anlthresh = (float4) anl_base_thresh + anl_scale_factor * reltuples;
|
||||
|
||||
|
@ -3426,6 +3426,15 @@ struct config_int ConfigureNamesInt[] =
|
||||
50, 0, INT_MAX,
|
||||
NULL, NULL, NULL
|
||||
},
|
||||
{
|
||||
{"autovacuum_vacuum_max_threshold", PGC_SIGHUP, VACUUM_AUTOVACUUM,
|
||||
gettext_noop("Maximum number of tuple updates or deletes prior to vacuum."),
|
||||
NULL
|
||||
},
|
||||
&autovacuum_vac_max_thresh,
|
||||
100000000, -1, INT_MAX,
|
||||
NULL, NULL, NULL
|
||||
},
|
||||
{
|
||||
{"autovacuum_vacuum_insert_threshold", PGC_SIGHUP, VACUUM_AUTOVACUUM,
|
||||
gettext_noop("Minimum number of tuple inserts prior to vacuum, or -1 to disable insert vacuums."),
|
||||
|
@ -670,6 +670,9 @@ autovacuum_worker_slots = 16 # autovacuum worker slots to allocate
|
||||
#autovacuum_vacuum_insert_scale_factor = 0.2 # fraction of inserts over table
|
||||
# size before insert vacuum
|
||||
#autovacuum_analyze_scale_factor = 0.1 # fraction of table size before analyze
|
||||
#autovacuum_vacuum_max_threshold = 100000000 # max number of row updates
|
||||
# before vacuum; -1 disables max
|
||||
# threshold
|
||||
#autovacuum_freeze_max_age = 200000000 # maximum XID age before forced vacuum
|
||||
# (change requires restart)
|
||||
#autovacuum_multixact_freeze_max_age = 400000000 # maximum multixact age
|
||||
|
@ -1368,6 +1368,7 @@ static const char *const table_storage_parameters[] = {
|
||||
"autovacuum_vacuum_cost_limit",
|
||||
"autovacuum_vacuum_insert_scale_factor",
|
||||
"autovacuum_vacuum_insert_threshold",
|
||||
"autovacuum_vacuum_max_threshold",
|
||||
"autovacuum_vacuum_scale_factor",
|
||||
"autovacuum_vacuum_threshold",
|
||||
"fillfactor",
|
||||
@ -1384,6 +1385,7 @@ static const char *const table_storage_parameters[] = {
|
||||
"toast.autovacuum_vacuum_cost_limit",
|
||||
"toast.autovacuum_vacuum_insert_scale_factor",
|
||||
"toast.autovacuum_vacuum_insert_threshold",
|
||||
"toast.autovacuum_vacuum_max_threshold",
|
||||
"toast.autovacuum_vacuum_scale_factor",
|
||||
"toast.autovacuum_vacuum_threshold",
|
||||
"toast.log_autovacuum_min_duration",
|
||||
|
@ -33,6 +33,7 @@ extern PGDLLIMPORT int autovacuum_max_workers;
|
||||
extern PGDLLIMPORT int autovacuum_work_mem;
|
||||
extern PGDLLIMPORT int autovacuum_naptime;
|
||||
extern PGDLLIMPORT int autovacuum_vac_thresh;
|
||||
extern PGDLLIMPORT int autovacuum_vac_max_thresh;
|
||||
extern PGDLLIMPORT double autovacuum_vac_scale;
|
||||
extern PGDLLIMPORT int autovacuum_vac_ins_thresh;
|
||||
extern PGDLLIMPORT double autovacuum_vac_ins_scale;
|
||||
|
@ -309,6 +309,7 @@ typedef struct AutoVacOpts
|
||||
{
|
||||
bool enabled;
|
||||
int vacuum_threshold;
|
||||
int vacuum_max_threshold;
|
||||
int vacuum_ins_threshold;
|
||||
int analyze_threshold;
|
||||
int vacuum_cost_limit;
|
||||
|
Reference in New Issue
Block a user