1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-02 09:02:37 +03:00

Trigger more frequent autovacuums with relallfrozen

Calculate the insert threshold for triggering an autovacuum of a
relation based on the number of unfrozen pages.

By only considering the unfrozen portion of the table when calculating
how many tuples to add to the insert threshold, we can trigger more
frequent vacuums of insert-heavy tables. This increases the chances of
vacuuming those pages when they still reside in shared buffers

This also increases the number of autovacuums triggered by tuples
inserted and not by wraparound risk. We prefer to freeze these pages
during insert-triggered autovacuums, as anti-wraparound vacuums are not
automatically canceled by conflicting lock requests.

We calculate the unfrozen percentage of the table using the recently
added (99f8f3fbbc) relallfrozen column of pg_class.

Author: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-by: Nathan Bossart <nathandbossart@gmail.com>
Reviewed-by: Greg Sabino Mullane <htamfids@gmail.com>
Reviewed-by: Robert Treat <rob@xzilla.net>
Reviewed-by: wenhui qiu <qiuwenhuifx@gmail.com>
Discussion: https://postgr.es/m/flat/CAAKRu_aj-P7YyBz_cPNwztz6ohP%2BvWis%3Diz3YcomkB3NpYA--w%40mail.gmail.com
This commit is contained in:
Melanie Plageman
2025-03-03 14:42:00 -05:00
parent 35c8dd9e11
commit 06eae9e621
4 changed files with 37 additions and 16 deletions

View File

@ -2938,7 +2938,6 @@ relation_needs_vacanalyze(Oid relid,
{
bool force_vacuum;
bool av_enabled;
float4 reltuples; /* pg_class.reltuples */
/* constants from reloptions or GUC variables */
int vac_base_thresh,
@ -3052,7 +3051,11 @@ relation_needs_vacanalyze(Oid relid,
*/
if (PointerIsValid(tabentry) && AutoVacuumingActive())
{
reltuples = classForm->reltuples;
float4 pcnt_unfrozen = 1;
float4 reltuples = classForm->reltuples;
int32 relpages = classForm->relpages;
int32 relallfrozen = classForm->relallfrozen;
vactuples = tabentry->dead_tuples;
instuples = tabentry->ins_since_vacuum;
anltuples = tabentry->mod_since_analyze;
@ -3061,11 +3064,29 @@ relation_needs_vacanalyze(Oid relid,
if (reltuples < 0)
reltuples = 0;
/*
* If we have data for relallfrozen, calculate the unfrozen percentage
* of the table to modify insert scale factor. This helps us decide
* whether or not to vacuum an insert-heavy table based on the number
* of inserts to the more "active" part of the table.
*/
if (relpages > 0 && relallfrozen > 0)
{
/*
* It could be the stats were updated manually and relallfrozen >
* relpages. Clamp relallfrozen to relpages to avoid nonsensical
* calculations.
*/
relallfrozen = Min(relallfrozen, relpages);
pcnt_unfrozen = 1 - ((float4) relallfrozen / relpages);
}
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;
vacinsthresh = (float4) vac_ins_base_thresh +
vac_ins_scale_factor * reltuples * pcnt_unfrozen;
anlthresh = (float4) anl_base_thresh + anl_scale_factor * reltuples;
/*

View File

@ -675,8 +675,8 @@ autovacuum_worker_slots = 16 # autovacuum worker slots to allocate
#autovacuum_analyze_threshold = 50 # min number of row updates before
# analyze
#autovacuum_vacuum_scale_factor = 0.2 # fraction of table size before vacuum
#autovacuum_vacuum_insert_scale_factor = 0.2 # fraction of inserts over table
# size before insert vacuum
#autovacuum_vacuum_insert_scale_factor = 0.2 # fraction of unfrozen pages
# 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