Tweak stats collector start logic so that we will not try to spawn a

new stats collector oftener than once a minute.  Per gripe from Erik Walthinsen
4/25/03.
This commit is contained in:
Tom Lane 2003-04-26 02:57:14 +00:00
parent 9fdb1de3ba
commit 2b1e36c7c0
3 changed files with 89 additions and 54 deletions

View File

@ -10,13 +10,10 @@
* *
* - Add a pgstat config column to pg_database, so this * - Add a pgstat config column to pg_database, so this
* entire thing can be enabled/disabled on a per db base. * entire thing can be enabled/disabled on a per db base.
* Not to be done before 7.2 - requires catalog change and
* thus an initdb and we might want to provide this as a
* patch for 7.1.
* *
* Copyright (c) 2001, PostgreSQL Global Development Group * Copyright (c) 2001-2003, PostgreSQL Global Development Group
* *
* $Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.33 2003/04/25 01:24:00 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.34 2003/04/26 02:57:14 tgl Exp $
* ---------- * ----------
*/ */
#include "postgres.h" #include "postgres.h"
@ -31,6 +28,8 @@
#include <errno.h> #include <errno.h>
#include <signal.h> #include <signal.h>
#include "pgstat.h"
#include "access/xact.h" #include "access/xact.h"
#include "access/heapam.h" #include "access/heapam.h"
#include "catalog/catname.h" #include "catalog/catname.h"
@ -47,8 +46,6 @@
#include "utils/ps_status.h" #include "utils/ps_status.h"
#include "utils/syscache.h" #include "utils/syscache.h"
#include "pgstat.h"
/* ---------- /* ----------
* GUC parameters * GUC parameters
@ -60,6 +57,12 @@ bool pgstat_collect_querystring = false;
bool pgstat_collect_tuplelevel = false; bool pgstat_collect_tuplelevel = false;
bool pgstat_collect_blocklevel = false; bool pgstat_collect_blocklevel = false;
/* ----------
* Other global variables
* ----------
*/
bool pgstat_is_running = false;
/* ---------- /* ----------
* Local data * Local data
* ---------- * ----------
@ -69,8 +72,8 @@ static int pgStatPipe[2];
static struct sockaddr_in pgStatAddr; static struct sockaddr_in pgStatAddr;
static int pgStatPmPipe[2] = {-1, -1}; static int pgStatPmPipe[2] = {-1, -1};
static int pgStatRunning = 0;
static int pgStatPid; static int pgStatPid;
static time_t last_pgstat_start_time;
static long pgStatNumMessages = 0; static long pgStatNumMessages = 0;
@ -130,14 +133,12 @@ static void pgstat_recv_resetcounter(PgStat_MsgResetcounter *msg, int len);
* pgstat_init() - * pgstat_init() -
* *
* Called from postmaster at startup. Create the resources required * Called from postmaster at startup. Create the resources required
* by the statistics collector process. * by the statistics collector process. If unable to do so, do not
* * fail --- better to let the postmaster start with stats collection
* NOTE: failure exit from this routine causes the postmaster to abort. * disabled.
* This is unfriendly and should not be done except in dire straits.
* Better to let the postmaster start with stats collection disabled.
* ---------- * ----------
*/ */
int void
pgstat_init(void) pgstat_init(void)
{ {
int alen; int alen;
@ -168,7 +169,7 @@ pgstat_init(void)
* Nothing else required if collector will not get started * Nothing else required if collector will not get started
*/ */
if (!pgstat_collect_startcollector) if (!pgstat_collect_startcollector)
return 0; return;
/* /*
* Create the UDP socket for sending and receiving statistic messages * Create the UDP socket for sending and receiving statistic messages
@ -231,7 +232,7 @@ pgstat_init(void)
goto startup_failed; goto startup_failed;
} }
return 0; return;
startup_failed: startup_failed:
if (pgStatSock >= 0) if (pgStatSock >= 0)
@ -239,11 +240,10 @@ startup_failed:
pgStatSock = -1; pgStatSock = -1;
/* Adjust GUC variables to suppress useless activity */ /* Adjust GUC variables to suppress useless activity */
pgstat_collect_startcollector = false;
pgstat_collect_querystring = false; pgstat_collect_querystring = false;
pgstat_collect_tuplelevel = false; pgstat_collect_tuplelevel = false;
pgstat_collect_blocklevel = false; pgstat_collect_blocklevel = false;
return 0;
} }
@ -251,31 +251,51 @@ startup_failed:
* pgstat_start() - * pgstat_start() -
* *
* Called from postmaster at startup or after an existing collector * Called from postmaster at startup or after an existing collector
* died. Fire up a fresh statistics collector. * died. Attempt to fire up a fresh statistics collector.
* *
* NOTE: failure exit from this routine causes the postmaster to abort. * Note: if fail, we will be called again from the postmaster main loop.
* ---------- * ----------
*/ */
int void
pgstat_start(void) pgstat_start(void)
{ {
time_t curtime;
/* /*
* Do nothing if no collector needed * Do nothing if no collector needed
*/ */
if (!pgstat_collect_startcollector) if (pgstat_is_running || !pgstat_collect_startcollector)
return 0; return;
/* /*
* Check that the socket is there, else pgstat_init failed * Do nothing if too soon since last collector start. This is a
* safety valve to protect against continuous respawn attempts if
* the collector is dying immediately at launch. Note that since
* we will be re-called from the postmaster main loop, we will get
* another chance later.
*/
curtime = time(NULL);
if ((unsigned int) (curtime - last_pgstat_start_time) <
(unsigned int) PGSTAT_RESTART_INTERVAL)
return;
last_pgstat_start_time = curtime;
/*
* Check that the socket is there, else pgstat_init failed.
*/ */
if (pgStatSock < 0) if (pgStatSock < 0)
{ {
elog(LOG, "PGSTAT: statistics collector startup skipped"); elog(LOG, "PGSTAT: statistics collector startup skipped");
return 0; /*
* We can only get here if someone tries to manually turn
* pgstat_collect_startcollector on after it had been off.
*/
pgstat_collect_startcollector = false;
return;
} }
/* /*
* Then fork off the collector. Remember its PID for pgstat_ispgstat. * Okay, fork off the collector. Remember its PID for pgstat_ispgstat.
*/ */
fflush(stdout); fflush(stdout);
@ -294,15 +314,14 @@ pgstat_start(void)
beos_backend_startup_failed(); beos_backend_startup_failed();
#endif #endif
elog(LOG, "PGSTAT: fork() failed: %m"); elog(LOG, "PGSTAT: fork() failed: %m");
pgStatRunning = 0; return;
return 0;
case 0: case 0:
break; break;
default: default:
pgStatRunning = 1; pgstat_is_running = true;
return 0; return;
} }
/* in postmaster child ... */ /* in postmaster child ... */
@ -335,16 +354,19 @@ pgstat_start(void)
* was the statistics collector. * was the statistics collector.
* ---------- * ----------
*/ */
int bool
pgstat_ispgstat(int pid) pgstat_ispgstat(int pid)
{ {
if (pgStatRunning == 0) if (!pgstat_is_running)
return 0; return false;
if (pgStatPid != pid) if (pgStatPid != pid)
return 0; return false;
return 1; /* Oh dear ... */
pgstat_is_running = false;
return true;
} }

