diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index 09e6beaa838f4b38282a702b1ad0f7b77e917803..8f13a9d674d338c5e951904b1f868e6f9b4dcefd 100644 --- a/src/backend/postmaster/pgstat.c +++ b/src/backend/postmaster/pgstat.c @@ -16,7 +16,7 @@ * * Copyright (c) 2001, PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.18 2002/03/06 06:10:00 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.19 2002/04/03 00:27:25 tgl Exp $ * ---------- */ #include "postgres.h" @@ -133,6 +133,10 @@ static void pgstat_recv_resetcounter(PgStat_MsgResetcounter *msg, int len); * * Called from postmaster at startup. Create the resources required * by the statistics collector process. + * + * NOTE: failure exit from this routine causes the postmaster to abort. + * This is unfriendly and should not be done except in dire straits. + * Better to let the postmaster start with stats collection disabled. * ---------- */ int @@ -173,8 +177,8 @@ pgstat_init(void) */ if ((pgStatSock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { - perror("PGSTAT: socket(2)"); - return -1; + elog(LOG, "PGSTAT: socket() failed: %m"); + goto startup_failed; } /* @@ -187,17 +191,13 @@ pgstat_init(void) alen = sizeof(pgStatAddr); if (bind(pgStatSock, (struct sockaddr *) & pgStatAddr, alen) < 0) { - perror("PGSTAT: bind(2)"); - close(pgStatSock); - pgStatSock = -1; - return -1; + elog(LOG, "PGSTAT: bind(127.0.0.1) failed: %m"); + goto startup_failed; } if (getsockname(pgStatSock, (struct sockaddr *) & pgStatAddr, &alen) < 0) { - perror("PGSTAT: getsockname(2)"); - close(pgStatSock); - pgStatSock = -1; - return -1; + elog(LOG, "PGSTAT: getsockname() failed: %m"); + goto startup_failed; } /* @@ -208,10 +208,8 @@ pgstat_init(void) */ if (connect(pgStatSock, (struct sockaddr *) & pgStatAddr, alen) < 0) { - perror("PGSTAT: connect(2)"); - close(pgStatSock); - pgStatSock = -1; - return -1; + elog(LOG, "PGSTAT: connect() failed: %m"); + goto startup_failed; } /* @@ -222,10 +220,8 @@ pgstat_init(void) */ if (fcntl(pgStatSock, F_SETFL, O_NONBLOCK) < 0) { - perror("PGSTAT: fcntl(2)"); - close(pgStatSock); - pgStatSock = -1; - return -1; + elog(LOG, "PGSTAT: fcntl() failed: %m"); + goto startup_failed; } /* @@ -233,12 +229,22 @@ pgstat_init(void) */ if (pipe(pgStatPmPipe) < 0) { - perror("PGSTAT: pipe(2)"); - close(pgStatSock); - pgStatSock = -1; - return -1; + elog(LOG, "PGSTAT: pipe() failed: %m"); + goto startup_failed; } + return 0; + +startup_failed: + if (pgStatSock >= 0) + close(pgStatSock); + pgStatSock = -1; + + /* Adjust GUC variables to suppress useless activity */ + pgstat_collect_querystring = false; + pgstat_collect_tuplelevel = false; + pgstat_collect_blocklevel = false; + return 0; } @@ -248,6 +254,8 @@ pgstat_init(void) * * Called from postmaster at startup or after an existing collector * died. Fire up a fresh statistics collector. + * + * NOTE: failure exit from this routine causes the postmaster to abort. * ---------- */ int @@ -260,12 +268,11 @@ pgstat_start(void) return 0; /* - * Check that the socket at least is there + * Check that the socket is there, else pgstat_init failed */ if (pgStatSock < 0) { - fprintf(stderr, - "PGSTAT: suppress collector startup due to missing socket\n"); + elog(LOG, "PGSTAT: statistics collector startup skipped"); return 0; } @@ -288,9 +295,9 @@ pgstat_start(void) /* Specific beos actions */ beos_backend_startup_failed(); #endif - perror("PGSTAT: fork(2)"); + elog(LOG, "PGSTAT: fork() failed: %m"); pgStatRunning = 0; - return -1; + return 0; case 0: break; @@ -371,7 +378,7 @@ pgstat_beterm(int pid) { PgStat_MsgBeterm msg; - if (!pgstat_collect_startcollector || pgStatSock < 0) + if (pgStatSock < 0) return; msg.m_hdr.m_type = PGSTAT_MTYPE_BETERM; @@ -401,7 +408,7 @@ pgstat_bestart(void) { PgStat_MsgBestart msg; - if (!pgstat_collect_startcollector || pgStatSock < 0) + if (pgStatSock < 0) return; pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_BESTART); @@ -752,7 +759,7 @@ pgstat_initstats(PgStat_Info *stats, Relation rel) stats->heap_scan_counted = FALSE; stats->index_scan_counted = FALSE; - if (!pgstat_collect_startcollector || pgStatSock < 0) + if (pgStatSock < 0) { stats->no_stats = TRUE; return; @@ -768,7 +775,7 @@ pgstat_initstats(PgStat_Info *stats, Relation rel) malloc(sizeof(PgStat_MsgTabstat *) * pgStatTabstatAlloc); if (pgStatTabstatMessages == NULL) { - perror("PGSTATBE: malloc(2)"); + elog(LOG, "PGSTATBE: malloc() failed"); return; } for (i = 0; i < pgStatTabstatAlloc; i++) @@ -777,7 +784,7 @@ pgstat_initstats(PgStat_Info *stats, Relation rel) malloc(sizeof(PgStat_MsgTabstat)); if (pgStatTabstatMessages[i] == NULL) { - perror("PGSTATBE: malloc(2)"); + elog(LOG, "PGSTATBE: malloc() failed"); return; } } @@ -824,7 +831,7 @@ pgstat_initstats(PgStat_Info *stats, Relation rel) if (pgStatTabstatMessages == NULL) { pgStatTabstatAlloc -= 4; - perror("PGSTATBE: malloc(2)"); + elog(LOG, "PGSTATBE: malloc() failed"); return; } for (i = pgStatTabstatUsed; i < pgStatTabstatAlloc; i++) @@ -834,7 +841,7 @@ pgstat_initstats(PgStat_Info *stats, Relation rel) if (pgStatTabstatMessages[i] == NULL) { pgStatTabstatAlloc -= 4; - perror("PGSTATBE: malloc(2)"); + elog(LOG, "PGSTATBE: malloc() failed"); return; } } @@ -1162,14 +1169,14 @@ pgstat_main(void) */ if (pipe(pgStatPipe) < 0) { - perror("PGSTAT: pipe(2)"); + elog(LOG, "PGSTAT: pipe() failed: %m"); exit(1); } switch (fork()) { case -1: - perror("PGSTAT: fork(2)"); + elog(LOG, "PGSTAT: fork() failed: %m"); exit(1); case 0: @@ -1221,8 +1228,7 @@ pgstat_main(void) &hash_ctl, HASH_ELEM | HASH_FUNCTION); if (pgStatBeDead == NULL) { - fprintf(stderr, - "PGSTAT: Creation of dead backend hash table failed\n"); + elog(LOG, "PGSTAT: Creation of dead backend hash table failed"); exit(1); } @@ -1233,7 +1239,7 @@ pgstat_main(void) sizeof(PgStat_StatBeEntry) * MaxBackends); if (pgStatBeTable == NULL) { - perror("PGSTAT: Allocation of backend table failed"); + elog(LOG, "PGSTAT: Allocation of backend table failed"); exit(1); } memset(pgStatBeTable, 0, sizeof(PgStat_StatBeEntry) * MaxBackends); @@ -1289,7 +1295,7 @@ pgstat_main(void) { if (errno == EINTR) continue; - perror("PGSTAT: select(2)"); + elog(LOG, "PGSTAT: select() failed: %m"); exit(1); } @@ -1329,7 +1335,7 @@ pgstat_main(void) { if (errno == EINTR) continue; - perror("PGSTAT: read(2)"); + elog(LOG, "PGSTAT: read() failed: %m"); exit(1); } if (len == 0) /* EOF on the pipe! */ @@ -1347,7 +1353,7 @@ pgstat_main(void) * sync with the buffer process somehow. Abort so * that we can restart both processes. */ - fprintf(stderr, "PGSTAT: bogus message length\n"); + elog(LOG, "PGSTAT: bogus message length"); exit(1); } } @@ -1497,7 +1503,7 @@ pgstat_recvbuffer(void) */ if (fcntl(writePipe, F_SETFL, O_NONBLOCK) < 0) { - perror("PGSTATBUFF: fcntl(2)"); + elog(LOG, "PGSTATBUFF: fcntl() failed: %m"); exit(1); } @@ -1507,7 +1513,7 @@ pgstat_recvbuffer(void) msgbuffer = (char *) malloc(PGSTAT_RECVBUFFERSZ); if (msgbuffer == NULL) { - perror("PGSTATBUFF: malloc()"); + elog(LOG, "PGSTATBUFF: malloc() failed"); exit(1); } @@ -1534,7 +1540,7 @@ pgstat_recvbuffer(void) { if (!overflow) { - fprintf(stderr, "PGSTATBUFF: Warning - receive buffer full\n"); + elog(LOG, "PGSTATBUFF: Warning - receive buffer full"); overflow = true; } } @@ -1565,7 +1571,7 @@ pgstat_recvbuffer(void) { if (errno == EINTR) continue; - perror("PGSTATBUFF: select(2)"); + elog(LOG, "PGSTATBUFF: select() failed: %m"); exit(1); } @@ -1581,7 +1587,7 @@ pgstat_recvbuffer(void) (struct sockaddr *) &fromaddr, &fromlen); if (len < 0) { - perror("PGSTATBUFF: recvfrom(2)"); + elog(LOG, "PGSTATBUFF: recvfrom() failed: %m"); exit(1); } @@ -1656,7 +1662,7 @@ pgstat_recvbuffer(void) { if (errno == EINTR || errno == EAGAIN) continue; /* not enough space in pipe */ - perror("PGSTATBUFF: write(2)"); + elog(LOG, "PGSTATBUFF: write() failed: %m"); exit(1); } /* NB: len < xfr is okay */ @@ -1709,7 +1715,7 @@ pgstat_add_backend(PgStat_MsgHdr *msg) */ if (msg->m_backendid < 1 || msg->m_backendid > MaxBackends) { - fprintf(stderr, "PGSTAT: Invalid backend ID %d\n", msg->m_backendid); + elog(LOG, "PGSTAT: Invalid backend ID %d", msg->m_backendid); return -1; } @@ -1765,7 +1771,7 @@ pgstat_add_backend(PgStat_MsgHdr *msg) HASH_ENTER, &found); if (dbentry == NULL) { - fprintf(stderr, "PGSTAT: DB hash table out of memory - abort\n"); + elog(LOG, "PGSTAT: DB hash table out of memory - abort"); exit(1); } @@ -1794,8 +1800,8 @@ pgstat_add_backend(PgStat_MsgHdr *msg) HASH_ELEM | HASH_FUNCTION); if (dbentry->tables == NULL) { - fprintf(stderr, "PGSTAT: failed to initialize hash table for " - "new database entry\n"); + elog(LOG, "PGSTAT: failed to initialize hash table for " + "new database entry"); exit(1); } } @@ -1846,8 +1852,7 @@ pgstat_sub_backend(int procpid) HASH_ENTER, &found); if (deadbe == NULL) { - fprintf(stderr, "PGSTAT: dead backend hash table out of memory " - "- abort\n"); + elog(LOG, "PGSTAT: dead backend hash table out of memory"); exit(1); } if (!found) @@ -1894,9 +1899,8 @@ pgstat_write_statsfile(void) fpout = fopen(pgStat_tmpfname, PG_BINARY_W); if (fpout == NULL) { - fprintf(stderr, "PGSTAT: cannot open temp stats file\nPGSTAT: "); - perror(pgStat_tmpfname); - fflush(stderr); + elog(LOG, "PGSTAT: cannot open temp stats file %s: %m", + pgStat_tmpfname); return; } @@ -1921,8 +1925,8 @@ pgstat_write_statsfile(void) (void *) &(dbentry->databaseid), HASH_REMOVE, NULL) == NULL) { - fprintf(stderr, "PGSTAT: database hash table corrupted " - "during cleanup - abort\n"); + elog(LOG, "PGSTAT: database hash table corrupted " + "during cleanup - abort"); exit(1); } } @@ -1957,9 +1961,9 @@ pgstat_write_statsfile(void) (void *) &(tabentry->tableid), HASH_REMOVE, NULL) == NULL) { - fprintf(stderr, "PGSTAT: tables hash table for " + elog(LOG, "PGSTAT: tables hash table for " "database %d corrupted during " - "cleanup - abort\n", + "cleanup - abort", dbentry->databaseid); exit(1); } @@ -2004,20 +2008,15 @@ pgstat_write_statsfile(void) fputc('E', fpout); if (fclose(fpout) < 0) { - fprintf(stderr, "PGSTAT: Error closing temp stats file\nPGSTAT: "); - perror(pgStat_tmpfname); - fprintf(stderr, "PGSTAT: Abort\n"); - fflush(stderr); - exit(1); + elog(LOG, "PGSTAT: Error closing temp stats file %s: %m", + pgStat_tmpfname); } else { if (rename(pgStat_tmpfname, pgStat_fname) < 0) { - fprintf(stderr, "PGSTAT: Cannot rename temp stats file\n" - "PGSTAT: "); - perror(pgStat_fname); - fflush(stderr); + elog(LOG, "PGSTAT: Cannot rename temp stats file %s: %m", + pgStat_fname); } } @@ -2037,8 +2036,8 @@ pgstat_write_statsfile(void) (void *) &(deadbe->procpid), HASH_REMOVE, NULL) == NULL) { - fprintf(stderr, "PGSTAT: dead backend hash table corrupted " - "during cleanup - abort\n"); + elog(LOG, "PGSTAT: dead backend hash table corrupted " + "during cleanup - abort"); exit(1); } } @@ -2102,9 +2101,10 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb, { if (pgStatRunningInCollector) { - fprintf(stderr, "PGSTAT: Creation of DB hash table failed\n"); + elog(LOG, "PGSTAT: Creation of DB hash table failed"); exit(1); } + /* in backend, can do normal error */ elog(ERROR, "PGSTAT: Creation of DB hash table failed"); } @@ -2143,15 +2143,13 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb, { if (pgStatRunningInCollector) { - fprintf(stderr, - "PGSTAT: corrupted pgstat.stat file\n"); + elog(LOG, "PGSTAT: corrupted pgstat.stat file"); fclose(fpin); return; } else { - elog(WARNING, - "PGSTAT: corrupted pgstat.stat file"); + elog(WARNING, "PGSTAT: corrupted pgstat.stat file"); fclose(fpin); return; } @@ -2167,7 +2165,7 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb, { if (pgStatRunningInCollector) { - fprintf(stderr, "PGSTAT: DB hash table out of memory\n"); + elog(LOG, "PGSTAT: DB hash table out of memory"); exit(1); } else @@ -2180,15 +2178,13 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb, { if (pgStatRunningInCollector) { - fprintf(stderr, - "PGSTAT: corrupted pgstat.stat file\n"); + elog(LOG, "PGSTAT: corrupted pgstat.stat file"); fclose(fpin); return; } else { - elog(WARNING, - "PGSTAT: corrupted pgstat.stat file"); + elog(WARNING, "PGSTAT: corrupted pgstat.stat file"); fclose(fpin); return; } @@ -2219,15 +2215,15 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb, { if (pgStatRunningInCollector) { - fprintf(stderr, "PGSTAT: failed to initialize " - "hash table for new database entry\n"); + elog(LOG, "PGSTAT: failed to initialize " + "hash table for new database entry"); exit(1); } else { fclose(fpin); elog(ERROR, "PGSTAT: failed to initialize " - "hash table for new database entry\n"); + "hash table for new database entry"); } } @@ -2253,15 +2249,13 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb, { if (pgStatRunningInCollector) { - fprintf(stderr, - "PGSTAT: corrupted pgstat.stat file\n"); + elog(LOG, "PGSTAT: corrupted pgstat.stat file"); fclose(fpin); return; } else { - elog(WARNING, - "PGSTAT: corrupted pgstat.stat file"); + elog(WARNING, "PGSTAT: corrupted pgstat.stat file"); fclose(fpin); return; } @@ -2280,7 +2274,7 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb, { if (pgStatRunningInCollector) { - fprintf(stderr, "PGSTAT: Tab hash table out of memory\n"); + elog(LOG, "PGSTAT: Tab hash table out of memory"); exit(1); } else @@ -2294,15 +2288,13 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb, { if (pgStatRunningInCollector) { - fprintf(stderr, - "PGSTAT: corrupted pgstat.stat file\n"); + elog(LOG, "PGSTAT: corrupted pgstat.stat file"); fclose(fpin); return; } else { - elog(WARNING, - "PGSTAT: corrupted pgstat.stat file"); + elog(WARNING, "PGSTAT: corrupted pgstat.stat file"); fclose(fpin); return; } @@ -2325,15 +2317,13 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb, { if (pgStatRunningInCollector) { - fprintf(stderr, - "PGSTAT: corrupted pgstat.stat file\n"); + elog(LOG, "PGSTAT: corrupted pgstat.stat file"); fclose(fpin); return; } else { - elog(WARNING, - "PGSTAT: corrupted pgstat.stat file"); + elog(WARNING, "PGSTAT: corrupted pgstat.stat file"); fclose(fpin); return; } @@ -2381,15 +2371,13 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb, { if (pgStatRunningInCollector) { - fprintf(stderr, - "PGSTAT: corrupted pgstat.stat file\n"); + elog(LOG, "PGSTAT: corrupted pgstat.stat file"); fclose(fpin); return; } else { - elog(WARNING, - "PGSTAT: corrupted pgstat.stat file"); + elog(WARNING, "PGSTAT: corrupted pgstat.stat file"); fclose(fpin); return; } @@ -2424,7 +2412,7 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb, default: if (pgStatRunningInCollector) { - fprintf(stderr, "PGSTAT: corrupted pgstat.stat file\n"); + elog(LOG, "PGSTAT: corrupted pgstat.stat file"); fclose(fpin); return; } @@ -2539,8 +2527,8 @@ pgstat_recv_tabstat(PgStat_MsgTabstat *msg, int len) HASH_ENTER, &found); if (tabentry == NULL) { - fprintf(stderr, "PGSTAT: tables hash table out of memory for " - "database %d - abort\n", dbentry->databaseid); + elog(LOG, "PGSTAT: tables hash table out of memory for " + "database %d - abort", dbentry->databaseid); exit(1); } @@ -2719,8 +2707,8 @@ pgstat_recv_resetcounter(PgStat_MsgResetcounter *msg, int len) HASH_ELEM | HASH_FUNCTION); if (dbentry->tables == NULL) { - fprintf(stderr, "PGSTAT: failed to reinitialize hash table for " - "database entry\n"); + elog(LOG, "PGSTAT: failed to reinitialize hash table for " + "database entry"); exit(1); } }