Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 48f8ead

Browse files
author
Neil Conway
committed
This patch reduces the size of the message header used by statistics
collector messages, per recent discussion on pgsql-patches. This actually required quite a few changes -- for example, "databaseid != InvalidOid" was used to check whether a slot in the backend entry table was initialized, but that no longer works since the slot might be initialized prior to receiving the BESTART message which contains the database id. We now use procpid > 0 to indicate that a slot is non-empty. Other changes: - various comment improvements and cleanups - there's no need to zero-out the entire activity buffer in pgstat_add_backend(), we can just set activity[0] to '\0'. - remove the counting of the # of connections to a database; this was not used anywhere One change in behavior I wasn't sure about: previously, the code would create a hash table entry for a database as soon as any message was received whose header referenced that database. Now, we only create hash table entries as needed (so for example BESTART won't create a database hash table entry, since it doesn't need to access anything in the per-db hash table). It would be easy enough to retain the old behavior, but AFAICS it is not required.
1 parent f38e413 commit 48f8ead

File tree

3 files changed

+129
-107
lines changed

3 files changed

+129
-107
lines changed

src/backend/postmaster/pgstat.c

Lines changed: 92 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
*
1414
* Copyright (c) 2001-2005, PostgreSQL Global Development Group
1515
*
16-
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.93 2005/05/09 11:31:33 neilc Exp $
16+
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.94 2005/05/11 01:41:40 neilc Exp $
1717
* ----------
1818
*/
1919
#include "postgres.h"
@@ -162,6 +162,7 @@ static void pgstat_exit(SIGNAL_ARGS);
162162
static void pgstat_die(SIGNAL_ARGS);
163163
static void pgstat_beshutdown_hook(int code, Datum arg);
164164

165+
static PgStat_StatDBEntry *pgstat_get_db_entry(int databaseid);
165166
static int pgstat_add_backend(PgStat_MsgHdr *msg);
166167
static void pgstat_sub_backend(int procpid);
167168
static void pgstat_drop_database(Oid databaseid);
@@ -653,6 +654,9 @@ pgstat_bestart(void)
653654
return;
654655

655656
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_BESTART);
657+
msg.m_databaseid = MyDatabaseId;
658+
msg.m_userid = GetSessionUserId();
659+
memcpy(&msg.m_clientaddr, &MyProcPort->raddr, sizeof(msg.m_clientaddr));
656660
pgstat_send(&msg, sizeof(msg));
657661

658662
/*
@@ -748,6 +752,7 @@ pgstat_report_tabstat(void)
748752
pgStatXactRollback = 0;
749753

750754
pgstat_setheader(&tsmsg->m_hdr, PGSTAT_MTYPE_TABSTAT);
755+
tsmsg->m_databaseid = MyDatabaseId;
751756
pgstat_send(tsmsg, len);
752757
}
753758

@@ -825,7 +830,7 @@ pgstat_vacuum_tabstat(void)
825830
}
826831

827832
/*
828-
* Add this tables Oid to the message
833+
* Add this table's Oid to the message
829834
*/
830835
msg.m_tableid[msg.m_nentries++] = tabentry->tableid;
831836
nobjects++;
@@ -854,6 +859,7 @@ pgstat_vacuum_tabstat(void)
854859
+msg.m_nentries * sizeof(Oid);
855860

856861
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_TABPURGE);
862+
msg.m_databaseid = MyDatabaseId;
857863
pgstat_send(&msg, len);
858864
}
859865

@@ -933,9 +939,8 @@ pgstat_drop_database(Oid databaseid)
933939
if (pgStatSock < 0)
934940
return;
935941

936-
msg.m_databaseid = databaseid;
937-
938942
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_DROPDB);
943+
msg.m_databaseid = databaseid;
939944
pgstat_send(&msg, sizeof(msg));
940945
}
941946

@@ -960,6 +965,7 @@ pgstat_reset_counters(void)
960965
errmsg("must be superuser to reset statistics counters")));
961966

962967
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETCOUNTER);
968+
msg.m_databaseid = MyDatabaseId;
963969
pgstat_send(&msg, sizeof(msg));
964970
}
965971

