mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-11-27 07:21:09 +08:00
Add options to pg_autovacuum to support setting the cost-based-vacuum
parameters differently from their default values. Matthew T. O'Connor
This commit is contained in:
parent
18b58350db
commit
c47fc6d050
@ -133,6 +133,17 @@ pg_autovacuum has the following optional arguments:
|
||||
-p port: port used for connection.
|
||||
-h help: list of command line options.
|
||||
|
||||
The following 5 autovacuum command line options correspond to the various
|
||||
cost-based vacuum settings. If not given, then the cluster default values
|
||||
will be used.
|
||||
|
||||
-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:
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* Revisions by Christopher B. Browne, Liberty RMS
|
||||
* Win32 Service code added by Dave Page
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/pg_autovacuum/pg_autovacuum.c,v 1.23 2004/10/25 02:14:59 tgl Exp $
|
||||
* $PostgreSQL: pgsql/contrib/pg_autovacuum/pg_autovacuum.c,v 1.24 2004/11/17 16:54:15 tgl Exp $
|
||||
*/
|
||||
|
||||
#include "postgres_fe.h"
|
||||
@ -530,7 +530,7 @@ print_table_info(tbl_info * tbl)
|
||||
{
|
||||
sprintf(logbuffer, " table name: %s.%s", tbl->dbi->dbname, tbl->table_name);
|
||||
log_entry(logbuffer, LVL_INFO);
|
||||
sprintf(logbuffer, " relid: %u; relisshared: %i", tbl->relid, tbl->relisshared);
|
||||
sprintf(logbuffer, " relid: %u; relisshared: %d", tbl->relid, tbl->relisshared);
|
||||
log_entry(logbuffer, LVL_INFO);
|
||||
sprintf(logbuffer, " reltuples: %f; relpages: %u", tbl->reltuples, tbl->relpages);
|
||||
log_entry(logbuffer, LVL_INFO);
|
||||
@ -905,6 +905,7 @@ db_connect(db_info * dbi)
|
||||
PQfinish(db_conn);
|
||||
db_conn = NULL;
|
||||
}
|
||||
|
||||
return db_conn;
|
||||
} /* end of db_connect() */
|
||||
|
||||
@ -973,6 +974,75 @@ send_query(const char *query, db_info * dbi)
|
||||
return res;
|
||||
} /* End of send_query() */
|
||||
|
||||
/*
|
||||
* Perform either a vacuum or a vacuum analyze
|
||||
*/
|
||||
static void
|
||||
perform_maintenance_command(db_info * dbi, tbl_info * tbl, int operation)
|
||||
{
|
||||
char buf[256];
|
||||
|
||||
/*
|
||||
* Set the vacuum_cost variables if supplied on command line
|
||||
*/
|
||||
if (args->av_vacuum_cost_delay != -1)
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "set vacuum_cost_delay = %d",
|
||||
args->av_vacuum_cost_delay);
|
||||
send_query(buf, dbi);
|
||||
}
|
||||
if (args->av_vacuum_cost_page_hit != -1)
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "set vacuum_cost_page_hit = %d",
|
||||
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 = %d",
|
||||
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 = %d",
|
||||
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 = %d",
|
||||
args->av_vacuum_cost_limit);
|
||||
send_query(buf, dbi);
|
||||
}
|
||||
|
||||
/*
|
||||
* if ((relisshared = t and database != template1) or
|
||||
* if operation = ANALYZE_ONLY)
|
||||
* then only do an analyze
|
||||
*/
|
||||
if ((tbl->relisshared > 0 && strcmp("template1", dbi->dbname) != 0) ||
|
||||
(operation == ANALYZE_ONLY))
|
||||
snprintf(buf, sizeof(buf), "ANALYZE %s", tbl->table_name);
|
||||
else if (operation == VACUUM_ANALYZE)
|
||||
snprintf(buf, sizeof(buf), "VACUUM ANALYZE %s", tbl->table_name);
|
||||
else
|
||||
return;
|
||||
|
||||
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, operation);
|
||||
|
||||
if (args->debug >= 2)
|
||||
print_table_info(tbl);
|
||||
}
|
||||
|
||||
static void
|
||||
free_cmd_args(void)
|
||||
@ -1014,14 +1084,23 @@ get_cmd_args(int argc, char *argv[])
|
||||
args->logfile = 0;
|
||||
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")) != -1)
|
||||
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:")) != -1)
|
||||
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,6 +1123,21 @@ get_cmd_args(int argc, char *argv[])
|
||||
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++;
|
||||
@ -1124,24 +1218,30 @@ usage(void)
|
||||
fprintf(stderr, " [-W] Password to run service with (only useful when installing as a Windows service)\n");
|
||||
#endif
|
||||
i = AUTOVACUUM_DEBUG;
|
||||
fprintf(stderr, " [-d] debug (debug level=0,1,2,3; default=%i)\n", i);
|
||||
fprintf(stderr, " [-d] debug (debug level=0,1,2,3; default=%d)\n", i);
|
||||
|
||||
i = SLEEPBASEVALUE;
|
||||
fprintf(stderr, " [-s] sleep base value (default=%i)\n", i);
|
||||
fprintf(stderr, " [-s] sleep base value (default=%d)\n", i);
|
||||
f = SLEEPSCALINGFACTOR;
|
||||
fprintf(stderr, " [-S] sleep scaling factor (default=%f)\n", f);
|
||||
|
||||
i = VACBASETHRESHOLD;
|
||||
fprintf(stderr, " [-v] vacuum base threshold (default=%i)\n", i);
|
||||
fprintf(stderr, " [-v] vacuum base threshold (default=%d)\n", i);
|
||||
f = VACSCALINGFACTOR;
|
||||
fprintf(stderr, " [-V] vacuum scaling factor (default=%f)\n", f);
|
||||
i = i / 2;
|
||||
fprintf(stderr, " [-a] analyze base threshold (default=%i)\n", i);
|
||||
fprintf(stderr, " [-a] analyze base threshold (default=%d)\n", i);
|
||||
f = f / 2;
|
||||
fprintf(stderr, " [-A] analyze scaling factor (default=%f)\n", f);
|
||||
|
||||
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");
|
||||
@ -1166,12 +1266,12 @@ print_cmd_args(void)
|
||||
sprintf(logbuffer, " args->logfile=%s", (args->logfile) ? args->logfile : "(null)");
|
||||
log_entry(logbuffer, LVL_INFO);
|
||||
#ifndef WIN32
|
||||
sprintf(logbuffer, " args->daemonize=%i", args->daemonize);
|
||||
sprintf(logbuffer, " args->daemonize=%d", args->daemonize);
|
||||
log_entry(logbuffer, LVL_INFO);
|
||||
#else
|
||||
sprintf(logbuffer, " args->install_as_service=%i", args->install_as_service);
|
||||
sprintf(logbuffer, " args->install_as_service=%d", args->install_as_service);
|
||||
log_entry(logbuffer, LVL_INFO);
|
||||
sprintf(logbuffer, " args->remove_as_service=%i", args->remove_as_service);
|
||||
sprintf(logbuffer, " args->remove_as_service=%d", args->remove_as_service);
|
||||
log_entry(logbuffer, LVL_INFO);
|
||||
sprintf(logbuffer, " args->service_user=%s", (args->service_user) ? args->service_user : "(null)");
|
||||
log_entry(logbuffer, LVL_INFO);
|
||||
@ -1179,19 +1279,46 @@ print_cmd_args(void)
|
||||
log_entry(logbuffer, LVL_INFO);
|
||||
#endif
|
||||
|
||||
sprintf(logbuffer, " args->sleep_base_value=%i", args->sleep_base_value);
|
||||
sprintf(logbuffer, " args->sleep_base_value=%d", args->sleep_base_value);
|
||||
log_entry(logbuffer, LVL_INFO);
|
||||
sprintf(logbuffer, " args->sleep_scaling_factor=%f", args->sleep_scaling_factor);
|
||||
log_entry(logbuffer, LVL_INFO);
|
||||
sprintf(logbuffer, " args->vacuum_base_threshold=%i", args->vacuum_base_threshold);
|
||||
sprintf(logbuffer, " args->vacuum_base_threshold=%d", args->vacuum_base_threshold);
|
||||
log_entry(logbuffer, LVL_INFO);
|
||||
sprintf(logbuffer, " args->vacuum_scaling_factor=%f", args->vacuum_scaling_factor);
|
||||
log_entry(logbuffer, LVL_INFO);
|
||||
sprintf(logbuffer, " args->analyze_base_threshold=%i", args->analyze_base_threshold);
|
||||
sprintf(logbuffer, " args->analyze_base_threshold=%d", args->analyze_base_threshold);
|
||||
log_entry(logbuffer, LVL_INFO);
|
||||
sprintf(logbuffer, " args->analyze_scaling_factor=%f", args->analyze_scaling_factor);
|
||||
log_entry(logbuffer, LVL_INFO);
|
||||
sprintf(logbuffer, " args->debug=%i", args->debug);
|
||||
|
||||
if (args->av_vacuum_cost_delay != -1)
|
||||
sprintf(logbuffer, " args->av_vacuum_cost_delay=%d", 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=%d", 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=%d", 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=%d", 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=%d", args->av_vacuum_cost_limit);
|
||||
else
|
||||
sprintf(logbuffer, " args->av_vacuum_cost_limit=(default)");
|
||||
log_entry(logbuffer, LVL_INFO);
|
||||
|
||||
sprintf(logbuffer, " args->debug=%d", args->debug);
|
||||
log_entry(logbuffer, LVL_INFO);
|
||||
|
||||
fflush(LOGOUTPUT);
|
||||
@ -1285,20 +1412,30 @@ InstallService()
|
||||
if (args->logfile)
|
||||
sprintf(szCommand, "%s -L %s", szCommand, args->logfile);
|
||||
if (args->sleep_base_value != (int) SLEEPBASEVALUE)
|
||||
sprintf(szCommand, "%s -s %i", szCommand, args->sleep_base_value);
|
||||
sprintf(szCommand, "%s -s %d", szCommand, args->sleep_base_value);
|
||||
if (args->sleep_scaling_factor != (float) SLEEPSCALINGFACTOR)
|
||||
sprintf(szCommand, "%s -S %f", szCommand, args->sleep_scaling_factor);
|
||||
if (args->vacuum_base_threshold != (int) VACBASETHRESHOLD)
|
||||
sprintf(szCommand, "%s -v %i", szCommand, args->vacuum_base_threshold);
|
||||
sprintf(szCommand, "%s -v %d", szCommand, args->vacuum_base_threshold);
|
||||
if (args->vacuum_scaling_factor != (float) VACSCALINGFACTOR)
|
||||
sprintf(szCommand, "%s -V %f", szCommand, args->vacuum_scaling_factor);
|
||||
if (args->analyze_base_threshold != (int) (VACBASETHRESHOLD / 2))
|
||||
sprintf(szCommand, "%s -a %i", szCommand, args->analyze_base_threshold);
|
||||
sprintf(szCommand, "%s -a %d", szCommand, args->analyze_base_threshold);
|
||||
if (args->analyze_scaling_factor != (float) (VACSCALINGFACTOR / 2))
|
||||
sprintf(szCommand, "%s -A %f", szCommand, args->analyze_scaling_factor);
|
||||
if (args->debug != (int) AUTOVACUUM_DEBUG)
|
||||
sprintf(szCommand, "%s -d %i", szCommand, args->debug);
|
||||
|
||||
sprintf(szCommand, "%s -d %d", szCommand, args->debug);
|
||||
if (args->av_vacuum_cost_delay != -1)
|
||||
sprintf(szCommand, "%s -d %d", szCommand, args->av_vacuum_cost_delay);
|
||||
if (args->av_vacuum_cost_page_hit != -1)
|
||||
sprintf(szCommand, "%s -d %d", szCommand, args->av_vacuum_cost_page_hit);
|
||||
if (args->av_vacuum_cost_page_miss != -1)
|
||||
sprintf(szCommand, "%s -d %d", szCommand, args->av_vacuum_cost_page_miss);
|
||||
if (args->av_vacuum_cost_page_dirty != -1)
|
||||
sprintf(szCommand, "%s -d %d", szCommand, args->av_vacuum_cost_page_dirty);
|
||||
if (args->av_vacuum_cost_limit != -1)
|
||||
sprintf(szCommand, "%s -d %d", szCommand, args->av_vacuum_cost_limit);
|
||||
|
||||
/* And write the new value */
|
||||
if (RegSetValueEx(hk, "ImagePath", 0, REG_EXPAND_SZ, (LPBYTE) szCommand, (DWORD) strlen(szCommand) + 1))
|
||||
return -4;
|
||||
@ -1366,7 +1503,6 @@ static
|
||||
int
|
||||
VacuumLoop(int argc, char **argv)
|
||||
{
|
||||
char buf[256];
|
||||
int j = 0,
|
||||
loops = 0;
|
||||
|
||||
@ -1516,45 +1652,11 @@ VacuumLoop(int argc, char **argv)
|
||||
* 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);
|
||||
}
|
||||
perform_maintenance_command(dbs, tbl, VACUUM_ANALYZE);
|
||||
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);
|
||||
}
|
||||
perform_maintenance_command(dbs, tbl, ANALYZE_ONLY);
|
||||
|
||||
break; /* once we have found a
|
||||
* match, no need to keep
|
||||
* checking. */
|
||||
break; /* We found a match, no need to keep looping. */
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1566,7 +1668,7 @@ VacuumLoop(int argc, char **argv)
|
||||
} /* end for table while loop */
|
||||
} /* end for j loop (tuples in PGresult) */
|
||||
} /* end if (res != NULL) */
|
||||
} /* close of if(xid_wraparound_check()) */
|
||||
} /* close of if (xid_wraparound_check()) */
|
||||
/* Done working on this db, Clean up, then advance cur_db */
|
||||
PQclear(res);
|
||||
res = NULL;
|
||||
@ -1585,7 +1687,7 @@ VacuumLoop(int argc, char **argv)
|
||||
if (args->debug >= 2)
|
||||
{
|
||||
sprintf(logbuffer,
|
||||
"%i All DBs checked in: %.0f usec, will sleep for %i secs.",
|
||||
"%d All DBs checked in: %.0f usec, will sleep for %d secs.",
|
||||
loops, diff, sleep_secs);
|
||||
log_entry(logbuffer, LVL_DEBUG);
|
||||
fflush(LOGOUTPUT);
|
||||
|
@ -2,7 +2,7 @@
|
||||
* Header file for pg_autovacuum.c
|
||||
* (c) 2003 Matthew T. O'Connor
|
||||
*
|
||||
* $PostgreSQL: pgsql/contrib/pg_autovacuum/pg_autovacuum.h,v 1.12 2004/10/16 21:50:02 tgl Exp $
|
||||
* $PostgreSQL: pgsql/contrib/pg_autovacuum/pg_autovacuum.h,v 1.13 2004/11/17 16:54:15 tgl Exp $
|
||||
*/
|
||||
|
||||
#ifndef _PG_AUTOVACUUM_H
|
||||
@ -46,6 +46,16 @@ typedef struct cmdargs
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user