*
* Copyright (c) 2001-2008, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.175 2008/06/19 00:46:05 alvherre Exp $
+ * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.176 2008/06/30 10:58:47 heikki Exp $
* ----------
*/
#include "postgres.h"
bool pgstat_track_activities = false;
bool pgstat_track_counts = false;
int pgstat_track_functions = TRACK_FUNC_OFF;
+int pgstat_track_activity_query_size = 1024;
/*
* BgWriter global statistics counters (unused in other processes).
static PgBackendStatus *BackendStatusArray = NULL;
static PgBackendStatus *MyBEEntry = NULL;
+static char *BackendActivityBuffer = NULL;
/*
{
Size size;
- size = mul_size(sizeof(PgBackendStatus), MaxBackends);
+ size = add_size(mul_size(sizeof(PgBackendStatus), MaxBackends),
+ mul_size(pgstat_track_activity_query_size, MaxBackends));
return size;
}
/*
- * Initialize the shared status array during postmaster startup.
+ * Initialize the shared status array and activity string buffer during
+ * postmaster startup.
*/
void
CreateSharedBackendStatus(void)
{
- Size size = BackendStatusShmemSize();
+ Size size;
bool found;
+ int i;
+ char *buffer;
/* Create or attach to the shared array */
+ size = mul_size(sizeof(PgBackendStatus), MaxBackends);
BackendStatusArray = (PgBackendStatus *)
ShmemInitStruct("Backend Status Array", size, &found);
*/
MemSet(BackendStatusArray, 0, size);
}
+
+ /* Create or attach to the shared activity buffer */
+ size = mul_size(pgstat_track_activity_query_size, MaxBackends);
+ BackendActivityBuffer = (char*)
+ ShmemInitStruct("Backend Activity Buffer", size, &found);
+
+ if (!found)
+ {
+ MemSet(BackendActivityBuffer, 0, size);
+
+ /* Initialize st_activity pointers. */
+ buffer = BackendActivityBuffer;
+ for (i = 0; i < MaxBackends; i++) {
+ BackendStatusArray[i].st_activity = buffer;
+ buffer += pgstat_track_activity_query_size;
+ }
+ }
}
beentry->st_waiting = false;
beentry->st_activity[0] = '\0';
/* Also make sure the last byte in the string area is always 0 */
- beentry->st_activity[PGBE_ACTIVITY_SIZE - 1] = '\0';
+ beentry->st_activity[pgstat_track_activity_query_size - 1] = '\0';
beentry->st_changecount++;
Assert((beentry->st_changecount & 1) == 0);
start_timestamp = GetCurrentStatementStartTimestamp();
len = strlen(cmd_str);
- len = pg_mbcliplen(cmd_str, len, PGBE_ACTIVITY_SIZE - 1);
+ len = pg_mbcliplen(cmd_str, len, pgstat_track_activity_query_size - 1);
/*
* Update my status entry, following the protocol of bumping
volatile PgBackendStatus *beentry;
PgBackendStatus *localtable;
PgBackendStatus *localentry;
+ char *localactivity;
int i;
Assert(!pgStatRunningInCollector);
localtable = (PgBackendStatus *)
MemoryContextAlloc(pgStatLocalContext,
sizeof(PgBackendStatus) * MaxBackends);
+ localactivity = (char *)
+ MemoryContextAlloc(pgStatLocalContext,
+ pgstat_track_activity_query_size * MaxBackends);
localNumBackends = 0;
beentry = BackendStatusArray;
{
int save_changecount = beentry->st_changecount;
- /*
- * XXX if PGBE_ACTIVITY_SIZE is really large, it might be best to
- * use strcpy not memcpy for copying the activity string?
- */
- memcpy(localentry, (char *) beentry, sizeof(PgBackendStatus));
+ localentry->st_procpid = beentry->st_procpid;
+ if (localentry->st_procpid > 0)
+ {
+ memcpy(localentry, (char *) beentry, sizeof(PgBackendStatus));
+ /*
+ * strcpy is safe even if the string is modified concurrently,
+ * because there's always a \0 at the end of the buffer.
+ */
+ strcpy(localactivity, (char *) beentry->st_activity);
+ localentry->st_activity = localactivity;
+ }
if (save_changecount == beentry->st_changecount &&
(save_changecount & 1) == 0)
if (localentry->st_procpid > 0)
{
localentry++;
+ localactivity += pgstat_track_activity_query_size;
localNumBackends++;
}
}
* Written by Peter Eisentraut <peter_e@gmx.net>.
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.456 2008/05/28 09:04:06 mha Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.457 2008/06/30 10:58:47 heikki Exp $
*
*--------------------------------------------------------------------
*/
-1, -1, INT_MAX, NULL, NULL
},
+ {
+ {"track_activity_query_size", PGC_POSTMASTER, RESOURCES_MEM,
+ gettext_noop("Sets the size reserved for pg_stat_activity.current_query, in bytes."),
+ NULL,
+ },
+ &pgstat_track_activity_query_size,
+ 1024, 100, 102400, NULL, NULL
+ },
+
/* End-of-list marker */
{
{NULL, 0, 0, NULL, NULL}, NULL, 0, 0, 0, NULL, NULL