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 ||
160161 pgstat_collect_blocklevel )
161162 pgstat_collect_startcollector = true;
162163
@@ -536,34 +537,38 @@ void
536537pgstat_report_tabstat (void )
537538{
538539 int 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 ;
547548 return ;
549+ }
548550
549551 /*
550552 * For each message buffer used during the last query set the header
551553 * fields and send it out.
552554 */
553555 for (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 ;
556562 len = offsetof(PgStat_MsgTabstat , m_entry [0 ]) +
557563 n * 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 ;
561567 pgStatXactCommit = 0 ;
562568 pgStatXactRollback = 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
569574 pgStatTabstatUsed = 0 ;
@@ -802,6 +807,53 @@ pgstat_ping(void)
802807 pgstat_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 ;
819870 Oid rel_id = rel -> rd_id ;
871+ PgStat_TableEntry * useent ;
872+ PgStat_MsgTabstat * tsmsg ;
820873 int mb ;
821874 int i ;
822875
@@ -828,69 +881,39 @@ pgstat_initstats(PgStat_Info *stats, Relation rel)
828881 stats -> heap_scan_counted = FALSE;
829882 stats -> index_scan_counted = FALSE;
830883
831- if (pgStatSock < 0 )
884+ if (pgStatSock < 0 ||
885+ !(pgstat_collect_tuplelevel ||
886+ pgstat_collect_blocklevel ))
832887 {
833888 stats -> no_stats = TRUE;
834889 return ;
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 */
874895 for (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 ]);
881904 return ;
882905 }
883906 }
884907
885- if (pgStatTabstatMessages [ mb ] -> m_nentries >= PGSTAT_NUM_TABENTRIES )
908+ if (tsmsg -> m_nentries >= PGSTAT_NUM_TABENTRIES )
886909 continue ;
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 ];
894917 MemSet (useent , 0 , sizeof (PgStat_TableEntry ));
895918 useent -> t_id = rel_id ;
896919 stats -> tabentry = (void * ) useent ;
@@ -902,43 +925,21 @@ pgstat_initstats(PgStat_Info *stats, Relation rel)
902925 */
903926 if (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;
927931 return ;
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 */
939939 mb = 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 ];
942943 MemSet (useent , 0 , sizeof (PgStat_TableEntry ));
943944 useent -> t_id = rel_id ;
944945 stats -> 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 ))
959961 return ;
960962
961963 pgStatXactCommit ++ ;
@@ -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 ))
990995 return ;
991996
992997 pgStatXactRollback ++ ;
@@ -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
0 commit comments