1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-09 06:21:09 +03:00

Take the statistics collector out of the loop for monitoring backends'

current commands; instead, store current-status information in shared
memory.  This substantially reduces the overhead of stats_command_string
and also ensures that pg_stat_activity is fully up to date at all times.
Per my recent proposal.
This commit is contained in:
Tom Lane
2006-06-19 01:51:22 +00:00
parent 6075feed40
commit b13c9686d0
11 changed files with 880 additions and 1198 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -37,7 +37,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.486 2006/06/18 15:38:37 petere Exp $
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.487 2006/06/19 01:51:21 tgl Exp $
*
* NOTES
*
@@ -2109,9 +2109,6 @@ reaper(SIGNAL_ARGS)
{
AutoVacPID = 0;
autovac_stopped();
/* Tell the collector about process termination */
pgstat_beterm(pid);
if (exitstatus != 0)
HandleChildCrash(pid, exitstatus,
_("autovacuum process"));
@@ -2252,8 +2249,6 @@ CleanupBackend(int pid,
#ifdef EXEC_BACKEND
ShmemBackendArrayRemove(pid);
#endif
/* Tell the collector about backend termination */
pgstat_beterm(pid);
break;
}
}
@@ -2299,8 +2294,6 @@ HandleChildCrash(int pid, int exitstatus, const char *procname)
#ifdef EXEC_BACKEND
ShmemBackendArrayRemove(pid);
#endif
/* Tell the collector about backend termination */
pgstat_beterm(pid);
/* Keep looping so we can signal remaining backends */
}
else

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/ipc/ipci.c,v 1.83 2006/05/08 00:00:10 tgl Exp $
* $PostgreSQL: pgsql/src/backend/storage/ipc/ipci.c,v 1.84 2006/06/19 01:51:21 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,6 +21,7 @@
#include "access/twophase.h"
#include "access/xlog.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "postmaster/bgwriter.h"
#include "postmaster/postmaster.h"
#include "storage/bufmgr.h"
@@ -86,6 +87,7 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int port)
size = add_size(size, MultiXactShmemSize());
size = add_size(size, LWLockShmemSize());
size = add_size(size, ProcArrayShmemSize());
size = add_size(size, BackendStatusShmemSize());
size = add_size(size, SInvalShmemSize());
size = add_size(size, FreeSpaceShmemSize());
size = add_size(size, BgWriterShmemSize());
@@ -167,6 +169,7 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int port)
if (!IsUnderPostmaster)
InitProcGlobal();
CreateSharedProcArray();
CreateSharedBackendStatus();
/*
* Set up shared-inval messaging

View File

@@ -23,7 +23,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.11 2006/03/05 15:58:37 momjian Exp $
* $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.12 2006/06/19 01:51:21 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -732,42 +732,6 @@ IsBackendPid(int pid)
return (BackendPidGetProc(pid) != NULL);
}
/*
* GetAllBackendPids -- get an array of all current backends' PIDs
*
* The result is a palloc'd array with the number of active backends in
* entry [0], their PIDs in entries [1] .. [n]. The caller must bear in
* mind that the result may already be obsolete when returned.
*/
int *
GetAllBackendPids(void)
{
int *result;
int npids;
ProcArrayStruct *arrayP = procArray;
int index;
result = (int *) palloc((MaxBackends + 1) * sizeof(int));
npids = 0;
LWLockAcquire(ProcArrayLock, LW_SHARED);
for (index = 0; index < arrayP->numProcs; index++)
{
PGPROC *proc = arrayP->procs[index];
if (proc->pid != 0) /* ignore dummy procs */
result[++npids] = proc->pid;
}
LWLockRelease(ProcArrayLock);
Assert(npids <= MaxBackends);
result[0] = npids;
return result;
}
/*
* CountActiveBackends --- count backends (other than myself) that are in
* active transactions. This is used as a heuristic to decide if

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/pgstatfuncs.c,v 1.29 2006/05/19 19:08:26 alvherre Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/pgstatfuncs.c,v 1.30 2006/06/19 01:51:21 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -61,11 +61,9 @@ extern Datum pg_stat_get_db_blocks_hit(PG_FUNCTION_ARGS);
Datum
pg_stat_get_numscans(PG_FUNCTION_ARGS)
{
PgStat_StatTabEntry *tabentry;
Oid relid;
Oid relid = PG_GETARG_OID(0);
int64 result;
relid = PG_GETARG_OID(0);
PgStat_StatTabEntry *tabentry;
if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
result = 0;
@@ -79,11 +77,9 @@ pg_stat_get_numscans(PG_FUNCTION_ARGS)
Datum
pg_stat_get_tuples_returned(PG_FUNCTION_ARGS)
{
PgStat_StatTabEntry *tabentry;
Oid relid;
Oid relid = PG_GETARG_OID(0);
int64 result;
relid = PG_GETARG_OID(0);
PgStat_StatTabEntry *tabentry;
if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
result = 0;
@@ -97,11 +93,9 @@ pg_stat_get_tuples_returned(PG_FUNCTION_ARGS)
Datum
pg_stat_get_tuples_fetched(PG_FUNCTION_ARGS)
{
PgStat_StatTabEntry *tabentry;
Oid relid;
Oid relid = PG_GETARG_OID(0);
int64 result;
relid = PG_GETARG_OID(0);
PgStat_StatTabEntry *tabentry;
if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
result = 0;
@@ -115,11 +109,9 @@ pg_stat_get_tuples_fetched(PG_FUNCTION_ARGS)
Datum
pg_stat_get_tuples_inserted(PG_FUNCTION_ARGS)
{
PgStat_StatTabEntry *tabentry;
Oid relid;
Oid relid = PG_GETARG_OID(0);
int64 result;
relid = PG_GETARG_OID(0);
PgStat_StatTabEntry *tabentry;
if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
result = 0;
@@ -133,11 +125,9 @@ pg_stat_get_tuples_inserted(PG_FUNCTION_ARGS)
Datum
pg_stat_get_tuples_updated(PG_FUNCTION_ARGS)
{
PgStat_StatTabEntry *tabentry;
Oid relid;
Oid relid = PG_GETARG_OID(0);
int64 result;
relid = PG_GETARG_OID(0);
PgStat_StatTabEntry *tabentry;
if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
result = 0;
@@ -151,11 +141,9 @@ pg_stat_get_tuples_updated(PG_FUNCTION_ARGS)
Datum
pg_stat_get_tuples_deleted(PG_FUNCTION_ARGS)
{
PgStat_StatTabEntry *tabentry;
Oid relid;
Oid relid = PG_GETARG_OID(0);
int64 result;
relid = PG_GETARG_OID(0);
PgStat_StatTabEntry *tabentry;
if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
result = 0;
@@ -169,11 +157,9 @@ pg_stat_get_tuples_deleted(PG_FUNCTION_ARGS)
Datum
pg_stat_get_blocks_fetched(PG_FUNCTION_ARGS)
{
PgStat_StatTabEntry *tabentry;
Oid relid;
Oid relid = PG_GETARG_OID(0);
int64 result;
relid = PG_GETARG_OID(0);
PgStat_StatTabEntry *tabentry;
if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
result = 0;
@@ -187,11 +173,9 @@ pg_stat_get_blocks_fetched(PG_FUNCTION_ARGS)
Datum
pg_stat_get_blocks_hit(PG_FUNCTION_ARGS)
{
PgStat_StatTabEntry *tabentry;
Oid relid;
Oid relid = PG_GETARG_OID(0);
int64 result;
relid = PG_GETARG_OID(0);
PgStat_StatTabEntry *tabentry;
if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
result = 0;
@@ -204,11 +188,9 @@ pg_stat_get_blocks_hit(PG_FUNCTION_ARGS)
Datum
pg_stat_get_last_vacuum_time(PG_FUNCTION_ARGS)
{
PgStat_StatTabEntry *tabentry;
Oid relid;
Oid relid = PG_GETARG_OID(0);
TimestampTz result;
relid = PG_GETARG_OID(0);
PgStat_StatTabEntry *tabentry;
if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
result = 0;
@@ -224,11 +206,9 @@ pg_stat_get_last_vacuum_time(PG_FUNCTION_ARGS)
Datum
pg_stat_get_last_autovacuum_time(PG_FUNCTION_ARGS)
{
PgStat_StatTabEntry *tabentry;
Oid relid;
Oid relid = PG_GETARG_OID(0);
TimestampTz result;
relid = PG_GETARG_OID(0);
PgStat_StatTabEntry *tabentry;
if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
result = 0;
@@ -244,11 +224,9 @@ pg_stat_get_last_autovacuum_time(PG_FUNCTION_ARGS)
Datum
pg_stat_get_last_analyze_time(PG_FUNCTION_ARGS)
{
PgStat_StatTabEntry *tabentry;
Oid relid;
Oid relid = PG_GETARG_OID(0);
TimestampTz result;
relid = PG_GETARG_OID(0);
PgStat_StatTabEntry *tabentry;
if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
result = 0;
@@ -264,11 +242,9 @@ pg_stat_get_last_analyze_time(PG_FUNCTION_ARGS)
Datum
pg_stat_get_last_autoanalyze_time(PG_FUNCTION_ARGS)
{
PgStat_StatTabEntry *tabentry;
Oid relid;
Oid relid = PG_GETARG_OID(0);
TimestampTz result;
relid = PG_GETARG_OID(0);
PgStat_StatTabEntry *tabentry;
if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
result = 0;
@@ -342,75 +318,59 @@ pg_stat_reset(PG_FUNCTION_ARGS)
Datum
pg_stat_get_backend_pid(PG_FUNCTION_ARGS)
{
PgStat_StatBeEntry *beentry;
int32 beid;
beid = PG_GETARG_INT32(0);
int32 beid = PG_GETARG_INT32(0);
PgBackendStatus *beentry;
if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
PG_RETURN_NULL();
PG_RETURN_INT32(beentry->procpid);
PG_RETURN_INT32(beentry->st_procpid);
}
Datum
pg_stat_get_backend_dbid(PG_FUNCTION_ARGS)
{
PgStat_StatBeEntry *beentry;
int32 beid;
beid = PG_GETARG_INT32(0);
int32 beid = PG_GETARG_INT32(0);
PgBackendStatus *beentry;
if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
PG_RETURN_NULL();
/* Not initialized yet? */
if (!OidIsValid(beentry->databaseid))
PG_RETURN_NULL();
PG_RETURN_OID(beentry->databaseid);
PG_RETURN_OID(beentry->st_databaseid);
}
Datum
pg_stat_get_backend_userid(PG_FUNCTION_ARGS)
{
PgStat_StatBeEntry *beentry;
int32 beid;
beid = PG_GETARG_INT32(0);
int32 beid = PG_GETARG_INT32(0);
PgBackendStatus *beentry;
if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
PG_RETURN_NULL();
/* Not initialized yet? */
if (!OidIsValid(beentry->userid))
PG_RETURN_NULL();
PG_RETURN_OID(beentry->userid);
PG_RETURN_OID(beentry->st_userid);
}
Datum
pg_stat_get_backend_activity(PG_FUNCTION_ARGS)
{
PgStat_StatBeEntry *beentry;
int32 beid;
int len;
char *activity;
int32 beid = PG_GETARG_INT32(0);
text *result;
beid = PG_GETARG_INT32(0);
PgBackendStatus *beentry;
int len;
const char *activity;
if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
activity = "<backend information not available>";
else if (!superuser() && beentry->userid != GetUserId())
else if (!superuser() && beentry->st_userid != GetUserId())
activity = "<insufficient privilege>";
else if (*(beentry->activity) == '\0')
else if (*(beentry->st_activity) == '\0')
activity = "<command string not enabled>";
else
activity = beentry->activity;
activity = beentry->st_activity;
len = strlen(activity);
result = palloc(VARHDRSZ + len);
@@ -426,15 +386,15 @@ pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS)
{
int32 beid = PG_GETARG_INT32(0);
TimestampTz result;
PgStat_StatBeEntry *beentry;
PgBackendStatus *beentry;
if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
PG_RETURN_NULL();
if (!superuser() && beentry->userid != GetUserId())
if (!superuser() && beentry->st_userid != GetUserId())
PG_RETURN_NULL();
result = beentry->activity_start_timestamp;
result = beentry->st_activity_start_timestamp;
/*
* No time recorded for start of current query -- this is the case if the
@@ -451,15 +411,15 @@ pg_stat_get_backend_start(PG_FUNCTION_ARGS)
{
int32 beid = PG_GETARG_INT32(0);
TimestampTz result;
PgStat_StatBeEntry *beentry;
PgBackendStatus *beentry;
if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
PG_RETURN_NULL();
if (!superuser() && beentry->userid != GetUserId())
if (!superuser() && beentry->st_userid != GetUserId())
PG_RETURN_NULL();
result = beentry->start_timestamp;
result = beentry->st_proc_start_timestamp;
if (result == 0) /* probably can't happen? */
PG_RETURN_NULL();
@@ -471,31 +431,25 @@ pg_stat_get_backend_start(PG_FUNCTION_ARGS)
Datum
pg_stat_get_backend_client_addr(PG_FUNCTION_ARGS)
{
PgStat_StatBeEntry *beentry;
int32 beid = PG_GETARG_INT32(0);
PgBackendStatus *beentry;
SockAddr zero_clientaddr;
int32 beid;
char remote_host[NI_MAXHOST];
int ret;
beid = PG_GETARG_INT32(0);
if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
PG_RETURN_NULL();
/* Not initialized yet? */
if (!OidIsValid(beentry->userid))
PG_RETURN_NULL();
if (!superuser() && beentry->userid != GetUserId())
if (!superuser() && beentry->st_userid != GetUserId())
PG_RETURN_NULL();
/* A zeroed client addr means we don't know */
memset(&zero_clientaddr, 0, sizeof(zero_clientaddr));
if (memcmp(&(beentry->clientaddr), &zero_clientaddr,
if (memcmp(&(beentry->st_clientaddr), &zero_clientaddr,
sizeof(zero_clientaddr) == 0))
PG_RETURN_NULL();
switch (beentry->clientaddr.addr.ss_family)
switch (beentry->st_clientaddr.addr.ss_family)
{
case AF_INET:
#ifdef HAVE_IPV6
@@ -507,7 +461,8 @@ pg_stat_get_backend_client_addr(PG_FUNCTION_ARGS)
}
remote_host[0] = '\0';
ret = pg_getnameinfo_all(&beentry->clientaddr.addr, beentry->clientaddr.salen,
ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
beentry->st_clientaddr.salen,
remote_host, sizeof(remote_host),
NULL, 0,
NI_NUMERICHOST | NI_NUMERICSERV);
@@ -521,31 +476,25 @@ pg_stat_get_backend_client_addr(PG_FUNCTION_ARGS)
Datum
pg_stat_get_backend_client_port(PG_FUNCTION_ARGS)
{
PgStat_StatBeEntry *beentry;
int32 beid = PG_GETARG_INT32(0);
PgBackendStatus *beentry;
SockAddr zero_clientaddr;
int32 beid;
char remote_port[NI_MAXSERV];
int ret;
beid = PG_GETARG_INT32(0);
if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
PG_RETURN_NULL();
/* Not initialized yet? */
if (!OidIsValid(beentry->userid))
PG_RETURN_NULL();
if (!superuser() && beentry->userid != GetUserId())
if (!superuser() && beentry->st_userid != GetUserId())
PG_RETURN_NULL();
/* A zeroed client addr means we don't know */
memset(&zero_clientaddr, 0, sizeof(zero_clientaddr));
if (memcmp(&(beentry->clientaddr), &zero_clientaddr,
if (memcmp(&(beentry->st_clientaddr), &zero_clientaddr,
sizeof(zero_clientaddr) == 0))
PG_RETURN_NULL();
switch (beentry->clientaddr.addr.ss_family)
switch (beentry->st_clientaddr.addr.ss_family)
{
case AF_INET:
#ifdef HAVE_IPV6
@@ -559,31 +508,35 @@ pg_stat_get_backend_client_port(PG_FUNCTION_ARGS)
}
remote_port[0] = '\0';
ret = pg_getnameinfo_all(&beentry->clientaddr.addr,
beentry->clientaddr.salen,
ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
beentry->st_clientaddr.salen,
NULL, 0,
remote_port, sizeof(remote_port),
NI_NUMERICHOST | NI_NUMERICSERV);
if (ret)
PG_RETURN_NULL();
PG_RETURN_DATUM(DirectFunctionCall1(int4in, CStringGetDatum(remote_port)));
PG_RETURN_DATUM(DirectFunctionCall1(int4in,
CStringGetDatum(remote_port)));
}
Datum
pg_stat_get_db_numbackends(PG_FUNCTION_ARGS)
{
PgStat_StatDBEntry *dbentry;
Oid dbid;
Oid dbid = PG_GETARG_OID(0);
int32 result;
int tot_backends = pgstat_fetch_stat_numbackends();
int beid;
dbid = PG_GETARG_OID(0);
result = 0;
for (beid = 1; beid <= tot_backends; beid++)
{
PgBackendStatus *beentry = pgstat_fetch_stat_beentry(beid);
if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
result = 0;
else
result = (int32) (dbentry->n_backends);
if (beentry && beentry->st_databaseid == dbid)
result++;
}
PG_RETURN_INT32(result);
}
@@ -592,11 +545,9 @@ pg_stat_get_db_numbackends(PG_FUNCTION_ARGS)
Datum
pg_stat_get_db_xact_commit(PG_FUNCTION_ARGS)
{
PgStat_StatDBEntry *dbentry;
Oid dbid;
Oid dbid = PG_GETARG_OID(0);
int64 result;
dbid = PG_GETARG_OID(0);
PgStat_StatDBEntry *dbentry;
if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
result = 0;
@@ -610,11 +561,9 @@ pg_stat_get_db_xact_commit(PG_FUNCTION_ARGS)
Datum
pg_stat_get_db_xact_rollback(PG_FUNCTION_ARGS)
{
PgStat_StatDBEntry *dbentry;
Oid dbid;
Oid dbid = PG_GETARG_OID(0);
int64 result;
dbid = PG_GETARG_OID(0);
PgStat_StatDBEntry *dbentry;
if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
result = 0;
@@ -628,11 +577,9 @@ pg_stat_get_db_xact_rollback(PG_FUNCTION_ARGS)
Datum
pg_stat_get_db_blocks_fetched(PG_FUNCTION_ARGS)
{
PgStat_StatDBEntry *dbentry;
Oid dbid;
Oid dbid = PG_GETARG_OID(0);
int64 result;
dbid = PG_GETARG_OID(0);
PgStat_StatDBEntry *dbentry;
if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
result = 0;
@@ -646,11 +593,9 @@ pg_stat_get_db_blocks_fetched(PG_FUNCTION_ARGS)
Datum
pg_stat_get_db_blocks_hit(PG_FUNCTION_ARGS)
{
PgStat_StatDBEntry *dbentry;
Oid dbid;
Oid dbid = PG_GETARG_OID(0);
int64 result;
dbid = PG_GETARG_OID(0);
PgStat_StatDBEntry *dbentry;
if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL)
result = 0;

View File

@@ -10,7 +10,7 @@
* Written by Peter Eisentraut <peter_e@gmx.net>.
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.321 2006/06/05 02:49:58 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.322 2006/06/19 01:51:21 tgl Exp $
*
*--------------------------------------------------------------------
*/
@@ -700,16 +700,6 @@ static struct config_bool ConfigureNamesBool[] =
&pgstat_collect_resetonpmstart,
false, NULL, NULL
},
{
{"stats_command_string", PGC_SUSET, STATS_COLLECTOR,
gettext_noop("Collects statistics about executing commands."),
gettext_noop("Enables the collection of statistics on the currently "
"executing command of each session, along with the time "
"at which that command began execution.")
},
&pgstat_collect_querystring,
false, NULL, NULL
},
{
{"stats_row_level", PGC_SUSET, STATS_COLLECTOR,
gettext_noop("Collects row-level statistics on database activity."),
@@ -727,6 +717,17 @@ static struct config_bool ConfigureNamesBool[] =
false, NULL, NULL
},
{
{"stats_command_string", PGC_SUSET, STATS_COLLECTOR,
gettext_noop("Collects information about executing commands."),
gettext_noop("Enables the collection of information on the currently "
"executing command of each session, along with the time "
"at which that command began execution.")
},
&pgstat_collect_querystring,
false, NULL, NULL
},
{
{"autovacuum", PGC_SIGHUP, AUTOVACUUM,
gettext_noop("Starts the autovacuum subprocess."),

View File

@@ -320,6 +320,14 @@
# RUNTIME STATISTICS
#---------------------------------------------------------------------------
# - Query/Index Statistics Collector -
#stats_command_string = off
#stats_start_collector = on # needed for block or row stats
#stats_block_level = off
#stats_row_level = off
#stats_reset_on_server_start = off
# - Statistics Monitoring -
#log_parser_stats = off
@@ -327,14 +335,6 @@
#log_executor_stats = off
#log_statement_stats = off
# - Query/Index Statistics Collector -
#stats_start_collector = on
#stats_command_string = off
#stats_block_level = off
#stats_row_level = off
#stats_reset_on_server_start = off
#---------------------------------------------------------------------------
# AUTOVACUUM PARAMETERS