@@ -1176,24 +1182,18 @@ pgstat_count_xact_rollback(void)
11761182
PgStat_StatDBEntry *
11771183
pgstat_fetch_stat_dbentry(Oid dbid)
11781184
{
1179-
PgStat_StatDBEntry *dbentry;
1180-
11811185
/*
11821186
* If not done for this transaction, read the statistics collector
11831187
* stats file into some hash tables.
11841188
*/
11851189
backend_read_statsfile();
11861190

11871191
/*
1188-
* Lookup the requested database
1192+
* Lookup the requested database; return NULL if not found
11891193
*/
1190-
dbentry = (PgStat_StatDBEntry *) hash_search(pgStatDBHash,
1191-
(void *) &dbid,
1192-
HASH_FIND, NULL);
1193-
if (dbentry == NULL)
1194-
return NULL;
1195-
1196-
return dbentry;
1194+
return (PgStat_StatDBEntry *) hash_search(pgStatDBHash,
1195+
(void *) &dbid,
1196+
HASH_FIND, NULL);
11971197
}
11981198

11991199

@@ -1298,9 +1298,6 @@ pgstat_setheader(PgStat_MsgHdr *hdr, int mtype)
12981298
hdr->m_type = mtype;
12991299
hdr->m_backendid = MyBackendId;
13001300
hdr->m_procpid = MyProcPid;
1301-
hdr->m_databaseid = MyDatabaseId;
1302-
hdr->m_userid = GetSessionUserId();
1303-
memcpy(&hdr->m_clientaddr, &MyProcPort->raddr, sizeof(hdr->m_clientaddr));
13041301
}
13051302

13061303

@@ -1976,10 +1973,8 @@ pgstat_die(SIGNAL_ARGS)
19761973
static int
19771974
pgstat_add_backend(PgStat_MsgHdr *msg)
19781975
{
1979-
PgStat_StatDBEntry *dbentry;
19801976
PgStat_StatBeEntry *beentry;
19811977
PgStat_StatBeDead *deadbe;
1982-
bool found;
19831978

19841979
/*
19851980
* Check that the backend ID is valid
@@ -1995,19 +1990,19 @@ pgstat_add_backend(PgStat_MsgHdr *msg)
19951990
* Get the slot for this backendid.
19961991
*/
19971992
beentry = &pgStatBeTable[msg->m_backendid - 1];
1998-
if (beentry->databaseid != InvalidOid)
1999-
{
2000-
/*
2001-
* If the slot contains the PID of this backend, everything is
2002-
* fine and we got nothing to do.
2003-
*/
2004-
if (beentry->procpid == msg->m_procpid)
2005-
return 0;
2006-
}
1993+
1994+
/*
1995+
* If the slot contains the PID of this backend, everything is
1996+
* fine and we have nothing to do. Note that all the slots are
1997+
* zero'd out when the collector is started. We assume that a slot
1998+
* is "empty" iff procpid == 0.
1999+
*/
2000+
if (beentry->procpid > 0 && beentry->procpid == msg->m_procpid)
2001+
return 0;
20072002

20082003
/*
20092004
* Lookup if this backend is known to be dead. This can be caused due
2010-
* to messages arriving in the wrong order - i.e. Postmaster's BETERM
2005+
* to messages arriving in the wrong order - e.g. postmaster's BETERM
20112006
* message might have arrived before we received all the backends
20122007
* stats messages, or even a new backend with the same backendid was
20132008
* faster in sending his BESTART.
@@ -2024,65 +2019,78 @@ pgstat_add_backend(PgStat_MsgHdr *msg)
20242019
* Backend isn't known to be dead. If it's slot is currently used, we
20252020
* have to kick out the old backend.
20262021
*/
2027-
if (beentry->databaseid != InvalidOid)
2022+
if (beentry->procpid > 0)
20282023
pgstat_sub_backend(beentry->procpid);
20292024

2030-
/*
2031-
* Put this new backend into the slot.
2032-
*/
2033-
beentry->databaseid = msg->m_databaseid;
2025+
/* Must be able to distinguish between empty and non-empty slots */
2026+
Assert(msg->m_procpid > 0);
2027+
2028+
/* Put this new backend into the slot */
20342029
beentry->procpid = msg->m_procpid;
2035-
beentry->userid = msg->m_userid;
20362030
beentry->start_sec =
20372031
GetCurrentAbsoluteTimeUsec(&beentry->start_usec);
20382032
beentry->activity_start_sec = 0;
20392033
beentry->activity_start_usec = 0;
2040-
memcpy(&beentry->clientaddr, &msg->m_clientaddr, sizeof(beentry->clientaddr));
2041-
MemSet(beentry->activity, 0, PGSTAT_ACTIVITY_SIZE);
2034+
beentry->activity[0] = '\0';
20422035

20432036
/*
2044-
* Lookup or create the database entry for this backend's DB.
2037+
* We can't initialize the rest of the data in this slot until we
2038+
* see the BESTART message. Therefore, we set the database and
2039+
* user to sentinel values, to indicate "undefined". There is no
2040+
* easy way to do this for the client address, so make sure to
2041+
* check that the database or user are defined before accessing
2042+
* the client address.
20452043
*/
2046-
dbentry = (PgStat_StatDBEntry *) hash_search(pgStatDBHash,
2047-
(void *) &(msg->m_databaseid),
2048-
HASH_ENTER, &found);
2049-
if (dbentry == NULL)
2044+
beentry->userid = InvalidOid;
2045+
beentry->databaseid = InvalidOid;
2046+
2047+
return 0;
2048+
}
2049+
2050+
/*
2051+
* Lookup the hash table entry for the specified database. If no hash
2052+
* table entry exists, initialize it.
2053+
*/
2054+
static PgStat_StatDBEntry *
2055+
pgstat_get_db_entry(int databaseid)
2056+
{
2057+
PgStat_StatDBEntry *result;
2058+
bool found;
2059+
2060+
/* Lookup or create the hash table entry for this database */
2061+
result = (PgStat_StatDBEntry *) hash_search(pgStatDBHash,
2062+
&databaseid,
2063+
HASH_ENTER, &found);
2064+
if (result == NULL)
20502065
ereport(ERROR,
20512066
(errcode(ERRCODE_OUT_OF_MEMORY),
2052-
errmsg("out of memory in statistics collector --- abort")));
2067+
errmsg("out of memory in statistics collector --- abort")));
20532068

