Re: Another small bug (pg_autovacuum) - Mailing list pgsql-hackers

From Bruce Momjian
Subject Re: Another small bug (pg_autovacuum)
Date
Msg-id 200309131627.h8DGREx06755@candle.pha.pa.us
Whole thread Raw
In response to Re: Another small bug (pg_autovacuum)  (Christopher Browne <cbbrowne@libertyrms.info>)
List pgsql-hackers
This was a combined patch including Matthew T. O'Connor's Patch. 

Applied.  Thanks.

---------------------------------------------------------------------------


Christopher Browne wrote:
> matthew@zeut.net ("Matthew T. O'Connor") writes:
> > 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...
> 
> ? pg_autovacuum
> Index: README.pg_autovacuum
> ===================================================================
> RCS file: /projects/cvsroot/pgsql-server/contrib/pg_autovacuum/README.pg_autovacuum,v
> retrieving revision 1.2
> diff -c -b -r1.2 README.pg_autovacuum
> *** README.pg_autovacuum    12 Jun 2003 01:36:44 -0000    1.2
> --- README.pg_autovacuum    12 Sep 2003 22:45:37 -0000
> ***************
> *** 2,67 ****
>   --------------------
>   
>   pg_autovacuum is a libpq client program that monitors all the
> ! databases associated with a postgresql server.  It uses the stats
>   collector to monitor insert, update and delete activity.  
>   
> ! When a table exceeds its insert or delete threshold (more detail
> ! on thresholds below) then that table will be  vacuumed or analyzed.  
> ! 
> ! This allows postgresql to keep the fsm and table statistics up to
> ! date, and eliminates the need to schedule periodic vacuums.
>   
>   The primary benefit of pg_autovacuum is that the FSM and table
> ! statistic information are updated as needed.  When a table is actively
> ! changing, pg_autovacuum will perform the necessary vacuums and
> ! analyzes, whereas if a table remains static, no cycles will be wasted
> ! performing unnecessary vacuums/analyzes.
>   
>   A secondary benefit of pg_autovacuum is that it ensures that a
> ! 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
> ! data loss.
> ! 
>   
>   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
> - by pg_ctl.  Along the sames lines, when the postmaster exits no one tells
> - pg_autovacuum.  The result is that at the start of the next loop,
> - 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
> - level stats.  The overhead of the stats system has been shown to be
> - significant under certain workloads.  For instance a tight loop of queries
> - performing "select 1" was nearly 30% slower with stats enabled.  However,
> - in practice with more realistic workloads, the stats system overhead is
> - usually nominal.
>   
>   
>   INSTALL:
>   --------
>   
> ! As of postgresql v7.4 pg_autovacuum is included in the main source tree
> ! under contrib.  Therefore you just make && make 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
> ! into the contrib directory and modify the contrib/Makefile to include the pg_autovacuum
> ! directory.  pg_autovacuum will then be made as part of the standard
> ! postgresql install.
>   
> ! make sure that the folowing are set in postgresql.conf
>   
>     stats_start_collector = true
>     stats_row_level = true
>   
> ! start up the postmaster, then execute the pg_autovacuum executable.
>   
>   
>   Command line arguments:
>   -----------------------
> --- 2,98 ----
>   --------------------
>   
>   pg_autovacuum is a libpq client program that monitors all the
> ! databases associated with a PostgreSQL server.  It uses the statistics
>   collector to monitor insert, update and delete activity.
>   
> ! When a table exceeds a insert or delete threshold (for more detail on
> ! thresholds, see "Vacuum and Analyze" below) then that table will be
> ! vacuumed and/or analyzed.
> ! 
> ! This allows PostgreSQL to keep the FSM (Free Space Map) and table
> ! statistics up to date, and eliminates the need to schedule periodic
> ! vacuums.
>   
>   The primary benefit of pg_autovacuum is that the FSM and table
> ! statistic information are updated more nearly as frequently as needed.
> ! When a table is actively changing, pg_autovacuum will perform the
> ! VACUUMs and ANALYZEs that such a table needs, whereas if a table
> ! remains static, no cycles will be wasted performing this
> ! unnecessarily.
>   
>   A secondary benefit of pg_autovacuum is that it ensures that a
> ! 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
> ! data loss.  (See the section in the _Administrator's Guide_ entitled
> ! "Preventing transaction ID wraparound failures" for more details.)
>   
>   KNOWN ISSUES:
>   -------------
>   
> + pg_autovacuum has been tested under Redhat Linux (by me) and Debian
> + GNU/Linux and Solaris (by Christopher B. Browne) and all known bugs
> + have been resolved.  Please report any problems to the hackers list.
> + 
> + pg_autovacuum requires that the statistics system be enabled and
> + reporting row level stats.  The overhead of the stats system has been
> + shown to be significant costly under certain workloads.  For instance,
> + a tight loop of queries performing "select 1" was found to run nearly
> + 30% slower when stats were enabled.  However, in practice, with more
> + 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:
>   --------
>   
> ! As of postgresql v7.4 pg_autovacuum is included in the main source
> ! tree under contrib.  Therefore you merely need to "make && make
> ! install" (similar to most other contrib modules) and it will be
> ! installed for you.
> ! 
> ! If you are using an earlier version of PostgreSQL, uncompress the
> ! tar.gz file into the contrib directory and modify the contrib/Makefile
> ! to include the pg_autovacuum directory.  pg_autovacuum will then be
> ! built as part of the standard postgresql install.
>   
> ! make sure that the following are set in postgresql.conf:
>   
>     stats_start_collector = true
>     stats_row_level = true
>   
> ! 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:
>   -----------------------
> ***************
> *** 69,75 ****
>   pg_autovacuum has the following optional arguments:
>   
>   -d debug: 0 silent, 1 basic info, 2 more debug info,  etc...
> ! -D dameonize: Detach from tty and run in background.
>   -s sleep base value: see "Sleeping" below.
>   -S sleep scaling factor: see "Sleeping" below.
>   -v vacuum base threshold: see Vacuum and Analyze.
> --- 100,106 ----
>   pg_autovacuum has the following optional arguments:
>   
>   -d debug: 0 silent, 1 basic info, 2 more debug info,  etc...
> ! -D daemonize: Detach from tty and run in background.
>   -s sleep base value: see "Sleeping" below.
>   -S sleep scaling factor: see "Sleeping" below.
>   -v vacuum base threshold: see Vacuum and Analyze.
> ***************
> *** 80,97 ****
>   -U username: Username pg_autovacuum will use to connect with, if not
>      specified the current username is used.
>   -P password: Password pg_autovacuum will use to connect with.
> ! -H host: host name or IP to connect too.
>   -p port: port used for connection.
>   -h help: list of command line options.
>   
> ! All arguments have default values defined in pg_autovacuum.h.  At the
> ! time of writing they are:
>   
>   -d 1
>   -v 1000
>   -V 2   
> ! -a 500 (half of -v is not specified)
> ! -A 1   (half of -v is not specified)
>   -s 300 (5 minutes)
>   -S 2
>   
> --- 111,128 ----
>   -U username: Username pg_autovacuum will use to connect with, if not
>      specified the current username is used.
>   -P password: Password pg_autovacuum will use to connect with.
> ! -H host: host name or IP to connect to.
>   -p port: port used for connection.
>   -h help: list of command line options.
>   
> ! Numerous arguments have default values defined in pg_autovacuum.h.  At
> ! the time of writing they are:
>   
>   -d 1
>   -v 1000
>   -V 2   
> ! -a 500 (half of -v if not specified)
> ! -A 1   (half of -v if not specified)
>   -s 300 (5 minutes)
>   -S 2
>   
> ***************
> *** 99,111 ****
>   Vacuum and Analyze:
>   -------------------
>   
> ! pg_autovacuum performs either a vacuum analyze or just analyze depending
> ! on the quantity and type of table activity (insert, update, or delete):
>   
>   - If the number of (inserts + updates + deletes) > AnalyzeThreshold, then
>     only an analyze is performed.
>   
> ! - If the number of (deletes + updates ) > VacuumThreshold, then a
>     vacuum analyze is performed.
>   
>   deleteThreshold is equal to: 
> --- 130,143 ----
>   Vacuum and Analyze:
>   -------------------
>   
> ! pg_autovacuum performs either a VACUUM ANALYZE or just ANALYZE
> ! depending on the mixture of table activity (insert, update, or
> ! delete):
>   
>   - If the number of (inserts + updates + deletes) > AnalyzeThreshold, then
>     only an analyze is performed.
>   
> ! - If the number of (deletes + updates) > VacuumThreshold, then a
>     vacuum analyze is performed.
>   
>   deleteThreshold is equal to: 
> ***************
> *** 115,140 ****
>       analyze_base_value + (analyze_scaling_factor * "number of tuples in the table")
>   
>   The AnalyzeThreshold defaults to half of the VacuumThreshold since it
> ! represents a much less expensive operation (approx 5%-10% of vacuum), and
> ! running it more often should not substantially degrade system performance.
>   
>   Sleeping:
>   ---------
>   
>   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
> ! resources it consumes.  This also allows the system administrator to
>   configure pg_autovacuum to be more or less aggressive.
>   
>   Reducing the sleep time will cause pg_autovacuum to respond more
>   quickly to changes, whether they be database addition/removal, table
>   addition/removal, or just normal table activity.
>   
> ! On the other hand, setting pg_autovaccum to sleep values to agressivly
> ! (for too short a period of time) can have a negative effect on server
> ! performance.  If a table gets vacuumed 5 times during the course of a
> ! large update, this is likely to take much longer than if the table was
> ! vacuumed only once, at the end.
>   
>   The total time it sleeps is equal to:
>   
> --- 147,173 ----
>       analyze_base_value + (analyze_scaling_factor * "number of tuples in the table")
>   
>   The AnalyzeThreshold defaults to half of the VacuumThreshold since it
> ! represents a much less expensive operation (approx 5%-10% of vacuum),
> ! and running ANALYZE more often should not substantially degrade system
> ! performance.
>   
>   Sleeping:
>   ---------
>   
>   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
> ! resources it consumes.  This allows the system administrator to
>   configure pg_autovacuum to be more or less aggressive.
>   
>   Reducing the sleep time will cause pg_autovacuum to respond more
>   quickly to changes, whether they be database addition/removal, table
>   addition/removal, or just normal table activity.
>   
> ! On the other hand, setting pg_autovacuum to sleep values too
> ! aggressively (to too short periods of time) can have a negative effect
> ! on server performance.  For instance, if a table gets vacuumed 5 times
> ! during the course of a large set of updates, this is likely to take a
> ! lot more work than if the table was vacuumed just once, at the end.
>   
>   The total time it sleeps is equal to:
>   
> ***************
> *** 142,156 ****
>     loop"
>   
>   Note that timing measurements are made in seconds; specifying
> ! "pg_vacuum -s 1" means pg_autovacuum could poll the database upto 60 times
> ! minute.  In a system with large tables where vacuums may run for several
> ! minutes, longer times between vacuums are likely to be appropriate.
>   
>   What pg_autovacuum monitors:
>   ----------------------------
>   
> ! pg_autovacuum dynamically generates a list of all databases and tables that
> ! exist on the server.  It will dynamically add and remove databases and
> ! tables that are removed from the database server while pg_autovacuum is
> ! running.  Overhead is fairly small per object.  For example: 10 databases
> ! with 10 tables each appears to less than 10k of memory on my Linux box.
> --- 175,191 ----
>     loop"
>   
>   Note that timing measurements are made in seconds; specifying
> ! "pg_vacuum -s 1" means pg_autovacuum could poll the database up to 60
> ! times minute.  In a system with large tables where vacuums may run for
> ! several minutes, rather longer times between vacuums are likely to be
> ! appropriate.
>   
>   What pg_autovacuum monitors:
>   ----------------------------
>   
> ! pg_autovacuum dynamically generates a list of all databases and tables
> ! that exist on the server.  It will dynamically add and remove
> ! databases and tables that are removed from the database server while
> ! pg_autovacuum is running.  Overhead is fairly small per object.  For
> ! example: 10 databases with 10 tables each appears to less than 10k of
> ! memory on my Linux box.
> Index: pg_autovacuum.c
> ===================================================================
> RCS file: /projects/cvsroot/pgsql-server/contrib/pg_autovacuum/pg_autovacuum.c,v
> retrieving revision 1.5
> diff -c -b -r1.5 pg_autovacuum.c
> *** pg_autovacuum.c    11 Sep 2003 19:01:18 -0000    1.5
> --- pg_autovacuum.c    12 Sep 2003 22:45:37 -0000
> ***************
> *** 118,123 ****
> --- 118,129 ----
>       new_tbl->reltuples = atoi(PQgetvalue(res, row, PQfnumber(res, "reltuples")));
>       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 =
>           args->analyze_base_threshold + args->analyze_scaling_factor * new_tbl->reltuples;
>       new_tbl->vacuum_threshold =
> ***************
> *** 213,219 ****
>            * both remove tables from the list that no longer exist and add
>            * tables to the list that are new
>            */
> !         res = send_query(query_table_stats(dbi), dbi);
>           t = PQntuples(res);
>   
>           /*
> --- 219,225 ----
>            * both remove tables from the list that no longer exist and add
>            * tables to the list that are new
>            */
> !         res = send_query((char *) TABLE_STATS_QUERY, dbi);
>           t = PQntuples(res);
>   
>           /*
> ***************
> *** 353,359 ****
>   {
>       sprintf(logbuffer, "  table name:     %s.%s", tbl->dbi->dbname, tbl->table_name);
>       log_entry(logbuffer);
> !     sprintf(logbuffer, "     relfilenode: %i", tbl->relfilenode);
>       log_entry(logbuffer);
>       sprintf(logbuffer, "     reltuples: %i;  relpages: %i", tbl->reltuples, tbl->relpages);
>       log_entry(logbuffer);
> --- 359,365 ----
>   {
>       sprintf(logbuffer, "  table name:     %s.%s", tbl->dbi->dbname, tbl->table_name);
>       log_entry(logbuffer);
> !     sprintf(logbuffer, "     relfilenode: %i;   relisshared: %i", tbl->relfilenode, tbl->relisshared);
>       log_entry(logbuffer);
>       sprintf(logbuffer, "     reltuples: %i;  relpages: %i", tbl->reltuples, tbl->relpages);
>       log_entry(logbuffer);
> ***************
> *** 688,706 ****
>   
>   /* End of DB List Management Function */
>   
> ! /* Begninning 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 */
>   PGconn *
> --- 694,700 ----
>   
>   /* End of DB List Management Function */
>   
> ! /* Beginning of misc Functions */
>   
>   /* Perhaps add some test to this function to make sure that the stats we need are available */
>   PGconn *
> ***************
> *** 753,758 ****
> --- 747,755 ----
>       if (NULL == dbi->conn)
>           return NULL;
>   
> +     if (args->debug >= 4)
> +       log_entry(query);
> + 
>       res = PQexec(dbi->conn, query);
>   
>       if (!res)
> ***************
> *** 964,970 ****
>       int            j = 0,
>                   loops = 0;
>   
> ! /*    int numInserts, numDeletes, */
>       int            sleep_secs;
>       Dllist       *db_list;
>       Dlelem       *db_elem,
> --- 961,967 ----
>     int            j = 0,
>       loops = 0;
>   
> !   /*    int numInserts, numDeletes, */
>     int            sleep_secs;
>     Dllist       *db_list;
>     Dlelem       *db_elem,
> ***************
> *** 1055,1061 ****
>   
>                   if (0 == xid_wraparound_check(dbs));
>                   {
> !                     res = send_query(query_table_stats(dbs), dbs);        /* Get an updated
>                                                                            * snapshot of this dbs
>                                                                            * table stats */
>                       for (j = 0; j < PQntuples(res); j++)
> --- 1052,1058 ----
>   
>             if (0 == xid_wraparound_check(dbs));
>             {
> !         res = send_query(TABLE_STATS_QUERY, dbs);        /* Get an updated
>                                        * snapshot of this dbs
>                                        * table stats */
>           for (j = 0; j < PQntuples(res); j++)
> ***************
> *** 1087,1093 ****
>                                    */
>                                   if ((tbl->curr_vacuum_count - tbl->CountAtLastVacuum) >= tbl->vacuum_threshold)
>                                   {
> !                                     snprintf(buf, sizeof(buf), "VACUUM ANALYZE \"%s\"", tbl->table_name);
>                                       if (args->debug >= 1)
>                                       {
>                                           sprintf(logbuffer, "Performing: %s", buf);
> --- 1084,1094 ----
>                    */
>                   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);
> ***************
> *** 1101,1107 ****
>                                   }
>                                   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);
> --- 1102,1108 ----
>                     }
>                   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);
> Index: pg_autovacuum.h
> ===================================================================
> RCS file: /projects/cvsroot/pgsql-server/contrib/pg_autovacuum/pg_autovacuum.h,v
> retrieving revision 1.6
> diff -c -b -r1.6 pg_autovacuum.h
> *** pg_autovacuum.h    7 Aug 2003 21:11:57 -0000    1.6
> --- pg_autovacuum.h    12 Sep 2003 22:45:37 -0000
> ***************
> *** 34,41 ****
>   #define VACUUM_ANALYZE        0
>   #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_delfrom
pg_classa, pg_stat_all_tables b where a.relfilenode=b.relid"
 
