Skip to content

Commit 1c6702f

Browse files
committed
Avoid unnecessary work when stats collection is disabled. Tighten
search loop in pgstat_initstats. Per report from Gavin Sherry.
1 parent e3d97d7 commit 1c6702f

File tree

1 file changed

+108
-101
lines changed

1 file changed

+108
-101
lines changed

src/backend/postmaster/pgstat.c

Lines changed: 108 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
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
536537
pgstat_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)
815867
void
816868
pgstat_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)
954955
void
955956
pgstat_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)
985989
void
986990
pgstat_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

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy