]> granicus.if.org Git - postgresql/commitdiff
New autovacuum_work_mem parameter
authorSimon Riggs <simon@2ndQuadrant.com>
Thu, 12 Dec 2013 11:42:39 +0000 (11:42 +0000)
committerSimon Riggs <simon@2ndQuadrant.com>
Thu, 12 Dec 2013 11:42:39 +0000 (11:42 +0000)
If autovacuum_work_mem is set, autovacuum workers now use
this parameter in preference to maintenance_work_mem.

Peter Geoghegan

doc/src/sgml/config.sgml
src/backend/commands/vacuumlazy.c
src/backend/postmaster/autovacuum.c
src/backend/utils/misc/guc.c
src/backend/utils/misc/postgresql.conf.sample
src/include/postmaster/autovacuum.h

index f33a16b7aad275265ca52fd3b2bec289a9179e03..8896988e5aa9a8f53e6b81190bb13f6e1a08b4ee 100644 (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>
index d346772600c833a082711d8c288730c989584f66..7b9837f4f425f89893c56338a2f498c5f3be3965 100644 (file)
  * 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));
 
index 88ecd3834b383a51a8417ab5b0b0fa10190aa16b..be370b19f980931f79ca7c819852d6c955a188b1 100644 (file)
  */
 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;
index f3bf6e0aa2fce7e66a775beeed8aa0ee15ac291f..e69e132f056288d5bcb0fe3f6d230a7e6256b3a4 100644 (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)
 {
index 6096fe44457452f72a7e581723902eb0b600b86e..f8bdce34d3307aba3cbadf152525b95286835a11 100644 (file)
 # 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:
index e96f07aaff94429c7e3559e5151add6b0c05cfa8..92560fe2177d295715adef0afba7e206b9149f04 100644 (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;