> ! #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_delfrom
pg_classa, pg_stat_user_tables b where a.relfilenode=b.relid"
 
>   #define FRONTEND
>   #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'"
> --- 34,41 ----
>   #define VACUUM_ANALYZE        0
>   #define ANALYZE_ONLY        1
>   
> ! #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
frompg_class a, pg_stat_all_tables b where a.relfilenode=b.relid and a.relkind = 'r'"
 
> ! 
>   #define FRONTEND
>   #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'"
> ***************
> *** 86,91 ****
> --- 86,92 ----
>                  *table_name;
>       int            relfilenode,
>                   reltuples,
> +                 relisshared,
>                   relpages;
>       long        analyze_threshold,
>                   vacuum_threshold;
> ***************
> *** 132,138 ****
>   static PGconn *db_connect(db_info * dbi);
>   static void db_disconnect(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 */
>   static void daemonize(void);
> --- 133,138 ----
> 
> -- 
> let name="cbbrowne" and tld="libertyrms.info" in String.concat "@" [name;tld];;
> <http://dev6.int.libertyrms.com/>
> Christopher Browne
> (416) 646 3304 x124 (land)
> 
> ---------------------------(end of broadcast)---------------------------
> TIP 3: if posting/reading through Usenet, please send an appropriate
>       subscribe-nomail command to majordomo@postgresql.org so that your
>       message can get through to the mailing list cleanly
> 

--  Bruce Momjian                        |  http://candle.pha.pa.us pgman@candle.pha.pa.us               |  (610)
359-1001+  If your life is a hard drive,     |  13 Roberts Road +  Christ can be your backup.        |  Newtown Square,
Pennsylvania19073
 


pgsql-hackers by date:

Previous
From: Bruce Momjian
Date:
Subject: Re: Another small bug (pg_autovacuum)
Next
From: Larry Rosenman
Date:
Subject: Link.shared help