Hello, as per some discussion on the lists a few days ago, I am
submitting this patch against the CVS version of pg_autovacuum.
This patch adds 5 new command line options to pg_autovacuum that
directly correspond to the 5 new vacuum cost GUC variables in 8.0. I
have done some simple testing and this patch works Ok on my FC3 box.
Two questions:
1) It is my understanding that these new GUC vars only effect vacuum.
That is they do NOT have any effect on an analyze command right? (I ask
since I'm only setting the vars before I issue a vacuum command)
2) Does anyone have any better suggestions for the letters used for the
new pg_autovacuum command line args? Nothing obvious came to mind, so I
just basically picked at random resulting in this:
-c vacuum_cost_delay
-C vacuum_cost_page_hit
-m vacuum_cost_page_miss
-n vacuum_cost_page_dirty
-N vacuum_cost_limit
Any better ideas?
Please review and if deemed accecptable, please apply to CVS HEAD.
Thanks,
Matthew O'Connor
*** ./pg_autovacuum.c.orig 2004-10-26 00:00:00.000000000 -0400
--- ./pg_autovacuum.c 2004-10-26 01:15:40.000000000 -0400
***************
*** 973,978 ****
--- 973,1054 ----
return res;
} /* End of send_query() */
+ static void perform_vacuum_analyze(db_info * dbi, tbl_info * tbl)
+ {
+ char buf[256];
+ /*
+ * if relisshared = t and database
+ * != template1 then only do an
+ * analyze
+ */
+ if (tbl->relisshared > 0 && strcmp("template1", dbi->dbname))
+ snprintf(buf, sizeof(buf), "ANALYZE %s", tbl->table_name);
+ else
+ {
+ /*
+ * Since we are actually doing a vacuum only in this case, then lets
+ * go ahead and set the vacuum_cost variables
+ */
+ if(args->av_vacuum_cost_delay != -1)
+ {
+ snprintf(buf, sizeof(buf), "set vacuum_cost_delay = %i", args->av_vacuum_cost_delay);
+ send_query(buf, dbi);
+ }
+ if(args->av_vacuum_cost_page_hit != -1)
+ {
+ snprintf(buf, sizeof(buf), "set vacuum_cost_delay = %i", args->av_vacuum_cost_page_hit);
+ send_query(buf, dbi);
+ }
+ if(args->av_vacuum_cost_page_miss != -1)
+ {
+ snprintf(buf, sizeof(buf), "set vacuum_cost_page_miss = %i", args->av_vacuum_cost_page_miss);
+ send_query(buf, dbi);
+ }
+ if(args->av_vacuum_cost_page_dirty != -1)
+ {
+ snprintf(buf, sizeof(buf), "set vacuum_cost_page_dirty = %i", args->av_vacuum_cost_page_dirty);
+ send_query(buf, dbi);
+ }
+ if(args->av_vacuum_cost_limit != -1)
+ {
+ snprintf(buf, sizeof(buf), "set vacuum_cost_limit = %i", args->av_vacuum_cost_limit);
+ send_query(buf, dbi);
+ }
+
+ /* Set buf to the actual vaccum command */
+ snprintf(buf, sizeof(buf), "VACUUM ANALYZE %s", tbl->table_name);
+ }
+
+ if (args->debug >= 1)
+ {
+ sprintf(logbuffer, "Performing: %s", buf);
+ log_entry(logbuffer, LVL_DEBUG);
+ fflush(LOGOUTPUT);
+ }
+
+ send_query(buf, dbi);
+ update_table_thresholds(dbi, tbl, VACUUM_ANALYZE);
+ if (args->debug >= 2)
+ print_table_info(tbl);
+
+ }
+
+ static void perform_analyze(db_info * dbi, tbl_info * tbl)
+ {
+ char buf[256];
+ snprintf(buf, sizeof(buf), "ANALYZE %s", tbl->table_name);
+ if (args->debug >= 1)
+ {
+ sprintf(logbuffer, "Performing: %s", buf);
+ log_entry(logbuffer, LVL_DEBUG);
+ fflush(LOGOUTPUT);
+ }
+ send_query(buf, dbi);
+ update_table_thresholds(dbi, tbl, ANALYZE_ONLY);
+ if (args->debug >= 2)
+ print_table_info(tbl);
+ }
+
static void
free_cmd_args(void)
***************
*** 1015,1027 ****
args->port = 0;
/*
* Fixme: Should add some sanity checking such as positive integer
* values etc
*/
#ifndef WIN32
! while ((c = getopt(argc, argv, "s:S:v:V:a:A:d:U:P:H:L:p:hD")) != -1)
#else
! while ((c = getopt(argc, argv, "s:S:v:V:a:A:d:U:P:H:L:p:hIRN:W:")) != -1)
#endif
{
switch (c)
--- 1091,1112 ----
args->port = 0;
/*
+ * Cost-Based Vacuum Delay Settings for pg_autovacuum
+ */
+ args->av_vacuum_cost_delay = -1;
+ args->av_vacuum_cost_page_hit = -1;
+ args->av_vacuum_cost_page_miss = -1;
+ args->av_vacuum_cost_page_dirty = -1;
+ args->av_vacuum_cost_limit = -1;
+
+ /*
* Fixme: Should add some sanity checking such as positive integer
* values etc
*/
#ifndef WIN32
! while ((c = getopt(argc, argv, "s:S:v:V:a:A:d:U:P:H:L:p:hD:c:C:m:n:N:")) != -1)
#else
! while ((c = getopt(argc, argv, "s:S:v:V:a:A:d:U:P:H:L:p:hIRN:W:c:C:m:n:N:")) != -1)
#endif
{
switch (c)
***************
*** 1044,1049 ****
--- 1129,1149 ----
case 'A':
args->analyze_scaling_factor = atof(optarg);
break;
+ case 'c':
+ args->av_vacuum_cost_delay = atoi(optarg);
+ break;
+ case 'C':
+ args->av_vacuum_cost_page_hit = atoi(optarg);
+ break;
+ case 'm':
+ args->av_vacuum_cost_page_miss = atoi(optarg);
+ break;
+ case 'n':
+ args->av_vacuum_cost_page_dirty = atoi(optarg);
+ break;
+ case 'N':
+ args->av_vacuum_cost_limit = atoi(optarg);
+ break;
#ifndef WIN32
case 'D':
args->daemonize++;
***************
*** 1142,1147 ****
--- 1242,1253 ----
fprintf(stderr, " [-L] logfile (default=none)\n");
+ fprintf(stderr, " [-c] vacuum_cost_delay (default=none)\n");
+ fprintf(stderr, " [-C] vacuum_cost_page_hit (default=none)\n");
+ fprintf(stderr, " [-m] vacuum_cost_page_miss (default=none)\n");
+ fprintf(stderr, " [-n] vacuum_cost_page_dirty (default=none)\n");
+ fprintf(stderr, " [-N] vacuum_cost_limit (default=none)\n");
+
fprintf(stderr, " [-U] username (libpq default)\n");
fprintf(stderr, " [-P] password (libpq default)\n");
fprintf(stderr, " [-H] host (libpq default)\n");
***************
*** 1191,1196 ****
--- 1297,1329 ----
log_entry(logbuffer, LVL_INFO);
sprintf(logbuffer, " args->analyze_scaling_factor=%f", args->analyze_scaling_factor);
log_entry(logbuffer, LVL_INFO);
+
+ if (args->av_vacuum_cost_delay != -1)
+ sprintf(logbuffer, " args->av_vacuum_cost_delay=%i", args->av_vacuum_cost_delay);
+ else
+ sprintf(logbuffer, " args->av_vacuum_cost_delay=(default)");
+ log_entry(logbuffer, LVL_INFO);
+ if(args->av_vacuum_cost_page_hit != -1)
+ sprintf(logbuffer, " args->av_vacuum_cost_page_hit=%i", args->av_vacuum_cost_page_hit);
+ else
+ sprintf(logbuffer, " args->av_vacuum_cost_page_hit=(default)");
+ log_entry(logbuffer, LVL_INFO);
+ if(args->av_vacuum_cost_page_miss != -1)
+ sprintf(logbuffer, " args->av_vacuum_cost_page_miss=%i", args->av_vacuum_cost_page_miss);
+ else
+ sprintf(logbuffer, " args->av_vacuum_cost_page_miss=(default)");
+ log_entry(logbuffer, LVL_INFO);
+ if(args->av_vacuum_cost_page_dirty != -1)
+ sprintf(logbuffer, " args->av_vacuum_cost_page_dirty=%i", args->av_vacuum_cost_page_dirty);
+ else
+ sprintf(logbuffer, " args->av_vacuum_cost_page_dirty=(default)");
+ log_entry(logbuffer, LVL_INFO);
+ if(args->av_vacuum_cost_limit != -1)
+ sprintf(logbuffer, " args->av_vacuum_cost_limit=%i", args->av_vacuum_cost_limit);
+ else
+ sprintf(logbuffer, " args->av_vacuum_cost_limit=(default)");
+ log_entry(logbuffer, LVL_INFO);
+
sprintf(logbuffer, " args->debug=%i", args->debug);
log_entry(logbuffer, LVL_INFO);
***************
*** 1366,1372 ****
int
VacuumLoop(int argc, char **argv)
{
- char buf[256];
int j = 0,
loops = 0;
--- 1499,1504 ----
***************
*** 1516,1556 ****
* analyze
*/
if (tbl->curr_vacuum_count - tbl->CountAtLastVacuum >= tbl->vacuum_threshold)
! {
! /*
! * if relisshared = t and database
! * != template1 then only do an
! * analyze
! */
! if (tbl->relisshared > 0 && strcmp("template1", dbs->dbname))
! snprintf(buf, sizeof(buf), "ANALYZE %s", tbl->table_name);
! else
! snprintf(buf, sizeof(buf), "VACUUM ANALYZE %s", tbl->table_name);
! if (args->debug >= 1)
! {
! sprintf(logbuffer, "Performing: %s", buf);
! log_entry(logbuffer, LVL_DEBUG);
! fflush(LOGOUTPUT);
! }
! send_query(buf, dbs);
! update_table_thresholds(dbs, tbl, VACUUM_ANALYZE);
! if (args->debug >= 2)
! print_table_info(tbl);
! }
else if (tbl->curr_analyze_count - tbl->CountAtLastAnalyze >=
tbl->analyze_threshold)
! {
! snprintf(buf, sizeof(buf), "ANALYZE %s", tbl->table_name);
! if (args->debug >= 1)
! {
! sprintf(logbuffer, "Performing: %s", buf);
! log_entry(logbuffer, LVL_DEBUG);
! fflush(LOGOUTPUT);
! }
! send_query(buf, dbs);
! update_table_thresholds(dbs, tbl, ANALYZE_ONLY);
! if (args->debug >= 2)
! print_table_info(tbl);
! }
break; /* once we have found a
* match, no need to keep
--- 1648,1656 ----
* analyze
*/
if (tbl->curr_vacuum_count - tbl->CountAtLastVacuum >= tbl->vacuum_threshold)
! perform_vacuum_analyze(dbs, tbl);
else if (tbl->curr_analyze_count - tbl->CountAtLastAnalyze >=
tbl->analyze_threshold)
! perform_analyze(dbs, tbl);
break; /* once we have found a
* match, no need to keep
*** ./pg_autovacuum.h.orig 2004-10-26 00:00:00.000000000 -0400
--- ./pg_autovacuum.h 2004-10-26 00:10:08.000000000 -0400
***************
*** 46,51 ****
--- 46,61 ----
analyze_base_threshold,
sleep_base_value,
debug,
+
+ /*
+ * Cost-Based Vacuum Delay Settings for pg_autovacuum
+ */
+ av_vacuum_cost_delay,
+ av_vacuum_cost_page_hit,
+ av_vacuum_cost_page_miss,
+ av_vacuum_cost_page_dirty,
+ av_vacuum_cost_limit,
+
#ifndef WIN32
daemonize;
#else
***************
*** 64,69 ****
--- 74,80 ----
*host,
*logfile,
*port;
+
} cmd_args;
/*
*** ./README.pg_autovacuum.orig 2004-10-26 00:10:38.000000000 -0400
--- ./README.pg_autovacuum 2004-10-26 00:17:56.000000000 -0400
***************
*** 133,138 ****
--- 133,148 ----
-p port: port used for connection.
-h help: list of command line options.
+ The following 5 options tell autovacuum to set specific values for the cost
+ based vacuum settings. If left unset, then the cluster default values will be
+ in effect.
+ -c vacuum_cost_delay
+ -C vacuum_cost_page_hit
+ -m vacuum_cost_page_miss
+ -n vacuum_cost_page_dirty
+ -N vacuum_cost_limit
+
+
Numerous arguments have default values defined in pg_autovacuum.h. At
the time of writing they are: