1313 *
1414 *Copyright (c) 2001-2004, PostgreSQL Global Development Group
1515 *
16- *$PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.83 2004/10/25 06:27:21 neilc Exp $
16+ *$PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.84 2004/10/28 01:38:41 neilc Exp $
1717 * ----------
1818 */
1919#include "postgres.h"
4242#include "miscadmin.h"
4343#include "postmaster/postmaster.h"
4444#include "storage/backendid.h"
45+ #include "storage/fd.h"
4546#include "storage/ipc.h"
4647#include "storage/pg_shmem.h"
4748#include "storage/pmsignal.h"
@@ -682,7 +683,7 @@ pgstat_bestart(void)
682683/* ----------
683684 * pgstat_report_activity() -
684685 *
685- *Calledin tcop/postgres.c to tell the collector what the backend
686+ *Calledfrom tcop/postgres.c to tell the collector what the backend
686687 *is actually doing (usually "<IDLE>" or the start of the query to
687688 *be executed).
688689 * ----------
@@ -988,7 +989,7 @@ pgstat_ping(void)
988989/*
989990 * Create or enlarge the pgStatTabstatMessages array
990991 */
991- static bool
992+ static void
992993more_tabstat_space (void )
993994{
994995PgStat_MsgTabstat * newMessages ;
@@ -998,39 +999,25 @@ more_tabstat_space(void)
998999
9991000/* Create (another) quantum of message buffers */
10001001newMessages = (PgStat_MsgTabstat * )
1001- malloc (sizeof (PgStat_MsgTabstat )* TABSTAT_QUANTUM );
1002- if (newMessages == NULL )
1003- {
1004- ereport (LOG ,
1005- (errcode (ERRCODE_OUT_OF_MEMORY ),
1006- errmsg ("out of memory" )));
1007- return false;
1008- }
1002+ MemoryContextAllocZero (TopMemoryContext ,
1003+ sizeof (PgStat_MsgTabstat )* TABSTAT_QUANTUM );
10091004
10101005/* Create or enlarge the pointer array */
10111006if (pgStatTabstatMessages == NULL )
10121007msgArray = (PgStat_MsgTabstat * * )
1013- malloc (sizeof (PgStat_MsgTabstat * )* newAlloc );
1008+ MemoryContextAlloc (TopMemoryContext ,
1009+ sizeof (PgStat_MsgTabstat * )* newAlloc );
10141010else
10151011msgArray = (PgStat_MsgTabstat * * )
1016- realloc (pgStatTabstatMessages ,
1017- sizeof (PgStat_MsgTabstat * )* newAlloc );
1018- if (msgArray == NULL )
1019- {
1020- free (newMessages );
1021- ereport (LOG ,
1022- (errcode (ERRCODE_OUT_OF_MEMORY ),
1023- errmsg ("out of memory" )));
1024- return false;
1025- }
1012+ repalloc (pgStatTabstatMessages ,
1013+ sizeof (PgStat_MsgTabstat * )* newAlloc );
10261014
1027- MemSet (newMessages ,0 ,sizeof (PgStat_MsgTabstat )* TABSTAT_QUANTUM );
10281015for (i = 0 ;i < TABSTAT_QUANTUM ;i ++ )
10291016msgArray [pgStatTabstatAlloc + i ]= newMessages ++ ;
10301017pgStatTabstatMessages = msgArray ;
10311018pgStatTabstatAlloc = newAlloc ;
10321019
1033- return true ;
1020+ Assert ( pgStatTabstatUsed < pgStatTabstatAlloc ) ;
10341021}
10351022
10361023/* ----------
@@ -1102,14 +1089,7 @@ pgstat_initstats(PgStat_Info *stats, Relation rel)
11021089 * If we ran out of message buffers, we just allocate more.
11031090 */
11041091if (pgStatTabstatUsed >=pgStatTabstatAlloc )
1105- {
1106- if (!more_tabstat_space ())
1107- {
1108- stats -> no_stats = TRUE;
1109- return ;
1110- }
1111- Assert (pgStatTabstatUsed < pgStatTabstatAlloc );
1112- }
1092+ more_tabstat_space ();
11131093
11141094/*
11151095 * Use the first entry of the next message buffer.
@@ -1146,10 +1126,8 @@ pgstat_count_xact_commit(void)
11461126 * new xact-counters.
11471127 */
11481128if (pgStatTabstatAlloc == 0 )
1149- {
1150- if (!more_tabstat_space ())
1151- return ;
1152- }
1129+ more_tabstat_space ();
1130+
11531131if (pgStatTabstatUsed == 0 )
11541132{
11551133pgStatTabstatUsed ++ ;
@@ -1180,10 +1158,8 @@ pgstat_count_xact_rollback(void)
11801158 * new xact-counters.
11811159 */
11821160if (pgStatTabstatAlloc == 0 )
1183- {
1184- if (!more_tabstat_space ())
1185- return ;
1186- }
1161+ more_tabstat_space ();
1162+
11871163if (pgStatTabstatUsed == 0 )
11881164{
11891165pgStatTabstatUsed ++ ;
@@ -1529,13 +1505,8 @@ PgstatCollectorMain(int argc, char *argv[])
15291505/*
15301506 * Create the known backends table
15311507 */
1532- pgStatBeTable = (PgStat_StatBeEntry * )malloc (
1508+ pgStatBeTable = (PgStat_StatBeEntry * )palloc0 (
15331509sizeof (PgStat_StatBeEntry )* MaxBackends );
1534- if (pgStatBeTable == NULL )
1535- ereport (ERROR ,
1536- (errcode (ERRCODE_OUT_OF_MEMORY ),
1537- errmsg ("out of memory in statistics collector --- abort" )));
1538- memset (pgStatBeTable ,0 ,sizeof (PgStat_StatBeEntry )* MaxBackends );
15391510
15401511readPipe = pgStatPipe [0 ];
15411512
@@ -1804,11 +1775,7 @@ pgstat_recvbuffer(void)
18041775/*
18051776 * Allocate the message buffer
18061777 */
1807- msgbuffer = (char * )malloc (PGSTAT_RECVBUFFERSZ );
1808- if (msgbuffer == NULL )
1809- ereport (ERROR ,
1810- (errcode (ERRCODE_OUT_OF_MEMORY ),
1811- errmsg ("out of memory in statistics collector --- abort" )));
1778+ msgbuffer = (char * )palloc (PGSTAT_RECVBUFFERSZ );
18121779
18131780/*
18141781 * Loop forever
@@ -2416,7 +2383,7 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
24162383 * simply return zero for anything and the collector simply starts
24172384 * from scratch with empty counters.
24182385 */
2419- if ((fpin = fopen (pgStat_fname ,PG_BINARY_R ))== NULL )
2386+ if ((fpin = AllocateFile (pgStat_fname ,PG_BINARY_R ))== NULL )
24202387return ;
24212388
24222389/*
@@ -2437,8 +2404,7 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
24372404{
24382405ereport (pgStatRunningInCollector ?LOG :WARNING ,
24392406(errmsg ("corrupted pgstat.stat file" )));
2440- fclose (fpin );
2441- return ;
2407+ gotodone ;
24422408}
24432409
24442410/*
@@ -2450,7 +2416,6 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
24502416& found );
24512417if (dbentry == NULL )
24522418{
2453- fclose (fpin );
24542419ereport (ERROR ,
24552420(errcode (ERRCODE_OUT_OF_MEMORY ),
24562421errmsg ("out of memory" )));
@@ -2459,8 +2424,7 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
24592424{
24602425ereport (pgStatRunningInCollector ?LOG :WARNING ,
24612426(errmsg ("corrupted pgstat.stat file" )));
2462- fclose (fpin );
2463- return ;
2427+ gotodone ;
24642428}
24652429
24662430memcpy (dbentry ,& dbbuf ,sizeof (PgStat_StatDBEntry ));
@@ -2479,19 +2443,10 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
24792443hash_ctl .entrysize = sizeof (PgStat_StatTabEntry );
24802444hash_ctl .hash = tag_hash ;
24812445hash_ctl .hcxt = use_mcxt ;
2482- PG_TRY ();
2483- {
2484- dbentry -> tables = hash_create ("Per-database table" ,
2485- PGSTAT_TAB_HASH_SIZE ,
2486- & hash_ctl ,
2487- HASH_ELEM |HASH_FUNCTION |mcxt_flags );
2488- }
2489- PG_CATCH ();
2490- {
2491- fclose (fpin );
2492- PG_RE_THROW ();
2493- }
2494- PG_END_TRY ();
2446+ dbentry -> tables = hash_create ("Per-database table" ,
2447+ PGSTAT_TAB_HASH_SIZE ,
2448+ & hash_ctl ,
2449+ HASH_ELEM |HASH_FUNCTION |mcxt_flags );
24952450
24962451/*
24972452 * Arrange that following 'T's add entries to this
@@ -2515,8 +2470,7 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
25152470{
25162471ereport (pgStatRunningInCollector ?LOG :WARNING ,
25172472(errmsg ("corrupted pgstat.stat file" )));
2518- fclose (fpin );
2519- return ;
2473+ gotodone ;
25202474}
25212475
25222476/*
@@ -2529,19 +2483,15 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
25292483(void * )& tabbuf .tableid ,
25302484HASH_ENTER ,& found );
25312485if (tabentry == NULL )
2532- {
2533- fclose (fpin );
25342486ereport (ERROR ,
25352487(errcode (ERRCODE_OUT_OF_MEMORY ),
25362488errmsg ("out of memory" )));
2537- }
25382489
25392490if (found )
25402491{
25412492ereport (pgStatRunningInCollector ?LOG :WARNING ,
25422493(errmsg ("corrupted pgstat.stat file" )));
2543- fclose (fpin );
2544- return ;
2494+ gotodone ;
25452495}
25462496
25472497memcpy (tabentry ,& tabbuf ,sizeof (tabbuf ));
@@ -2552,30 +2502,23 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
25522502 */
25532503case 'M' :
25542504if (betab == NULL || numbackends == NULL )
2555- {
2556- fclose (fpin );
2557- return ;
2558- }
2505+ gotodone ;
25592506if (fread (& maxbackends ,1 ,sizeof (maxbackends ),fpin )!=
25602507sizeof (maxbackends ))
25612508{
25622509ereport (pgStatRunningInCollector ?LOG :WARNING ,
25632510(errmsg ("corrupted pgstat.stat file" )));
2564- fclose (fpin );
2565- return ;
2511+ gotodone ;
25662512}
25672513if (maxbackends == 0 )
2568- {
2569- fclose (fpin );
2570- return ;
2571- }
2514+ gotodone ;
25722515
25732516/*
25742517 * Allocate space (in TopTransactionContext too) for the
25752518 * backend table.
25762519 */
25772520if (use_mcxt == NULL )
2578- * betab = (PgStat_StatBeEntry * )malloc (
2521+ * betab = (PgStat_StatBeEntry * )palloc (
25792522sizeof (PgStat_StatBeEntry )* maxbackends );
25802523else
25812524* betab = (PgStat_StatBeEntry * )MemoryContextAlloc (
@@ -2587,16 +2530,8 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
25872530 * 'B'A PgStat_StatBeEntry follows.
25882531 */
25892532case 'B' :
2590- if (betab == NULL || numbackends == NULL )
2591- {
2592- fclose (fpin );
2593- return ;
2594- }
2595- if (* betab == NULL )
2596- {
2597- fclose (fpin );
2598- return ;
2599- }
2533+ if (betab == NULL || numbackends == NULL || * betab == NULL )
2534+ gotodone ;
26002535
26012536/*
26022537 * Read it directly into the table.
@@ -2607,8 +2542,7 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
26072542{
26082543ereport (pgStatRunningInCollector ?LOG :WARNING ,
26092544(errmsg ("corrupted pgstat.stat file" )));
2610- fclose (fpin );
2611- return ;
2545+ gotodone ;
26122546}
26132547
26142548/*
@@ -2624,28 +2558,25 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
26242558if (numbackends != 0 )
26252559* numbackends = havebackends ;
26262560if (havebackends >=maxbackends )
2627- {
2628- fclose (fpin );
2629- return ;
2630- }
2561+ gotodone ;
2562+
26312563break ;
26322564
26332565/*
26342566 * 'E'The EOF marker of a complete stats file.
26352567 */
26362568case 'E' :
2637- fclose (fpin );
2638- return ;
2569+ gotodone ;
26392570
26402571default :
26412572ereport (pgStatRunningInCollector ?LOG :WARNING ,
26422573(errmsg ("corrupted pgstat.stat file" )));
2643- fclose (fpin );
2644- return ;
2574+ gotodone ;
26452575}
26462576}
26472577
2648- fclose (fpin );
2578+ done :
2579+ FreeFile (fpin );
26492580}
26502581
26512582/*