View File

@ -37,7 +37,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.314 2003/04/22 00:08:06 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.315 2003/04/26 02:57:14 tgl Exp $
* *
* NOTES * NOTES
* *
@ -790,12 +790,10 @@ PostmasterMain(int argc, char *argv[])
} }
/* /*
* Initialize and startup the statistics collector process * Initialize and try to startup the statistics collector process
*/ */
if (pgstat_init() < 0) pgstat_init();
ExitPostmaster(1); pgstat_start();
if (pgstat_start() < 0)
ExitPostmaster(1);
/* /*
* Load cached files for client authentication. * Load cached files for client authentication.
@ -1058,6 +1056,10 @@ ServerLoop(void)
ConnFree(port); ConnFree(port);
} }
} }
/* If we have lost the stats collector, try to start a new one */
if (!pgstat_is_running)
pgstat_start();
} }
} }
@ -1720,8 +1722,9 @@ reaper(SIGNAL_ARGS)
#endif #endif
/* /*
* Check if this child was the statistics collector. If so, start * Check if this child was the statistics collector. If so,
* a new one. * try to start a new one. (If fail, we'll try again in
* future cycles of the main loop.)
*/ */
if (pgstat_ispgstat(pid)) if (pgstat_ispgstat(pid))
{ {

View File

@ -3,15 +3,18 @@
* *
* Definitions for the PostgreSQL statistics collector daemon. * Definitions for the PostgreSQL statistics collector daemon.
* *
* Copyright (c) 2001, PostgreSQL Global Development Group * Copyright (c) 2001-2003, PostgreSQL Global Development Group
* *
* $Id: pgstat.h,v 1.13 2003/03/20 03:34:56 momjian Exp $ * $Id: pgstat.h,v 1.14 2003/04/26 02:57:14 tgl Exp $
* ---------- * ----------
*/ */
#ifndef PGSTAT_H #ifndef PGSTAT_H
#define PGSTAT_H #define PGSTAT_H
#include "utils/hsearch.h"
#include "utils/nabstime.h" #include "utils/nabstime.h"
#include "utils/rel.h"
/* ---------- /* ----------
* Paths for the statistics files. The %s is replaced with the * Paths for the statistics files. The %s is replaced with the
@ -26,16 +29,17 @@
* ---------- * ----------
*/ */
#define PGSTAT_STAT_INTERVAL 500 /* How often to write the status */ #define PGSTAT_STAT_INTERVAL 500 /* How often to write the status */
/* file, in milliseconds. */ /* file; in milliseconds. */
#define PGSTAT_DESTROY_DELAY 10000 /* How long to keep destroyed */ #define PGSTAT_DESTROY_DELAY 10000 /* How long to keep destroyed */
/* objects known to give delayed */ /* objects known, to give delayed */
/* UDP packets time to arrive, */ /* UDP packets time to arrive; */
/* in milliseconds. */ /* in milliseconds. */
#define PGSTAT_DESTROY_COUNT (PGSTAT_DESTROY_DELAY \ #define PGSTAT_DESTROY_COUNT (PGSTAT_DESTROY_DELAY / PGSTAT_STAT_INTERVAL)
/ PGSTAT_STAT_INTERVAL)
#define PGSTAT_RESTART_INTERVAL 60 /* How often to attempt to restart */
/* a failed statistics collector; in seconds. */
/* ---------- /* ----------
* How much of the actual query string to send to the collector. * How much of the actual query string to send to the collector.
@ -323,7 +327,7 @@ typedef union PgStat_Msg
/* ---------- /* ----------
* Global variables * GUC parameters
* ---------- * ----------
*/ */
extern bool pgstat_collect_startcollector; extern bool pgstat_collect_startcollector;
@ -332,13 +336,19 @@ extern bool pgstat_collect_querystring;
extern bool pgstat_collect_tuplelevel; extern bool pgstat_collect_tuplelevel;
extern bool pgstat_collect_blocklevel; extern bool pgstat_collect_blocklevel;
/* ----------
* Other global variables
* ----------
*/
extern bool pgstat_is_running;
/* ---------- /* ----------
* Functions called from postmaster * Functions called from postmaster
* ---------- * ----------
*/ */
extern int pgstat_init(void); extern void pgstat_init(void);
extern int pgstat_start(void); extern void pgstat_start(void);
extern int pgstat_ispgstat(int pid); extern bool pgstat_ispgstat(int pid);
extern void pgstat_close_sockets(void); extern void pgstat_close_sockets(void);
extern void pgstat_beterm(int pid); extern void pgstat_beterm(int pid);