New autovacuum_work_mem parameter

If autovacuum_work_mem is set, autovacuum workers now use
this parameter in preference to maintenance_work_mem.

Peter Geoghegan
This commit is contained in:
Simon Riggs 2013-12-12 11:42:39 +00:00
parent 36da3cfb45
commit 8693559cac
6 changed files with 69 additions and 10 deletions

View File

@ -1198,8 +1198,26 @@ include 'filename'
</para>
<para>
Note that when autovacuum runs, up to
<xref linkend="guc-autovacuum-max-workers"> times this memory may be
allocated, so be careful not to set the default value too high.
<xref linkend="guc-autovacuum-max-workers"> times this memory
may be allocated, so be careful not to set the default value
too high. It may be useful to control for this by separately
setting <xref linkend="guc-autovacuum-work-mem">.
</para>
</listitem>
</varlistentry>
<varlistentry id="guc-autovacuum-work-mem" xreflabel="autovacuum_work_mem">
<term><varname>autovacuum_work_mem</varname> (<type>integer</type>)</term>
<indexterm>
<primary><varname>autovacuum_work_mem</> configuration parameter</primary>
</indexterm>
<listitem>
<para>
Specifies the maximum amount of memory to be used by each
autovacuum worker process. It defaults to -1, indicating that
the value of <xref linkend="guc-maintenance-work-mem"> should
be used instead. The setting has no effect on the behavior of
<command>VACUUM</command> when run in other contexts.
</para>
</listitem>
</varlistentry>

View File

@ -10,13 +10,13 @@
* relations with finite memory space usage. To do that, we set upper bounds
* on the number of tuples and pages we will keep track of at once.
*
* We are willing to use at most maintenance_work_mem memory space to keep
* track of dead tuples. We initially allocate an array of TIDs of that size,
* with an upper limit that depends on table size (this limit ensures we don't
* allocate a huge area uselessly for vacuuming small tables). If the array
* threatens to overflow, we suspend the heap scan phase and perform a pass of
* index cleanup and page compaction, then resume the heap scan with an empty
* TID array.
* We are willing to use at most maintenance_work_mem (or perhaps
* autovacuum_work_mem) memory space to keep track of dead tuples. We
* initially allocate an array of TIDs of that size, with an upper limit that
* depends on table size (this limit ensures we don't allocate a huge area
* uselessly for vacuuming small tables). If the array threatens to overflow,
* we suspend the heap scan phase and perform a pass of index cleanup and page
* compaction, then resume the heap scan with an empty TID array.
*
* If we're processing a table with no indexes, we can just vacuum each page
* as we go; there's no need to save up multiple tuples to minimize the number
@ -1599,10 +1599,13 @@ static void
lazy_space_alloc(LVRelStats *vacrelstats, BlockNumber relblocks)
{
long maxtuples;
int vac_work_mem = IsAutoVacuumWorkerProcess() &&
autovacuum_work_mem != -1 ?
autovacuum_work_mem : maintenance_work_mem;
if (vacrelstats->hasindex)
{
maxtuples = (maintenance_work_mem * 1024L) / sizeof(ItemPointerData);
maxtuples = (vac_work_mem * 1024L) / sizeof(ItemPointerData);
maxtuples = Min(maxtuples, INT_MAX);
maxtuples = Min(maxtuples, MaxAllocSize / sizeof(ItemPointerData));

View File

@ -110,6 +110,7 @@
*/
bool autovacuum_start_daemon = false;
int autovacuum_max_workers;
int autovacuum_work_mem = -1;
int autovacuum_naptime;
int autovacuum_vac_thresh;
double autovacuum_vac_scale;

View File

@ -194,6 +194,7 @@ static const char *show_tcp_keepalives_count(void);
static bool check_maxconnections(int *newval, void **extra, GucSource source);
static bool check_max_worker_processes(int *newval, void **extra, GucSource source);
static bool check_autovacuum_max_workers(int *newval, void **extra, GucSource source);
static bool check_autovacuum_work_mem(int *newval, void **extra, GucSource source);
static bool check_effective_io_concurrency(int *newval, void **extra, GucSource source);
static void assign_effective_io_concurrency(int newval, void *extra);
static void assign_pgstat_temp_directory(const char *newval, void *extra);
@ -2357,6 +2358,17 @@ static struct config_int ConfigureNamesInt[] =
check_autovacuum_max_workers, NULL, NULL
},
{
{"autovacuum_work_mem", PGC_SIGHUP, RESOURCES_MEM,
gettext_noop("Sets the maximum memory to be used by each autovacuum worker process."),
NULL,
GUC_UNIT_KB
},
&autovacuum_work_mem,
-1, -1, MAX_KILOBYTES,
check_autovacuum_work_mem, NULL, NULL
},
{
{"tcp_keepalives_idle", PGC_USERSET, CLIENT_CONN_OTHER,
gettext_noop("Time between issuing TCP keepalives."),
@ -8777,6 +8789,29 @@ check_autovacuum_max_workers(int *newval, void **extra, GucSource source)
return true;
}
static bool
check_autovacuum_work_mem(int *newval, void **extra, GucSource source)
{
/*
* -1 indicates fallback.
*
* If we haven't yet changed the boot_val default of -1, just let it be.
* Autovacuum will look to maintenance_work_mem instead.
*/
if (*newval == -1)
return true;
/*
* We clamp manually-set values to at least 1MB. Since
* maintenance_work_mem is always set to at least this value, do the same
* here.
*/
if (*newval < 1024)
*newval = 1024;
return true;
}
static bool
check_max_worker_processes(int *newval, void **extra, GucSource source)
{

View File

@ -124,6 +124,7 @@
# actively intend to use prepared transactions.
#work_mem = 1MB # min 64kB
#maintenance_work_mem = 16MB # min 1MB
#autovacuum_work_mem = -1 # min 1MB, or -1 to use maintenance_work_mem
#max_stack_depth = 2MB # min 100kB
#dynamic_shared_memory_type = posix # the default is the first option
# supported by the operating system:

View File

@ -18,6 +18,7 @@
/* GUC variables */
extern bool autovacuum_start_daemon;
extern int autovacuum_max_workers;
extern int autovacuum_work_mem;
extern int autovacuum_naptime;
extern int autovacuum_vac_thresh;
extern double autovacuum_vac_scale;