Avoid unnecessary work when stats collection is disabled. Tighten

search loop in pgstat_initstats.  Per report from Gavin Sherry.
This commit is contained in:
Tom Lane 2003-08-12 16:21:18 +00:00
parent e3d97d7da2
commit 1c6702f6fc
1 changed files with 108 additions and 101 deletions

View File

@ -13,7 +13,7 @@
*
* Copyright (c) 2001-2003, PostgreSQL Global Development Group
*
* $Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.42 2003/08/04 00:43:21 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.43 2003/08/12 16:21:18 tgl Exp $
* ----------
*/
#include "postgres.h"
@ -156,7 +156,8 @@ pgstat_init(void)
/*
* Force start of collector daemon if something to collect
*/
if (pgstat_collect_querystring || pgstat_collect_tuplelevel ||
if (pgstat_collect_querystring ||
pgstat_collect_tuplelevel ||
pgstat_collect_blocklevel)
pgstat_collect_startcollector = true;
@ -536,15 +537,16 @@ void
pgstat_report_tabstat(void)
{
int i;
int n;
int len;
if (!pgstat_collect_querystring && !pgstat_collect_tuplelevel &&
!pgstat_collect_blocklevel)
return;
if (pgStatSock < 0)
if (pgStatSock < 0 ||
!(pgstat_collect_querystring ||
pgstat_collect_tuplelevel ||
pgstat_collect_blocklevel))
{
/* Not reporting stats, so just flush whatever we have */
pgStatTabstatUsed = 0;
return;
}
/*
* For each message buffer used during the last query set the header
@ -552,18 +554,21 @@ pgstat_report_tabstat(void)
*/
for (i = 0; i < pgStatTabstatUsed; i++)
{
n = pgStatTabstatMessages[i]->m_nentries;
PgStat_MsgTabstat *tsmsg = pgStatTabstatMessages[i];
int n;
int len;
n = tsmsg->m_nentries;
len = offsetof(PgStat_MsgTabstat, m_entry[0]) +
n * sizeof(PgStat_TableEntry);
pgStatTabstatMessages[i]->m_xact_commit = pgStatXactCommit;
pgStatTabstatMessages[i]->m_xact_rollback = pgStatXactRollback;
tsmsg->m_xact_commit = pgStatXactCommit;
tsmsg->m_xact_rollback = pgStatXactRollback;
pgStatXactCommit = 0;
pgStatXactRollback = 0;
pgstat_setheader(&pgStatTabstatMessages[i]->m_hdr,
PGSTAT_MTYPE_TABSTAT);
pgstat_send(pgStatTabstatMessages[i], len);
pgstat_setheader(&tsmsg->m_hdr, PGSTAT_MTYPE_TABSTAT);
pgstat_send(tsmsg, len);
}
pgStatTabstatUsed = 0;
@ -802,6 +807,53 @@ pgstat_ping(void)
pgstat_send(&msg, sizeof(msg));
}
/*
* Create or enlarge the pgStatTabstatMessages array
*/
static bool
more_tabstat_space(void)
{
PgStat_MsgTabstat *newMessages;
PgStat_MsgTabstat **msgArray;
int newAlloc = pgStatTabstatAlloc + TABSTAT_QUANTUM;
int i;
/* Create (another) quantum of message buffers */
newMessages = (PgStat_MsgTabstat *)
malloc(sizeof(PgStat_MsgTabstat) * TABSTAT_QUANTUM);
if (newMessages == NULL)
{
ereport(LOG,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory")));
return false;
}
/* Create or enlarge the pointer array */
if (pgStatTabstatMessages == NULL)
msgArray = (PgStat_MsgTabstat **)
malloc(sizeof(PgStat_MsgTabstat *) * newAlloc);
else
msgArray = (PgStat_MsgTabstat **)
realloc(pgStatTabstatMessages,
sizeof(PgStat_MsgTabstat *) * newAlloc);
if (msgArray == NULL)
{
free(newMessages);
ereport(LOG,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory")));
return false;
}
MemSet(newMessages, 0, sizeof(PgStat_MsgTabstat) * TABSTAT_QUANTUM);
for (i = 0; i < TABSTAT_QUANTUM; i++)
msgArray[pgStatTabstatAlloc + i] = newMessages++;
pgStatTabstatMessages = msgArray;
pgStatTabstatAlloc = newAlloc;
return true;
}
/* ----------
* pgstat_initstats() -
@ -815,8 +867,9 @@ pgstat_ping(void)
void
pgstat_initstats(PgStat_Info *stats, Relation rel)
{
PgStat_TableEntry *useent;
Oid rel_id = rel->rd_id;
PgStat_TableEntry *useent;
PgStat_MsgTabstat *tsmsg;
int mb;
int i;
@ -828,69 +881,39 @@ pgstat_initstats(PgStat_Info *stats, Relation rel)
stats->heap_scan_counted = FALSE;
stats->index_scan_counted = FALSE;
if (pgStatSock < 0)
if (pgStatSock < 0 ||
!(pgstat_collect_tuplelevel ||
pgstat_collect_blocklevel))
{
stats->no_stats = TRUE;
return;
}
/*
* On the first of all calls create some message buffers.
*/
if (pgStatTabstatMessages == NULL)
{
PgStat_MsgTabstat *newMessages;
PgStat_MsgTabstat **msgArray;
newMessages = (PgStat_MsgTabstat *)
malloc(sizeof(PgStat_MsgTabstat) * TABSTAT_QUANTUM);
if (newMessages == NULL)
{
ereport(LOG,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory")));
return;
}
msgArray = (PgStat_MsgTabstat **)
malloc(sizeof(PgStat_MsgTabstat *) * TABSTAT_QUANTUM);
if (msgArray == NULL)
{
free(newMessages);
ereport(LOG,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory")));
return;
}
MemSet(newMessages, 0, sizeof(PgStat_MsgTabstat) * TABSTAT_QUANTUM);
for (i = 0; i < TABSTAT_QUANTUM; i++)
msgArray[i] = newMessages++;
pgStatTabstatMessages = msgArray;
pgStatTabstatAlloc = TABSTAT_QUANTUM;
}
/*
* Search the already-used message slots for this relation.
*/
for (mb = 0; mb < pgStatTabstatUsed; mb++)
{
for (i = 0; i < pgStatTabstatMessages[mb]->m_nentries; i++)
tsmsg = pgStatTabstatMessages[mb];
for (i = tsmsg->m_nentries; --i >= 0; )
{
if (pgStatTabstatMessages[mb]->m_entry[i].t_id == rel_id)
if (tsmsg->m_entry[i].t_id == rel_id)
{
stats->tabentry = (void *) &(pgStatTabstatMessages[mb]->m_entry[i]);
stats->tabentry = (void *) &(tsmsg->m_entry[i]);
return;
}
}
if (pgStatTabstatMessages[mb]->m_nentries >= PGSTAT_NUM_TABENTRIES)
if (tsmsg->m_nentries >= PGSTAT_NUM_TABENTRIES)
continue;
/*
* Not found, but found a message buffer with an empty slot
* instead. Fine, let's use this one.
*/
i = pgStatTabstatMessages[mb]->m_nentries++;
useent = &pgStatTabstatMessages[mb]->m_entry[i];
i = tsmsg->m_nentries++;
useent = &tsmsg->m_entry[i];
MemSet(useent, 0, sizeof(PgStat_TableEntry));
useent->t_id = rel_id;
stats->tabentry = (void *) useent;
@ -902,43 +925,21 @@ pgstat_initstats(PgStat_Info *stats, Relation rel)
*/
if (pgStatTabstatUsed >= pgStatTabstatAlloc)
{
int newAlloc = pgStatTabstatAlloc + TABSTAT_QUANTUM;
PgStat_MsgTabstat *newMessages;
PgStat_MsgTabstat **msgArray;
newMessages = (PgStat_MsgTabstat *)
malloc(sizeof(PgStat_MsgTabstat) * TABSTAT_QUANTUM);
if (newMessages == NULL)
if (!more_tabstat_space())
{
ereport(LOG,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory")));
stats->no_stats = TRUE;
return;
}
msgArray = (PgStat_MsgTabstat **)
realloc(pgStatTabstatMessages,
sizeof(PgStat_MsgTabstat *) * newAlloc);
if (msgArray == NULL)
{
free(newMessages);
ereport(LOG,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of memory")));
return;
}
MemSet(newMessages, 0, sizeof(PgStat_MsgTabstat) * TABSTAT_QUANTUM);
for (i = 0; i < TABSTAT_QUANTUM; i++)
msgArray[pgStatTabstatAlloc + i] = newMessages++;
pgStatTabstatMessages = msgArray;
pgStatTabstatAlloc = newAlloc;
Assert(pgStatTabstatUsed < pgStatTabstatAlloc);
}
/*
* Use the first entry of the next message buffer.
*/
mb = pgStatTabstatUsed++;
pgStatTabstatMessages[mb]->m_nentries = 1;
useent = &pgStatTabstatMessages[mb]->m_entry[0];
tsmsg = pgStatTabstatMessages[mb];
tsmsg->m_nentries = 1;
useent = &tsmsg->m_entry[0];
MemSet(useent, 0, sizeof(PgStat_TableEntry));
useent->t_id = rel_id;
stats->tabentry = (void *) useent;
@ -954,8 +955,9 @@ pgstat_initstats(PgStat_Info *stats, Relation rel)
void
pgstat_count_xact_commit(void)
{
if (!pgstat_collect_querystring && !pgstat_collect_tuplelevel &&
!pgstat_collect_blocklevel)
if (!(pgstat_collect_querystring ||
pgstat_collect_tuplelevel ||
pgstat_collect_blocklevel))
return;
pgStatXactCommit++;
@ -965,13 +967,15 @@ pgstat_count_xact_commit(void)
* message buffer used without slots, causing the next report to tell
* new xact-counters.
*/
if (pgStatTabstatAlloc > 0)
if (pgStatTabstatAlloc == 0)
{
if (pgStatTabstatUsed == 0)
{
pgStatTabstatUsed++;
pgStatTabstatMessages[0]->m_nentries = 0;
}
if (!more_tabstat_space())
return;
}
if (pgStatTabstatUsed == 0)
{
pgStatTabstatUsed++;
pgStatTabstatMessages[0]->m_nentries = 0;
}
}
@ -985,8 +989,9 @@ pgstat_count_xact_commit(void)
void
pgstat_count_xact_rollback(void)
{
if (!pgstat_collect_querystring && !pgstat_collect_tuplelevel &&
!pgstat_collect_blocklevel)
if (!(pgstat_collect_querystring ||
pgstat_collect_tuplelevel ||
pgstat_collect_blocklevel))
return;
pgStatXactRollback++;
@ -996,13 +1001,15 @@ pgstat_count_xact_rollback(void)
* message buffer used without slots, causing the next report to tell
* new xact-counters.
*/
if (pgStatTabstatAlloc > 0)
if (pgStatTabstatAlloc == 0)
{
if (pgStatTabstatUsed == 0)
{
pgStatTabstatUsed++;
pgStatTabstatMessages[0]->m_nentries = 0;
}
if (!more_tabstat_space())
return;
}
if (pgStatTabstatUsed == 0)
{
pgStatTabstatUsed++;
pgStatTabstatMessages[0]->m_nentries = 0;
}
}