1313 *
1414 *Copyright (c) 2001-2003, PostgreSQL Global Development Group
1515 *
16- *$Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.42 2003/08/04 00:43:21 momjian Exp $
16+ *$Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.43 2003/08/12 16:21:18 tgl Exp $
1717 * ----------
1818 */
1919#include "postgres.h"
@@ -156,7 +156,8 @@ pgstat_init(void)
156156/*
157157 * Force start of collector daemon if something to collect
158158 */
159- if (pgstat_collect_querystring || pgstat_collect_tuplelevel ||
159+ if (pgstat_collect_querystring ||
160+ pgstat_collect_tuplelevel ||
160161pgstat_collect_blocklevel )
161162pgstat_collect_startcollector = true;
162163
@@ -536,34 +537,38 @@ void
536537pgstat_report_tabstat (void )
537538{
538539int i ;
539- int n ;
540- int len ;
541-
542- if (!pgstat_collect_querystring && !pgstat_collect_tuplelevel &&
543- !pgstat_collect_blocklevel )
544- return ;
545540
546- if (pgStatSock < 0 )
541+ if (pgStatSock < 0 ||
542+ !(pgstat_collect_querystring ||
543+ pgstat_collect_tuplelevel ||
544+ pgstat_collect_blocklevel ))
545+ {
546+ /* Not reporting stats, so just flush whatever we have */
547+ pgStatTabstatUsed = 0 ;
547548return ;
549+ }
548550
549551/*
550552 * For each message buffer used during the last query set the header
551553 * fields and send it out.
552554 */
553555for (i = 0 ;i < pgStatTabstatUsed ;i ++ )
554556{
555- n = pgStatTabstatMessages [i ]-> m_nentries ;
557+ PgStat_MsgTabstat * tsmsg = pgStatTabstatMessages [i ];
558+ int n ;
559+ int len ;
560+
561+ n = tsmsg -> m_nentries ;
556562len = offsetof(PgStat_MsgTabstat ,m_entry [0 ])+
557563n * sizeof (PgStat_TableEntry );
558564
559- pgStatTabstatMessages [ i ] -> m_xact_commit = pgStatXactCommit ;
560- pgStatTabstatMessages [ i ] -> m_xact_rollback = pgStatXactRollback ;
565+ tsmsg -> m_xact_commit = pgStatXactCommit ;
566+ tsmsg -> m_xact_rollback = pgStatXactRollback ;
561567pgStatXactCommit = 0 ;
562568pgStatXactRollback = 0 ;
563569
564- pgstat_setheader (& pgStatTabstatMessages [i ]-> m_hdr ,
565- PGSTAT_MTYPE_TABSTAT );
566- pgstat_send (pgStatTabstatMessages [i ],len );
570+ pgstat_setheader (& tsmsg -> m_hdr ,PGSTAT_MTYPE_TABSTAT );
571+ pgstat_send (tsmsg ,len );
567572}
568573
569574pgStatTabstatUsed = 0 ;
@@ -802,6 +807,53 @@ pgstat_ping(void)
802807pgstat_send (& msg ,sizeof (msg ));
803808}
804809
810+ /*
811+ * Create or enlarge the pgStatTabstatMessages array
812+ */
813+ static bool
814+ more_tabstat_space (void )
815+ {
816+ PgStat_MsgTabstat * newMessages ;
817+ PgStat_MsgTabstat * * msgArray ;
818+ int newAlloc = pgStatTabstatAlloc + TABSTAT_QUANTUM ;
819+ int i ;
820+
821+ /* Create (another) quantum of message buffers */
822+ newMessages = (PgStat_MsgTabstat * )
823+ malloc (sizeof (PgStat_MsgTabstat )* TABSTAT_QUANTUM );
824+ if (newMessages == NULL )
825+ {
826+ ereport (LOG ,
827+ (errcode (ERRCODE_OUT_OF_MEMORY ),
828+ errmsg ("out of memory" )));
829+ return false;
830+ }
831+
832+ /* Create or enlarge the pointer array */
833+ if (pgStatTabstatMessages == NULL )
834+ msgArray = (PgStat_MsgTabstat * * )
835+ malloc (sizeof (PgStat_MsgTabstat * )* newAlloc );
836+ else
837+ msgArray = (PgStat_MsgTabstat * * )
838+ realloc (pgStatTabstatMessages ,
839+ sizeof (PgStat_MsgTabstat * )* newAlloc );
840+ if (msgArray == NULL )
841+ {
842+ free (newMessages );
843+ ereport (LOG ,
844+ (errcode (ERRCODE_OUT_OF_MEMORY ),
845+ errmsg ("out of memory" )));
846+ return false;
847+ }
848+
849+ MemSet (newMessages ,0 ,sizeof (PgStat_MsgTabstat )* TABSTAT_QUANTUM );
850+ for (i = 0 ;i < TABSTAT_QUANTUM ;i ++ )
851+ msgArray [pgStatTabstatAlloc + i ]= newMessages ++ ;
852+ pgStatTabstatMessages = msgArray ;
853+ pgStatTabstatAlloc = newAlloc ;
854+
855+ return true;
856+ }
805857
806858/* ----------
807859 * pgstat_initstats() -
@@ -815,8 +867,9 @@ pgstat_ping(void)
815867void
816868pgstat_initstats (PgStat_Info * stats ,Relation rel )
817869{
818- PgStat_TableEntry * useent ;
819870Oid rel_id = rel -> rd_id ;
871+ PgStat_TableEntry * useent ;
872+ PgStat_MsgTabstat * tsmsg ;
820873int mb ;
821874int i ;
822875
@@ -828,69 +881,39 @@ pgstat_initstats(PgStat_Info *stats, Relation rel)
828881stats -> heap_scan_counted = FALSE;
829882stats -> index_scan_counted = FALSE;
830883
831- if (pgStatSock < 0 )
884+ if (pgStatSock < 0 ||
885+ !(pgstat_collect_tuplelevel ||
886+ pgstat_collect_blocklevel ))
832887{
833888stats -> no_stats = TRUE;
834889return ;
835890}
836891
837- /*
838- * On the first of all calls create some message buffers.
839- */
840- if (pgStatTabstatMessages == NULL )
841- {
842- PgStat_MsgTabstat * newMessages ;
843- PgStat_MsgTabstat * * msgArray ;
844-
845- newMessages = (PgStat_MsgTabstat * )
846- malloc (sizeof (PgStat_MsgTabstat )* TABSTAT_QUANTUM );
847- if (newMessages == NULL )
848- {
849- ereport (LOG ,
850- (errcode (ERRCODE_OUT_OF_MEMORY ),
851- errmsg ("out of memory" )));
852- return ;
853- }
854- msgArray = (PgStat_MsgTabstat * * )
855- malloc (sizeof (PgStat_MsgTabstat * )* TABSTAT_QUANTUM );
856- if (msgArray == NULL )
857- {
858- free (newMessages );
859- ereport (LOG ,
860- (errcode (ERRCODE_OUT_OF_MEMORY ),
861- errmsg ("out of memory" )));
862- return ;
863- }
864- MemSet (newMessages ,0 ,sizeof (PgStat_MsgTabstat )* TABSTAT_QUANTUM );
865- for (i = 0 ;i < TABSTAT_QUANTUM ;i ++ )
866- msgArray [i ]= newMessages ++ ;
867- pgStatTabstatMessages = msgArray ;
868- pgStatTabstatAlloc = TABSTAT_QUANTUM ;
869- }
870-
871892/*
872893 * Search the already-used message slots for this relation.
873894 */
874895for (mb = 0 ;mb < pgStatTabstatUsed ;mb ++ )
875896{
876- for (i = 0 ;i < pgStatTabstatMessages [mb ]-> m_nentries ;i ++ )
897+ tsmsg = pgStatTabstatMessages [mb ];
898+
899+ for (i = tsmsg -> m_nentries ;-- i >=0 ; )
877900{
878- if (pgStatTabstatMessages [ mb ] -> m_entry [i ].t_id == rel_id )
901+ if (tsmsg -> m_entry [i ].t_id == rel_id )
879902{
880- stats -> tabentry = (void * )& (pgStatTabstatMessages [ mb ] -> m_entry [i ]);
903+ stats -> tabentry = (void * )& (tsmsg -> m_entry [i ]);
881904return ;
882905}
883906}
884907
885- if (pgStatTabstatMessages [ mb ] -> m_nentries >=PGSTAT_NUM_TABENTRIES )
908+ if (tsmsg -> m_nentries >=PGSTAT_NUM_TABENTRIES )
886909continue ;
887910
888911/*
889912 * Not found, but found a message buffer with an empty slot
890913 * instead. Fine, let's use this one.
891914 */
892- i = pgStatTabstatMessages [ mb ] -> m_nentries ++ ;
893- useent = & pgStatTabstatMessages [ mb ] -> m_entry [i ];
915+ i = tsmsg -> m_nentries ++ ;
916+ useent = & tsmsg -> m_entry [i ];
894917MemSet (useent ,0 ,sizeof (PgStat_TableEntry ));
895918useent -> t_id = rel_id ;
896919stats -> tabentry = (void * )useent ;
@@ -902,43 +925,21 @@ pgstat_initstats(PgStat_Info *stats, Relation rel)
902925 */
903926if (pgStatTabstatUsed >=pgStatTabstatAlloc )
904927{
905- int newAlloc = pgStatTabstatAlloc + TABSTAT_QUANTUM ;
906- PgStat_MsgTabstat * newMessages ;
907- PgStat_MsgTabstat * * msgArray ;
908-
909- newMessages = (PgStat_MsgTabstat * )
910- malloc (sizeof (PgStat_MsgTabstat )* TABSTAT_QUANTUM );
911- if (newMessages == NULL )
912- {
913- ereport (LOG ,
914- (errcode (ERRCODE_OUT_OF_MEMORY ),
915- errmsg ("out of memory" )));
916- return ;
917- }
918- msgArray = (PgStat_MsgTabstat * * )
919- realloc (pgStatTabstatMessages ,
920- sizeof (PgStat_MsgTabstat * )* newAlloc );
921- if (msgArray == NULL )
928+ if (!more_tabstat_space ())
922929{
923- free (newMessages );
924- ereport (LOG ,
925- (errcode (ERRCODE_OUT_OF_MEMORY ),
926- errmsg ("out of memory" )));
930+ stats -> no_stats = TRUE;
927931return ;
928932}
929- MemSet (newMessages ,0 ,sizeof (PgStat_MsgTabstat )* TABSTAT_QUANTUM );
930- for (i = 0 ;i < TABSTAT_QUANTUM ;i ++ )
931- msgArray [pgStatTabstatAlloc + i ]= newMessages ++ ;
932- pgStatTabstatMessages = msgArray ;
933- pgStatTabstatAlloc = newAlloc ;
933+ Assert (pgStatTabstatUsed < pgStatTabstatAlloc );
934934}
935935
936936/*
937937 * Use the first entry of the next message buffer.
938938 */
939939mb = pgStatTabstatUsed ++ ;
940- pgStatTabstatMessages [mb ]-> m_nentries = 1 ;
941- useent = & pgStatTabstatMessages [mb ]-> m_entry [0 ];
940+ tsmsg = pgStatTabstatMessages [mb ];
941+ tsmsg -> m_nentries = 1 ;
942+ useent = & tsmsg -> m_entry [0 ];
942943MemSet (useent ,0 ,sizeof (PgStat_TableEntry ));
943944useent -> t_id = rel_id ;
944945stats -> tabentry = (void * )useent ;
@@ -954,8 +955,9 @@ pgstat_initstats(PgStat_Info *stats, Relation rel)
954955void
955956pgstat_count_xact_commit (void )
956957{
957- if (!pgstat_collect_querystring && !pgstat_collect_tuplelevel &&
958- !pgstat_collect_blocklevel )
958+ if (!(pgstat_collect_querystring ||
959+ pgstat_collect_tuplelevel ||
960+ pgstat_collect_blocklevel ))
959961return ;
960962
961963pgStatXactCommit ++ ;
@@ -965,13 +967,15 @@ pgstat_count_xact_commit(void)
965967 * message buffer used without slots, causing the next report to tell
966968 * new xact-counters.
967969 */
968- if (pgStatTabstatAlloc > 0 )
970+ if (pgStatTabstatAlloc == 0 )
969971{
970- if (pgStatTabstatUsed == 0 )
971- {
972- pgStatTabstatUsed ++ ;
973- pgStatTabstatMessages [0 ]-> m_nentries = 0 ;
974- }
972+ if (!more_tabstat_space ())
973+ return ;
974+ }
975+ if (pgStatTabstatUsed == 0 )
976+ {
977+ pgStatTabstatUsed ++ ;
978+ pgStatTabstatMessages [0 ]-> m_nentries = 0 ;
975979}
976980}
977981
@@ -985,8 +989,9 @@ pgstat_count_xact_commit(void)
985989void
986990pgstat_count_xact_rollback (void )
987991{
988- if (!pgstat_collect_querystring && !pgstat_collect_tuplelevel &&
989- !pgstat_collect_blocklevel )
992+ if (!(pgstat_collect_querystring ||
993+ pgstat_collect_tuplelevel ||
994+ pgstat_collect_blocklevel ))
990995return ;
991996
992997pgStatXactRollback ++ ;
@@ -996,13 +1001,15 @@ pgstat_count_xact_rollback(void)
9961001 * message buffer used without slots, causing the next report to tell
9971002 * new xact-counters.
9981003 */
999- if (pgStatTabstatAlloc > 0 )
1004+ if (pgStatTabstatAlloc == 0 )
10001005{
1001- if (pgStatTabstatUsed == 0 )
1002- {
1003- pgStatTabstatUsed ++ ;
1004- pgStatTabstatMessages [0 ]-> m_nentries = 0 ;
1005- }
1006+ if (!more_tabstat_space ())
1007+ return ;
1008+ }
1009+ if (pgStatTabstatUsed == 0 )
1010+ {
1011+ pgStatTabstatUsed ++ ;
1012+ pgStatTabstatMessages [0 ]-> m_nentries = 0 ;
10061013}
10071014}
10081015