2054-
/*
2055-
* If not found, initialize the new one.
2056-
*/
2069+
/* If not found, initialize the new one. */
20572070
if (!found)
20582071
{
20592072
HASHCTL hash_ctl;
20602073

2061-
dbentry->tables = NULL;
2062-
dbentry->n_xact_commit = 0;
2063-
dbentry->n_xact_rollback = 0;
2064-
dbentry->n_blocks_fetched = 0;
2065-
dbentry->n_blocks_hit = 0;
2066-
dbentry->n_connects = 0;
2067-
dbentry->destroy = 0;
2074+
result->tables = NULL;
2075+
result->n_xact_commit = 0;
2076+
result->n_xact_rollback = 0;
2077+
result->n_blocks_fetched = 0;
2078+
result->n_blocks_hit = 0;
2079+
result->destroy = 0;
20682080

20692081
memset(&hash_ctl, 0, sizeof(hash_ctl));
20702082
hash_ctl.keysize = sizeof(Oid);
20712083
hash_ctl.entrysize = sizeof(PgStat_StatTabEntry);
20722084
hash_ctl.hash = oid_hash;
2073-
dbentry->tables = hash_create("Per-database table",
2085+
result->tables = hash_create("Per-database table",
20742086
PGSTAT_TAB_HASH_SIZE,
20752087
&hash_ctl,
20762088
HASH_ELEM | HASH_FUNCTION);
20772089
}
20782090

2079-
/* Count the number of connects to the database */
2080-
dbentry->n_connects++;
2081-
2082-
return 0;
2091+
return result;
20832092
}
20842093

2085-
20862094
/* ----------
20872095
* pgstat_sub_backend() -
20882096
*
@@ -2102,8 +2110,7 @@ pgstat_sub_backend(int procpid)
21022110
*/
21032111
for (i = 0; i < MaxBackends; i++)
21042112
{
2105-
if (pgStatBeTable[i].databaseid != InvalidOid &&
2106-
pgStatBeTable[i].procpid == procpid)
2113+
if (pgStatBeTable[i].procpid == procpid)
21072114
{
21082115
/*
21092116
* That's him. Add an entry to the known to be dead backends.
@@ -2133,7 +2140,7 @@ pgstat_sub_backend(int procpid)
21332140
/*
21342141
* Declare the backend slot empty.
21352142
*/
2136-
pgStatBeTable[i].databaseid = InvalidOid;
2143+
pgStatBeTable[i].procpid = 0;
21372144
return;
21382145
}
21392146
}
@@ -2263,7 +2270,7 @@ pgstat_write_statsfile(void)
22632270

