1010 *
1111 *- Add a pgstat config column to pg_database, so this
1212 * entire thing can be enabled/disabled on a per db base.
13- * Not to be done before 7.2 - requires catalog change and
14- * thus an initdb and we might want to provide this as a
15- * patch for 7.1.
1613 *
17- *Copyright (c) 2001, PostgreSQL Global Development Group
14+ *Copyright (c) 2001-2003 , PostgreSQL Global Development Group
1815 *
19- *$Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.33 2003/04/25 01:24:00 momjian Exp $
16+ *$Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.34 2003/04/26 02:57:14 tgl Exp $
2017 * ----------
2118 */
2219#include "postgres.h"
3128#include <errno.h>
3229#include <signal.h>
3330
31+ #include "pgstat.h"
32+
3433#include "access/xact.h"
3534#include "access/heapam.h"
3635#include "catalog/catname.h"
4746#include "utils/ps_status.h"
4847#include "utils/syscache.h"
4948
50- #include "pgstat.h"
51-
5249
5350/* ----------
5451 * GUC parameters
@@ -60,6 +57,12 @@ boolpgstat_collect_querystring = false;
6057bool pgstat_collect_tuplelevel = false;
6158bool pgstat_collect_blocklevel = false;
6259
60+ /* ----------
61+ * Other global variables
62+ * ----------
63+ */
64+ bool pgstat_is_running = false;
65+
6366/* ----------
6467 * Local data
6568 * ----------
@@ -69,8 +72,8 @@ static intpgStatPipe[2];
6972static struct sockaddr_in pgStatAddr ;
7073static int pgStatPmPipe [2 ]= {-1 ,-1 };
7174
72- static int pgStatRunning = 0 ;
7375static int pgStatPid ;
76+ static time_t last_pgstat_start_time ;
7477
7578static long pgStatNumMessages = 0 ;
7679
@@ -130,14 +133,12 @@ static void pgstat_recv_resetcounter(PgStat_MsgResetcounter *msg, int len);
130133 * pgstat_init() -
131134 *
132135 *Called from postmaster at startup. Create the resources required
133- *by the statistics collector process.
134- *
135- *NOTE: failure exit from this routine causes the postmaster to abort.
136- *This is unfriendly and should not be done except in dire straits.
137- *Better to let the postmaster start with stats collection disabled.
136+ *by the statistics collector process. If unable to do so, do not
137+ *fail --- better to let the postmaster start with stats collection
138+ *disabled.
138139 * ----------
139140 */
140- int
141+ void
141142pgstat_init (void )
142143{
143144int alen ;
@@ -168,7 +169,7 @@ pgstat_init(void)
168169 * Nothing else required if collector will not get started
169170 */
170171if (!pgstat_collect_startcollector )
171- return 0 ;
172+ return ;
172173
173174/*
174175 * Create the UDP socket for sending and receiving statistic messages
@@ -231,51 +232,70 @@ pgstat_init(void)
231232gotostartup_failed ;
232233}
233234
234- return 0 ;
235+ return ;
235236
236237startup_failed :
237238if (pgStatSock >=0 )
238239closesocket (pgStatSock );
239240pgStatSock = -1 ;
240241
241242/* Adjust GUC variables to suppress useless activity */
243+ pgstat_collect_startcollector = false;
242244pgstat_collect_querystring = false;
243245pgstat_collect_tuplelevel = false;
244246pgstat_collect_blocklevel = false;
245-
246- return 0 ;
247247}
248248
249249
250250/* ----------
251251 * pgstat_start() -
252252 *
253253 *Called from postmaster at startup or after an existing collector
254- *died.Fire up a fresh statistics collector.
254+ *died.Attempt to fire up a fresh statistics collector.
255255 *
256- *NOTE: failure exit from this routine causes the postmasterto abort .
256+ *Note: if fail, we will be called again from the postmastermain loop .
257257 * ----------
258258 */
259- int
259+ void
260260pgstat_start (void )
261261{
262+ time_t curtime ;
263+
262264/*
263265 * Do nothing if no collector needed
264266 */
265- if (!pgstat_collect_startcollector )
266- return 0 ;
267+ if (pgstat_is_running || !pgstat_collect_startcollector )
268+ return ;
269+
270+ /*
271+ * Do nothing if too soon since last collector start. This is a
272+ * safety valve to protect against continuous respawn attempts if
273+ * the collector is dying immediately at launch. Note that since
274+ * we will be re-called from the postmaster main loop, we will get
275+ * another chance later.
276+ */
277+ curtime = time (NULL );
278+ if ((unsignedint ) (curtime - last_pgstat_start_time )<
279+ (unsignedint )PGSTAT_RESTART_INTERVAL )
280+ return ;
281+ last_pgstat_start_time = curtime ;
267282
268283/*
269- * Check that the socket is there, else pgstat_init failed
284+ * Check that the socket is there, else pgstat_init failed.
270285 */
271286if (pgStatSock < 0 )
272287{
273288elog (LOG ,"PGSTAT: statistics collector startup skipped" );
274- return 0 ;
289+ /*
290+ * We can only get here if someone tries to manually turn
291+ * pgstat_collect_startcollector on after it had been off.
292+ */
293+ pgstat_collect_startcollector = false;
294+ return ;
275295}
276296
277297/*
278- *Then fork off the collector. Remember its PID for pgstat_ispgstat.
298+ *Okay, fork off the collector. Remember its PID for pgstat_ispgstat.
279299 */
280300
281301fflush (stdout );
@@ -294,15 +314,14 @@ pgstat_start(void)
294314beos_backend_startup_failed ();
295315#endif
296316elog (LOG ,"PGSTAT: fork() failed: %m" );
297- pgStatRunning = 0 ;
298- return 0 ;
317+ return ;
299318
300319case 0 :
301320break ;
302321
303322default :
304- pgStatRunning = 1 ;
305- return 0 ;
323+ pgstat_is_running = true ;
324+ return ;
306325}
307326
308327/* in postmaster child ... */
@@ -335,16 +354,19 @@ pgstat_start(void)
335354 *was the statistics collector.
336355 * ----------
337356 */
338- int
357+ bool
339358pgstat_ispgstat (int pid )
340359{
341- if (pgStatRunning == 0 )
342- return 0 ;
360+ if (! pgstat_is_running )
361+ return false ;
343362
344363if (pgStatPid != pid )
345- return 0 ;
364+ return false;
365+
366+ /* Oh dear ... */
367+ pgstat_is_running = false;
346368
347- return 1 ;
369+ return true ;
348370}
349371
350372