mirror of
https://github.com/postgres/postgres.git
synced 2025-06-14 18:42:34 +03:00
> OK, well as we wait on the fix for the stats system, let me submit my
> patch for pg_autovacuum. This patch assumes that the stats system will > be fixed so that all inserts, updates and deletes performed on shared > tables reguardless of what database those commands were executed from, > will show up in the stats shown in each database. I had to make a further change to this to take quotes off the 'last ANALYZE' in order for it to not overquote the relation name, so there's a _little_ work left to get it to play well. I have deployed it onto several boxes that should be doing some vacuuming over the weekend, and it is now certainly hitting pg_ tables. I would like to present a CVS-oriented patch; unfortunately, I had to change the indentation patterns when editing some of it :-(. The following _may_ be good; not sure... Matthew T. O'Connor Christopher Browne
This commit is contained in:
@ -2,66 +2,97 @@ pg_autovacuum README
|
|||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
pg_autovacuum is a libpq client program that monitors all the
|
pg_autovacuum is a libpq client program that monitors all the
|
||||||
databases associated with a postgresql server. It uses the stats
|
databases associated with a PostgreSQL server. It uses the statistics
|
||||||
collector to monitor insert, update and delete activity.
|
collector to monitor insert, update and delete activity.
|
||||||
|
|
||||||
When a table exceeds its insert or delete threshold (more detail
|
When a table exceeds a insert or delete threshold (for more detail on
|
||||||
on thresholds below) then that table will be vacuumed or analyzed.
|
thresholds, see "Vacuum and Analyze" below) then that table will be
|
||||||
|
vacuumed and/or analyzed.
|
||||||
|
|
||||||
This allows postgresql to keep the fsm and table statistics up to
|
This allows PostgreSQL to keep the FSM (Free Space Map) and table
|
||||||
date, and eliminates the need to schedule periodic vacuums.
|
statistics up to date, and eliminates the need to schedule periodic
|
||||||
|
vacuums.
|
||||||
|
|
||||||
The primary benefit of pg_autovacuum is that the FSM and table
|
The primary benefit of pg_autovacuum is that the FSM and table
|
||||||
statistic information are updated as needed. When a table is actively
|
statistic information are updated more nearly as frequently as needed.
|
||||||
changing, pg_autovacuum will perform the necessary vacuums and
|
When a table is actively changing, pg_autovacuum will perform the
|
||||||
analyzes, whereas if a table remains static, no cycles will be wasted
|
VACUUMs and ANALYZEs that such a table needs, whereas if a table
|
||||||
performing unnecessary vacuums/analyzes.
|
remains static, no cycles will be wasted performing this
|
||||||
|
unnecessarily.
|
||||||
|
|
||||||
A secondary benefit of pg_autovacuum is that it ensures that a
|
A secondary benefit of pg_autovacuum is that it ensures that a
|
||||||
database wide vacuum is performed prior to xid wraparound. This is an
|
database wide vacuum is performed prior to XID wraparound. This is an
|
||||||
important, if rare, problem, as failing to do so can result in major
|
important, if rare, problem, as failing to do so can result in major
|
||||||
data loss.
|
data loss. (See the section in the _Administrator's Guide_ entitled
|
||||||
|
"Preventing transaction ID wraparound failures" for more details.)
|
||||||
|
|
||||||
KNOWN ISSUES:
|
KNOWN ISSUES:
|
||||||
-------------
|
-------------
|
||||||
pg_autovacuum has been tested under Redhat Linux (by me) and Solaris (by
|
|
||||||
Christopher B. Browne) and all known bugs have been resolved. Please report
|
|
||||||
any problems to the hackers list.
|
|
||||||
|
|
||||||
pg_autovacuum does not get started automatically by either the postmaster or
|
pg_autovacuum has been tested under Redhat Linux (by me) and Debian
|
||||||
by pg_ctl. Along the sames lines, when the postmaster exits no one tells
|
GNU/Linux and Solaris (by Christopher B. Browne) and all known bugs
|
||||||
pg_autovacuum. The result is that at the start of the next loop,
|
have been resolved. Please report any problems to the hackers list.
|
||||||
pg_autovacuum fails to connect to the server and exits. Any time it fails
|
|
||||||
to connect pg_autovacuum exits.
|
|
||||||
|
|
||||||
pg_autovacuum requires that the stats system be enabled and reporting row
|
pg_autovacuum requires that the statistics system be enabled and
|
||||||
level stats. The overhead of the stats system has been shown to be
|
reporting row level stats. The overhead of the stats system has been
|
||||||
significant under certain workloads. For instance a tight loop of queries
|
shown to be significant costly under certain workloads. For instance,
|
||||||
performing "select 1" was nearly 30% slower with stats enabled. However,
|
a tight loop of queries performing "select 1" was found to run nearly
|
||||||
in practice with more realistic workloads, the stats system overhead is
|
30% slower when stats were enabled. However, in practice, with more
|
||||||
usually nominal.
|
realistic workloads, the stats system overhead is usually nominal.
|
||||||
|
|
||||||
|
pg_autovacuum does not get started automatically by either the
|
||||||
|
postmaster or by pg_ctl. Similarly, when the postmaster exits, no one
|
||||||
|
tells pg_autovacuum. The result of that is that at the start of the
|
||||||
|
next loop, pg_autovacuum will fail to connect to the server and
|
||||||
|
exit(). Any time it fails to connect pg_autovacuum exit()s.
|
||||||
|
|
||||||
|
While pg_autovacuum can manage vacuums for as many databases as you
|
||||||
|
may have tied to a particular PostgreSQL postmaster, it can only
|
||||||
|
connect to a single PostgreSQL postmaster. Thus, if you have multiple
|
||||||
|
postmasters on a particular host, you will need multiple pg_autovacuum
|
||||||
|
instances, and they have no way, at present, to coordinate between one
|
||||||
|
another to ensure that they do not concurrently vacuum big tables.
|
||||||
|
|
||||||
|
TODO:
|
||||||
|
-----
|
||||||
|
|
||||||
|
At present, there are no sample scripts to automatically start up
|
||||||
|
pg_autovacuum along with the database. It would be desirable to have
|
||||||
|
a SysV script to start up pg_autovacuum after PostgreSQL has been
|
||||||
|
started.
|
||||||
|
|
||||||
|
Some users have expressed interest in making pg_autovacuum more
|
||||||
|
configurable so that certain tables known to be inactive could be
|
||||||
|
excluded from being vacuumed. It would probably make sense to
|
||||||
|
introduce this sort of functionality by providing arguments to specify
|
||||||
|
the database and schema in which to find a configuration table.
|
||||||
|
|
||||||
INSTALL:
|
INSTALL:
|
||||||
--------
|
--------
|
||||||
|
|
||||||
As of postgresql v7.4 pg_autovacuum is included in the main source tree
|
As of postgresql v7.4 pg_autovacuum is included in the main source
|
||||||
under contrib. Therefore you just make && make install (similar to most other
|
tree under contrib. Therefore you merely need to "make && make
|
||||||
contrib modules) and it will be installed for you.
|
install" (similar to most other contrib modules) and it will be
|
||||||
|
installed for you.
|
||||||
|
|
||||||
If you are using an earlier version of postgresql just uncompress the tar.gz
|
If you are using an earlier version of PostgreSQL, uncompress the
|
||||||
into the contrib directory and modify the contrib/Makefile to include the pg_autovacuum
|
tar.gz file into the contrib directory and modify the contrib/Makefile
|
||||||
directory. pg_autovacuum will then be made as part of the standard
|
to include the pg_autovacuum directory. pg_autovacuum will then be
|
||||||
postgresql install.
|
built as part of the standard postgresql install.
|
||||||
|
|
||||||
make sure that the folowing are set in postgresql.conf
|
make sure that the following are set in postgresql.conf:
|
||||||
|
|
||||||
stats_start_collector = true
|
stats_start_collector = true
|
||||||
stats_row_level = true
|
stats_row_level = true
|
||||||
|
|
||||||
start up the postmaster, then execute the pg_autovacuum executable.
|
Start up the postmaster, then execute the pg_autovacuum executable.
|
||||||
|
|
||||||
|
If you have a script that automatically starts up the PostgreSQL
|
||||||
|
instance, you might add in, after that, something similar to the
|
||||||
|
following:
|
||||||
|
|
||||||
|
sleep 10 # To give the database some time to start up
|
||||||
|
$PGBINS/pg_autovacuum -D -s $SBASE -S $SSCALE ... [other arguments]
|
||||||
|
|
||||||
Command line arguments:
|
Command line arguments:
|
||||||
-----------------------
|
-----------------------
|
||||||
@ -69,7 +100,7 @@ Command line arguments:
|
|||||||
pg_autovacuum has the following optional arguments:
|
pg_autovacuum has the following optional arguments:
|
||||||
|
|
||||||
-d debug: 0 silent, 1 basic info, 2 more debug info, etc...
|
-d debug: 0 silent, 1 basic info, 2 more debug info, etc...
|
||||||
-D dameonize: Detach from tty and run in background.
|
-D daemonize: Detach from tty and run in background.
|
||||||
-s sleep base value: see "Sleeping" below.
|
-s sleep base value: see "Sleeping" below.
|
||||||
-S sleep scaling factor: see "Sleeping" below.
|
-S sleep scaling factor: see "Sleeping" below.
|
||||||
-v vacuum base threshold: see Vacuum and Analyze.
|
-v vacuum base threshold: see Vacuum and Analyze.
|
||||||
@ -80,18 +111,18 @@ pg_autovacuum has the following optional arguments:
|
|||||||
-U username: Username pg_autovacuum will use to connect with, if not
|
-U username: Username pg_autovacuum will use to connect with, if not
|
||||||
specified the current username is used.
|
specified the current username is used.
|
||||||
-P password: Password pg_autovacuum will use to connect with.
|
-P password: Password pg_autovacuum will use to connect with.
|
||||||
-H host: host name or IP to connect too.
|
-H host: host name or IP to connect to.
|
||||||
-p port: port used for connection.
|
-p port: port used for connection.
|
||||||
-h help: list of command line options.
|
-h help: list of command line options.
|
||||||
|
|
||||||
All arguments have default values defined in pg_autovacuum.h. At the
|
Numerous arguments have default values defined in pg_autovacuum.h. At
|
||||||
time of writing they are:
|
the time of writing they are:
|
||||||
|
|
||||||
-d 1
|
-d 1
|
||||||
-v 1000
|
-v 1000
|
||||||
-V 2
|
-V 2
|
||||||
-a 500 (half of -v is not specified)
|
-a 500 (half of -v if not specified)
|
||||||
-A 1 (half of -v is not specified)
|
-A 1 (half of -v if not specified)
|
||||||
-s 300 (5 minutes)
|
-s 300 (5 minutes)
|
||||||
-S 2
|
-S 2
|
||||||
|
|
||||||
@ -99,8 +130,9 @@ time of writing they are:
|
|||||||
Vacuum and Analyze:
|
Vacuum and Analyze:
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
pg_autovacuum performs either a vacuum analyze or just analyze depending
|
pg_autovacuum performs either a VACUUM ANALYZE or just ANALYZE
|
||||||
on the quantity and type of table activity (insert, update, or delete):
|
depending on the mixture of table activity (insert, update, or
|
||||||
|
delete):
|
||||||
|
|
||||||
- If the number of (inserts + updates + deletes) > AnalyzeThreshold, then
|
- If the number of (inserts + updates + deletes) > AnalyzeThreshold, then
|
||||||
only an analyze is performed.
|
only an analyze is performed.
|
||||||
@ -115,26 +147,27 @@ insertThreshold is equal to:
|
|||||||
analyze_base_value + (analyze_scaling_factor * "number of tuples in the table")
|
analyze_base_value + (analyze_scaling_factor * "number of tuples in the table")
|
||||||
|
|
||||||
The AnalyzeThreshold defaults to half of the VacuumThreshold since it
|
The AnalyzeThreshold defaults to half of the VacuumThreshold since it
|
||||||
represents a much less expensive operation (approx 5%-10% of vacuum), and
|
represents a much less expensive operation (approx 5%-10% of vacuum),
|
||||||
running it more often should not substantially degrade system performance.
|
and running ANALYZE more often should not substantially degrade system
|
||||||
|
performance.
|
||||||
|
|
||||||
Sleeping:
|
Sleeping:
|
||||||
---------
|
---------
|
||||||
|
|
||||||
pg_autovacuum sleeps for a while after it is done checking all the
|
pg_autovacuum sleeps for a while after it is done checking all the
|
||||||
databases. It does this in order to limit the amount of system
|
databases. It does this in order to limit the amount of system
|
||||||
resources it consumes. This also allows the system administrator to
|
resources it consumes. This allows the system administrator to
|
||||||
configure pg_autovacuum to be more or less aggressive.
|
configure pg_autovacuum to be more or less aggressive.
|
||||||
|
|
||||||
Reducing the sleep time will cause pg_autovacuum to respond more
|
Reducing the sleep time will cause pg_autovacuum to respond more
|
||||||
quickly to changes, whether they be database addition/removal, table
|
quickly to changes, whether they be database addition/removal, table
|
||||||
addition/removal, or just normal table activity.
|
addition/removal, or just normal table activity.
|
||||||
|
|
||||||
On the other hand, setting pg_autovaccum to sleep values to agressivly
|
On the other hand, setting pg_autovacuum to sleep values too
|
||||||
(for too short a period of time) can have a negative effect on server
|
aggressively (to too short periods of time) can have a negative effect
|
||||||
performance. If a table gets vacuumed 5 times during the course of a
|
on server performance. For instance, if a table gets vacuumed 5 times
|
||||||
large update, this is likely to take much longer than if the table was
|
during the course of a large set of updates, this is likely to take a
|
||||||
vacuumed only once, at the end.
|
lot more work than if the table was vacuumed just once, at the end.
|
||||||
|
|
||||||
The total time it sleeps is equal to:
|
The total time it sleeps is equal to:
|
||||||
|
|
||||||
@ -142,15 +175,17 @@ The total time it sleeps is equal to:
|
|||||||
loop"
|
loop"
|
||||||
|
|
||||||
Note that timing measurements are made in seconds; specifying
|
Note that timing measurements are made in seconds; specifying
|
||||||
"pg_vacuum -s 1" means pg_autovacuum could poll the database upto 60 times
|
"pg_vacuum -s 1" means pg_autovacuum could poll the database up to 60
|
||||||
minute. In a system with large tables where vacuums may run for several
|
times minute. In a system with large tables where vacuums may run for
|
||||||
minutes, longer times between vacuums are likely to be appropriate.
|
several minutes, rather longer times between vacuums are likely to be
|
||||||
|
appropriate.
|
||||||
|
|
||||||
What pg_autovacuum monitors:
|
What pg_autovacuum monitors:
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
pg_autovacuum dynamically generates a list of all databases and tables that
|
pg_autovacuum dynamically generates a list of all databases and tables
|
||||||
exist on the server. It will dynamically add and remove databases and
|
that exist on the server. It will dynamically add and remove
|
||||||
tables that are removed from the database server while pg_autovacuum is
|
databases and tables that are removed from the database server while
|
||||||
running. Overhead is fairly small per object. For example: 10 databases
|
pg_autovacuum is running. Overhead is fairly small per object. For
|
||||||
with 10 tables each appears to less than 10k of memory on my Linux box.
|
example: 10 databases with 10 tables each appears to less than 10k of
|
||||||
|
memory on my Linux box.
|
||||||
|
@ -118,6 +118,12 @@ init_table_info(PGresult *res, int row, db_info * dbi)
|
|||||||
new_tbl->reltuples = atoi(PQgetvalue(res, row, PQfnumber(res, "reltuples")));
|
new_tbl->reltuples = atoi(PQgetvalue(res, row, PQfnumber(res, "reltuples")));
|
||||||
new_tbl->relpages = atoi(PQgetvalue(res, row, PQfnumber(res, "relpages")));
|
new_tbl->relpages = atoi(PQgetvalue(res, row, PQfnumber(res, "relpages")));
|
||||||
|
|
||||||
|
log_entry(PQgetvalue(res, row, PQfnumber(res, "relisshared")));
|
||||||
|
if (strcmp("t", PQgetvalue(res, row, PQfnumber(res, "relisshared"))))
|
||||||
|
new_tbl->relisshared = 0;
|
||||||
|
else
|
||||||
|
new_tbl->relisshared = 1;
|
||||||
|
|
||||||
new_tbl->analyze_threshold =
|
new_tbl->analyze_threshold =
|
||||||
args->analyze_base_threshold + args->analyze_scaling_factor * new_tbl->reltuples;
|
args->analyze_base_threshold + args->analyze_scaling_factor * new_tbl->reltuples;
|
||||||
new_tbl->vacuum_threshold =
|
new_tbl->vacuum_threshold =
|
||||||
@ -213,7 +219,7 @@ update_table_list(db_info * dbi)
|
|||||||
* both remove tables from the list that no longer exist and add
|
* both remove tables from the list that no longer exist and add
|
||||||
* tables to the list that are new
|
* tables to the list that are new
|
||||||
*/
|
*/
|
||||||
res = send_query(query_table_stats(dbi), dbi);
|
res = send_query((char *) TABLE_STATS_QUERY, dbi);
|
||||||
t = PQntuples(res);
|
t = PQntuples(res);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -353,7 +359,7 @@ print_table_info(tbl_info * tbl)
|
|||||||
{
|
{
|
||||||
sprintf(logbuffer, " table name: %s.%s", tbl->dbi->dbname, tbl->table_name);
|
sprintf(logbuffer, " table name: %s.%s", tbl->dbi->dbname, tbl->table_name);
|
||||||
log_entry(logbuffer);
|
log_entry(logbuffer);
|
||||||
sprintf(logbuffer, " relfilenode: %i", tbl->relfilenode);
|
sprintf(logbuffer, " relfilenode: %i; relisshared: %i", tbl->relfilenode, tbl->relisshared);
|
||||||
log_entry(logbuffer);
|
log_entry(logbuffer);
|
||||||
sprintf(logbuffer, " reltuples: %i; relpages: %i", tbl->reltuples, tbl->relpages);
|
sprintf(logbuffer, " reltuples: %i; relpages: %i", tbl->reltuples, tbl->relpages);
|
||||||
log_entry(logbuffer);
|
log_entry(logbuffer);
|
||||||
@ -688,19 +694,7 @@ print_db_info(db_info * dbi, int print_tbl_list)
|
|||||||
|
|
||||||
/* End of DB List Management Function */
|
/* End of DB List Management Function */
|
||||||
|
|
||||||
/* Begninning of misc Functions */
|
/* Beginning of misc Functions */
|
||||||
|
|
||||||
|
|
||||||
char *
|
|
||||||
query_table_stats(db_info * dbi)
|
|
||||||
{
|
|
||||||
if (!strcmp(dbi->dbname, "template1")) /* Use template1 to
|
|
||||||
* monitor the system
|
|
||||||
* tables */
|
|
||||||
return (char *) TABLE_STATS_ALL;
|
|
||||||
else
|
|
||||||
return (char *) TABLE_STATS_USER;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Perhaps add some test to this function to make sure that the stats we need are available */
|
/* Perhaps add some test to this function to make sure that the stats we need are available */
|
||||||
PGconn *
|
PGconn *
|
||||||
@ -753,6 +747,9 @@ send_query(const char *query, db_info * dbi)
|
|||||||
if (NULL == dbi->conn)
|
if (NULL == dbi->conn)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
if (args->debug >= 4)
|
||||||
|
log_entry(query);
|
||||||
|
|
||||||
res = PQexec(dbi->conn, query);
|
res = PQexec(dbi->conn, query);
|
||||||
|
|
||||||
if (!res)
|
if (!res)
|
||||||
@ -1055,7 +1052,7 @@ main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (0 == xid_wraparound_check(dbs));
|
if (0 == xid_wraparound_check(dbs));
|
||||||
{
|
{
|
||||||
res = send_query(query_table_stats(dbs), dbs); /* Get an updated
|
res = send_query(TABLE_STATS_QUERY, dbs); /* Get an updated
|
||||||
* snapshot of this dbs
|
* snapshot of this dbs
|
||||||
* table stats */
|
* table stats */
|
||||||
for (j = 0; j < PQntuples(res); j++)
|
for (j = 0; j < PQntuples(res); j++)
|
||||||
@ -1087,7 +1084,11 @@ main(int argc, char *argv[])
|
|||||||
*/
|
*/
|
||||||
if ((tbl->curr_vacuum_count - tbl->CountAtLastVacuum) >= tbl->vacuum_threshold)
|
if ((tbl->curr_vacuum_count - tbl->CountAtLastVacuum) >= tbl->vacuum_threshold)
|
||||||
{
|
{
|
||||||
snprintf(buf, sizeof(buf), "VACUUM ANALYZE \"%s\"", tbl->table_name);
|
/* 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)
|
if (args->debug >= 1)
|
||||||
{
|
{
|
||||||
sprintf(logbuffer, "Performing: %s", buf);
|
sprintf(logbuffer, "Performing: %s", buf);
|
||||||
@ -1101,7 +1102,7 @@ main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
else if ((tbl->curr_analyze_count - tbl->CountAtLastAnalyze) >= tbl->analyze_threshold)
|
else if ((tbl->curr_analyze_count - tbl->CountAtLastAnalyze) >= tbl->analyze_threshold)
|
||||||
{
|
{
|
||||||
snprintf(buf, sizeof(buf), "ANALYZE \"%s\"", tbl->table_name);
|
snprintf(buf, sizeof(buf), "ANALYZE %s", tbl->table_name);
|
||||||
if (args->debug >= 1)
|
if (args->debug >= 1)
|
||||||
{
|
{
|
||||||
sprintf(logbuffer, "Performing: %s", buf);
|
sprintf(logbuffer, "Performing: %s", buf);
|
||||||
|
@ -34,8 +34,8 @@
|
|||||||
#define VACUUM_ANALYZE 0
|
#define VACUUM_ANALYZE 0
|
||||||
#define ANALYZE_ONLY 1
|
#define ANALYZE_ONLY 1
|
||||||
|
|
||||||
#define TABLE_STATS_ALL "select a.relfilenode,a.relname,a.relnamespace,a.relpages,a.reltuples,b.schemaname,b.n_tup_ins,b.n_tup_upd,b.n_tup_del from pg_class a, pg_stat_all_tables b where a.relfilenode=b.relid"
|
#define TABLE_STATS_QUERY "select a.relfilenode,a.relname,a.relnamespace,a.relpages,a.relisshared,a.reltuples,b.schemaname,b.n_tup_ins,b.n_tup_upd,b.n_tup_del from pg_class a, pg_stat_all_tables b where a.relfilenode=b.relid and a.relkind = 'r'"
|
||||||
#define TABLE_STATS_USER "select a.relfilenode,a.relname,a.relnamespace,a.relpages,a.reltuples,b.schemaname,b.n_tup_ins,b.n_tup_upd,b.n_tup_del from pg_class a, pg_stat_user_tables b where a.relfilenode=b.relid"
|
|
||||||
#define FRONTEND
|
#define FRONTEND
|
||||||
#define PAGES_QUERY "select relfilenode,reltuples,relpages from pg_class where relfilenode=%i"
|
#define PAGES_QUERY "select relfilenode,reltuples,relpages from pg_class where relfilenode=%i"
|
||||||
#define FROZENOID_QUERY "select oid,age(datfrozenxid) from pg_database where datname = 'template1'"
|
#define FROZENOID_QUERY "select oid,age(datfrozenxid) from pg_database where datname = 'template1'"
|
||||||
@ -86,6 +86,7 @@ struct tableinfo
|
|||||||
*table_name;
|
*table_name;
|
||||||
int relfilenode,
|
int relfilenode,
|
||||||
reltuples,
|
reltuples,
|
||||||
|
relisshared,
|
||||||
relpages;
|
relpages;
|
||||||
long analyze_threshold,
|
long analyze_threshold,
|
||||||
vacuum_threshold;
|
vacuum_threshold;
|
||||||
@ -132,7 +133,6 @@ static int check_stats_enabled(db_info * dbi);
|
|||||||
static PGconn *db_connect(db_info * dbi);
|
static PGconn *db_connect(db_info * dbi);
|
||||||
static void db_disconnect(db_info * dbi);
|
static void db_disconnect(db_info * dbi);
|
||||||
static PGresult *send_query(const char *query, db_info * dbi);
|
static PGresult *send_query(const char *query, db_info * dbi);
|
||||||
static char *query_table_stats(db_info * dbi);
|
|
||||||
|
|
||||||
/* Other Generally needed Functions */
|
/* Other Generally needed Functions */
|
||||||
static void daemonize(void);
|
static void daemonize(void);
|
||||||
|
Reference in New Issue
Block a user