1313 *
1414 *Copyright (c) 2001-2003, PostgreSQL Global Development Group
1515 *
16- *$PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.74 2004/06/03 02 :08:03 tgl Exp $
16+ *$PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.75 2004/06/14 18 :08:18 tgl Exp $
1717 * ----------
1818 */
1919#include "postgres.h"
@@ -65,12 +65,6 @@ boolpgstat_collect_querystring = false;
6565bool pgstat_collect_tuplelevel = false;
6666bool pgstat_collect_blocklevel = false;
6767
68- /* ----------
69- * Other global variables
70- * ----------
71- */
72- bool pgstat_is_running = false;
73-
7468/* ----------
7569 * Local data
7670 * ----------
@@ -79,7 +73,6 @@ NON_EXEC_STATIC intpgStatSock = -1;
7973static int pgStatPipe [2 ];
8074static struct sockaddr_storage pgStatAddr ;
8175
82- static int pgStatPid ;
8376static time_t last_pgstat_start_time ;
8477
8578static long pgStatNumMessages = 0 ;
@@ -125,6 +118,7 @@ static void pgstat_parseArgs(int argc, char *argv[]);
125118NON_EXEC_STATIC void PgstatBufferMain (int argc ,char * argv []);
126119NON_EXEC_STATIC void PgstatCollectorMain (int argc ,char * argv []);
127120static void pgstat_recvbuffer (void );
121+ static void pgstat_exit (SIGNAL_ARGS );
128122static void pgstat_die (SIGNAL_ARGS );
129123
130124static int pgstat_add_backend (PgStat_MsgHdr * msg );
@@ -496,19 +490,22 @@ pgstat_parseArgs(int argc, char *argv[])
496490 *Called from postmaster at startup or after an existing collector
497491 *died. Attempt to fire up a fresh statistics collector.
498492 *
493+ *Returns PID of child process, or 0 if fail.
494+ *
499495 *Note: if fail, we will be called again from the postmaster main loop.
500496 * ----------
501497 */
502- void
498+ int
503499pgstat_start (void )
504500{
505501time_t curtime ;
502+ pid_t pgStatPid ;
506503
507504/*
508505 * Do nothing if no collector needed
509506 */
510- if (pgstat_is_running || !pgstat_collect_startcollector )
511- return ;
507+ if (!pgstat_collect_startcollector )
508+ return 0 ;
512509
513510/*
514511 * Do nothing if too soon since last collector start. This is a
@@ -520,7 +517,7 @@ pgstat_start(void)
520517curtime = time (NULL );
521518if ((unsignedint ) (curtime - last_pgstat_start_time )<
522519(unsignedint )PGSTAT_RESTART_INTERVAL )
523- return ;
520+ return 0 ;
524521last_pgstat_start_time = curtime ;
525522
526523/*
@@ -536,12 +533,11 @@ pgstat_start(void)
536533 * pgstat_collect_startcollector on after it had been off.
537534 */
538535pgstat_collect_startcollector = false;
539- return ;
536+ return 0 ;
540537}
541538
542539/*
543- * Okay, fork off the collector. Remember its PID for
544- * pgstat_ispgstat.
540+ * Okay, fork off the collector.
545541 */
546542
547543fflush (stdout );
@@ -553,9 +549,9 @@ pgstat_start(void)
553549#endif
554550
555551#ifdef EXEC_BACKEND
556- switch ((pgStatPid = ( int ) pgstat_forkexec (STAT_PROC_BUFFER )))
552+ switch ((pgStatPid = pgstat_forkexec (STAT_PROC_BUFFER )))
557553#else
558- switch ((pgStatPid = ( int ) fork ()))
554+ switch ((pgStatPid = fork ()))
559555#endif
560556{
561557case -1 :
@@ -565,7 +561,7 @@ pgstat_start(void)
565561#endif
566562ereport (LOG ,
567563(errmsg ("could not fork statistics buffer: %m" )));
568- return ;
564+ return 0 ;
569565
570566#ifndef EXEC_BACKEND
571567case 0 :
@@ -585,32 +581,11 @@ pgstat_start(void)
585581#endif
586582
587583default :
588- pgstat_is_running = true;
589- return ;
584+ return (int )pgStatPid ;
590585}
591- }
592586
593-
594- /* ----------
595- * pgstat_ispgstat() -
596- *
597- *Called from postmaster to check if a terminated child process
598- *was the statistics collector.
599- * ----------
600- */
601- bool
602- pgstat_ispgstat (int pid )
603- {
604- if (!pgstat_is_running )
605- return false;
606-
607- if (pgStatPid != pid )
608- return false;
609-
610- /* Oh dear ... */
611- pgstat_is_running = false;
612-
613- return true;
587+ /* shouldn't get here */
588+ return 0 ;
614589}
615590
616591
@@ -1381,12 +1356,12 @@ PgstatBufferMain(int argc, char *argv[])
13811356
13821357/*
13831358 * Ignore all signals usually bound to some action in the postmaster,
1384- * except for SIGCHLD --- see pgstat_recvbuffer.
1359+ * except for SIGCHLDand SIGQUIT --- see pgstat_recvbuffer.
13851360 */
13861361pqsignal (SIGHUP ,SIG_IGN );
13871362pqsignal (SIGINT ,SIG_IGN );
13881363pqsignal (SIGTERM ,SIG_IGN );
1389- pqsignal (SIGQUIT ,SIG_IGN );
1364+ pqsignal (SIGQUIT ,pgstat_exit );
13901365pqsignal (SIGALRM ,SIG_IGN );
13911366pqsignal (SIGPIPE ,SIG_IGN );
13921367pqsignal (SIGUSR1 ,SIG_IGN );
@@ -1476,9 +1451,9 @@ PgstatCollectorMain(int argc, char *argv[])
14761451
14771452/*
14781453 * Reset signal handling. With the exception of restoring default
1479- * SIGCHLD handling, this is a no-op in the non-EXEC_BACKEND case
1480- * because we'll have inherited these settings from the buffer process;
1481- * but it's not a no-op for EXEC_BACKEND.
1454+ * SIGCHLDand SIGQUIT handling, this is a no-op in the non-EXEC_BACKEND
1455+ *case because we'll have inherited these settings from the buffer
1456+ *process; but it's not a no-op for EXEC_BACKEND.
14821457 */
14831458pqsignal (SIGHUP ,SIG_IGN );
14841459pqsignal (SIGINT ,SIG_IGN );
@@ -1885,9 +1860,9 @@ pgstat_recvbuffer(void)
18851860}
18861861
18871862/*
1888- * Wait for some work to do; but not for more than 10 seconds
1889- * (this determines how quickly we will shut down afterpostmaster
1890- * termination).
1863+ * Wait for some work to do; but not for more than 10 seconds.
1864+ * (This determines how quickly we will shut down afteran
1865+ *ungraceful postmaster termination; so it needn't be very fast.)
18911866 */
18921867timeout .tv_sec = 10 ;
18931868timeout .tv_usec = 0 ;
@@ -1992,19 +1967,33 @@ pgstat_recvbuffer(void)
19921967
19931968/*
19941969 * Make sure we forwarded all messages before we check for
1995- *Postmaster termination.
1970+ *postmaster termination.
19961971 */
19971972if (msg_have != 0 || FD_ISSET (pgStatSock ,& rfds ))
19981973continue ;
19991974
20001975/*
2001- * If the postmaster has terminated, we've done our job.
1976+ * If the postmaster has terminated, we die too. (This is no longer
1977+ * the normal exit path, however.)
20021978 */
20031979if (!PostmasterIsAlive (true))
20041980exit (0 );
20051981}
20061982}
20071983
1984+ /* SIGQUIT signal handler for buffer process */
1985+ static void
1986+ pgstat_exit (SIGNAL_ARGS )
1987+ {
1988+ /*
1989+ * For now, we just nail the doors shut and get out of town. It might
1990+ * be cleaner to allow any pending messages to be sent, but that creates
1991+ * a tradeoff against speed of exit.
1992+ */
1993+ exit (0 );
1994+ }
1995+
1996+ /* SIGCHLD signal handler for buffer process */
20081997static void
20091998pgstat_die (SIGNAL_ARGS )
20101999{