22642271
for (i = 0; i < MaxBackends; i++)
22652272
{
2266-
if (pgStatBeTable[i].databaseid != InvalidOid)
2273+
if (pgStatBeTable[i].procpid > 0)
22672274
{
22682275
fputc('B', fpout);
22692276
fwrite(&pgStatBeTable[i], sizeof(PgStat_StatBeEntry), 1, fpout);
@@ -2624,7 +2631,20 @@ backend_read_statsfile(void)
26242631
static void
26252632
pgstat_recv_bestart(PgStat_MsgBestart *msg, int len)
26262633
{
2627-
pgstat_add_backend(&msg->m_hdr);
2634+
PgStat_StatBeEntry *entry;
2635+
2636+
/*
2637+
* If the backend is known dead, we ignore the message -- we don't
2638+
* want to update the backend entry's state since this BESTART
2639+
* message refers to an old, dead backend
2640+
*/
2641+
if (pgstat_add_backend(&msg->m_hdr) != 0)
2642+
return;
2643+
2644+
entry = &(pgStatBeTable[msg->m_hdr.m_backendid - 1]);
2645+
entry->userid = msg->m_userid;
2646+
memcpy(&entry->clientaddr, &msg->m_clientaddr, sizeof(entry->clientaddr));
2647+
entry->databaseid = msg->m_databaseid;
26282648
}
26292649

26302650

@@ -2690,14 +2710,7 @@ pgstat_recv_tabstat(PgStat_MsgTabstat *msg, int len)
26902710
if (pgstat_add_backend(&msg->m_hdr) < 0)
26912711
return;
26922712

2693-
/*
2694-
* Lookup the database in the hashtable.
2695-
*/
2696-
dbentry = (PgStat_StatDBEntry *) hash_search(pgStatDBHash,
2697-
(void *) &(msg->m_hdr.m_databaseid),
2698-
HASH_FIND, NULL);
2699-
if (!dbentry)
2700-
return;
2713+
dbentry = pgstat_get_db_entry(msg->m_databaseid);
27012714

27022715
/*
27032716
* If the database is marked for destroy, this is a delayed UDP packet
@@ -2782,14 +2795,7 @@ pgstat_recv_tabpurge(PgStat_MsgTabpurge *msg, int len)
27822795
if (pgstat_add_backend(&msg->m_hdr) < 0)
27832796
return;
27842797

2785-
/*
2786-
* Lookup the database in the hashtable.
2787-
*/
2788-
dbentry = (PgStat_StatDBEntry *) hash_search(pgStatDBHash,
2789-
(void *) &(msg->m_hdr.m_databaseid),
2790-
HASH_FIND, NULL);
2791-
if (!dbentry)
2792-
return;
2798+
dbentry = pgstat_get_db_entry(msg->m_databaseid);
27932799

27942800
/*
27952801
* If the database is marked for destroy, this is a delayed UDP packet
@@ -2832,11 +2838,7 @@ pgstat_recv_dropdb(PgStat_MsgDropdb *msg, int len)
28322838
/*
28332839
* Lookup the database in the hashtable.
28342840
*/
2835-
dbentry = (PgStat_StatDBEntry *) hash_search(pgStatDBHash,
2836-
(void *) &(msg->m_databaseid),
2837-
HASH_FIND, NULL);
2838-
if (!dbentry)
2839-
return;
2841+
dbentry = pgstat_get_db_entry(msg->m_databaseid);
28402842

28412843
/*
28422844
* Mark the database for destruction.
@@ -2846,9 +2848,9 @@ pgstat_recv_dropdb(PgStat_MsgDropdb *msg, int len)
28462848

28472849

28482850
/* ----------
2849-
* pgstat_recv_dropdb() -
2851+
* pgstat_recv_resetcounter() -
28502852
*
2851-
* Arrange for dead database removal
2853+
* Reset the statistics for the specified database.
28522854
* ----------
28532855
*/
28542856
static void
@@ -2866,15 +2868,11 @@ pgstat_recv_resetcounter(PgStat_MsgResetcounter *msg, int len)
28662868
/*
28672869
* Lookup the database in the hashtable.
28682870
*/
2869-
dbentry = (PgStat_StatDBEntry *) hash_search(pgStatDBHash,
2870-
(void *) &(msg->m_hdr.m_databaseid),
2871-
HASH_FIND, NULL);
2872-
if (!dbentry)
2873-
return;
2871+
dbentry = pgstat_get_db_entry(msg->m_databaseid);
28742872

28752873
/*
2876-
* We simply throw away all the databases table entries by recreating
2877-
* a new hash table for them.
2874+
* We simply throw away all the database's table entries by
2875+
* recreating a new hash table for them.
28782876
*/
28792877
if (dbentry->tables != NULL)
28802878
hash_destroy(dbentry->tables);
@@ -2884,7 +2882,6 @@ pgstat_recv_resetcounter(PgStat_MsgResetcounter *msg, int len)
28842882
dbentry->n_xact_rollback = 0;
28852883
dbentry->n_blocks_fetched = 0;
28862884
dbentry->n_blocks_hit = 0;
2887-
dbentry->n_connects = 0;
28882885
dbentry->destroy = 0;
28892886

28902887
memset(&hash_ctl, 0, sizeof(hash_ctl));

0 commit comments

Comments
 (0)