aboutsummaryrefslogtreecommitdiff
path: root/src/backend/postmaster/pgstat.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/postmaster/pgstat.c')
-rw-r--r--src/backend/postmaster/pgstat.c194
1 files changed, 169 insertions, 25 deletions
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index b704788eb5a..869afd4c4a5 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -50,6 +50,7 @@
#include "postmaster/autovacuum.h"
#include "postmaster/fork_process.h"
#include "postmaster/postmaster.h"
+#include "replication/walsender.h"
#include "storage/backendid.h"
#include "storage/dsm.h"
#include "storage/fd.h"
@@ -103,6 +104,18 @@
/* ----------
+ * Total number of backends including auxiliary
+ *
+ * We reserve a slot for each possible BackendId, plus one for each
+ * possible auxiliary process type. (This scheme assumes there is not
+ * more than one of any auxiliary process type at a time.) MaxBackends
+ * includes autovacuum workers and background workers as well.
+ * ----------
+ */
+#define NumBackendStatSlots (MaxBackends + NUM_AUXPROCTYPES)
+
+
+/* ----------
* GUC parameters
* ----------
*/
@@ -212,7 +225,11 @@ typedef struct TwoPhasePgStatRecord
*/
static MemoryContext pgStatLocalContext = NULL;
static HTAB *pgStatDBHash = NULL;
+
+/* Status for backends including auxiliary */
static LocalPgBackendStatus *localBackendStatusTable = NULL;
+
+/* Total number of backends including auxiliary */
static int localNumBackends = 0;
/*
@@ -2505,20 +2522,20 @@ BackendStatusShmemSize(void)
Size size;
/* BackendStatusArray: */
- size = mul_size(sizeof(PgBackendStatus), MaxBackends);
+ size = mul_size(sizeof(PgBackendStatus), NumBackendStatSlots);
/* BackendAppnameBuffer: */
size = add_size(size,
- mul_size(NAMEDATALEN, MaxBackends));
+ mul_size(NAMEDATALEN, NumBackendStatSlots));
/* BackendClientHostnameBuffer: */
size = add_size(size,
- mul_size(NAMEDATALEN, MaxBackends));
+ mul_size(NAMEDATALEN, NumBackendStatSlots));
/* BackendActivityBuffer: */
size = add_size(size,
- mul_size(pgstat_track_activity_query_size, MaxBackends));
+ mul_size(pgstat_track_activity_query_size, NumBackendStatSlots));
#ifdef USE_SSL
/* BackendSslStatusBuffer: */
size = add_size(size,
- mul_size(sizeof(PgBackendSSLStatus), MaxBackends));
+ mul_size(sizeof(PgBackendSSLStatus), NumBackendStatSlots));
#endif
return size;
}
@@ -2536,7 +2553,7 @@ CreateSharedBackendStatus(void)
char *buffer;
/* Create or attach to the shared array */
- size = mul_size(sizeof(PgBackendStatus), MaxBackends);
+ size = mul_size(sizeof(PgBackendStatus), NumBackendStatSlots);
BackendStatusArray = (PgBackendStatus *)
ShmemInitStruct("Backend Status Array", size, &found);
@@ -2559,7 +2576,7 @@ CreateSharedBackendStatus(void)
/* Initialize st_appname pointers. */
buffer = BackendAppnameBuffer;
- for (i = 0; i < MaxBackends; i++)
+ for (i = 0; i < NumBackendStatSlots; i++)
{
BackendStatusArray[i].st_appname = buffer;
buffer += NAMEDATALEN;
@@ -2577,7 +2594,7 @@ CreateSharedBackendStatus(void)
/* Initialize st_clienthostname pointers. */
buffer = BackendClientHostnameBuffer;
- for (i = 0; i < MaxBackends; i++)
+ for (i = 0; i < NumBackendStatSlots; i++)
{
BackendStatusArray[i].st_clienthostname = buffer;
buffer += NAMEDATALEN;
@@ -2586,7 +2603,7 @@ CreateSharedBackendStatus(void)
/* Create or attach to the shared activity buffer */
BackendActivityBufferSize = mul_size(pgstat_track_activity_query_size,
- MaxBackends);
+ NumBackendStatSlots);
BackendActivityBuffer = (char *)
ShmemInitStruct("Backend Activity Buffer",
BackendActivityBufferSize,
@@ -2598,7 +2615,7 @@ CreateSharedBackendStatus(void)
/* Initialize st_activity pointers. */
buffer = BackendActivityBuffer;
- for (i = 0; i < MaxBackends; i++)
+ for (i = 0; i < NumBackendStatSlots; i++)
{
BackendStatusArray[i].st_activity = buffer;
buffer += pgstat_track_activity_query_size;
@@ -2607,7 +2624,7 @@ CreateSharedBackendStatus(void)
#ifdef USE_SSL
/* Create or attach to the shared SSL status buffer */
- size = mul_size(sizeof(PgBackendSSLStatus), MaxBackends);
+ size = mul_size(sizeof(PgBackendSSLStatus), NumBackendStatSlots);
BackendSslStatusBuffer = (PgBackendSSLStatus *)
ShmemInitStruct("Backend SSL Status Buffer", size, &found);
@@ -2619,7 +2636,7 @@ CreateSharedBackendStatus(void)
/* Initialize st_sslstatus pointers. */
ptr = BackendSslStatusBuffer;
- for (i = 0; i < MaxBackends; i++)
+ for (i = 0; i < NumBackendStatSlots; i++)
{
BackendStatusArray[i].st_sslstatus = ptr;
ptr++;
@@ -2633,7 +2650,8 @@ CreateSharedBackendStatus(void)
* pgstat_initialize() -
*
* Initialize pgstats state, and set up our on-proc-exit hook.
- * Called from InitPostgres. MyBackendId must be set,
+ * Called from InitPostgres and AuxiliaryProcessMain. For auxiliary process,
+ * MyBackendId is invalid. Otherwise, MyBackendId must be set,
* but we must not have started any transaction yet (since the
* exit hook must run after the last transaction exit).
* NOTE: MyDatabaseId isn't set yet; so the shutdown hook has to be careful.
@@ -2643,8 +2661,26 @@ void
pgstat_initialize(void)
{
/* Initialize MyBEEntry */
- Assert(MyBackendId >= 1 && MyBackendId <= MaxBackends);
- MyBEEntry = &BackendStatusArray[MyBackendId - 1];
+ if (MyBackendId != InvalidBackendId)
+ {
+ Assert(MyBackendId >= 1 && MyBackendId <= MaxBackends);
+ MyBEEntry = &BackendStatusArray[MyBackendId - 1];
+ }
+ else
+ {
+ /* Must be an auxiliary process */
+ Assert(MyAuxProcType != NotAnAuxProcess);
+
+ /*
+ * Assign the MyBEEntry for an auxiliary process. Since it doesn't
+ * have a BackendId, the slot is statically allocated based on the
+ * auxiliary process type (MyAuxProcType). Backends use slots indexed
+ * in the range from 1 to MaxBackends (inclusive), so we use
+ * MaxBackends + AuxBackendType + 1 as the index of the slot for an
+ * auxiliary process.
+ */
+ MyBEEntry = &BackendStatusArray[MaxBackends + MyAuxProcType];
+ }
/* Set up a process-exit hook to clean up */
on_shmem_exit(pgstat_beshutdown_hook, 0);
@@ -2655,15 +2691,16 @@ pgstat_initialize(void)
*
* Initialize this backend's entry in the PgBackendStatus array.
* Called from InitPostgres.
- * MyDatabaseId, session userid, and application_name must be set
- * (hence, this cannot be combined with pgstat_initialize).
+ *
+ * Apart from auxiliary processes, MyBackendId, MyDatabaseId,
+ * session userid, and application_name must be set for a
+ * backend (hence, this cannot be combined with pgstat_initialize).
* ----------
*/
void
pgstat_bestart(void)
{
TimestampTz proc_start_timestamp;
- Oid userid;
SockAddr clientaddr;
volatile PgBackendStatus *beentry;
@@ -2678,7 +2715,6 @@ pgstat_bestart(void)
proc_start_timestamp = MyProcPort->SessionStartTime;
else
proc_start_timestamp = GetCurrentTimestamp();
- userid = GetSessionUserId();
/*
* We may not have a MyProcPort (eg, if this is the autovacuum process).
@@ -2697,6 +2733,66 @@ pgstat_bestart(void)
* cute.
*/
beentry = MyBEEntry;
+
+ /* pgstats state must be initialized from pgstat_initialize() */
+ Assert(beentry != NULL);
+
+ if (MyBackendId != InvalidBackendId)
+ {
+ if (IsAutoVacuumLauncherProcess())
+ {
+ /* Autovacuum Launcher */
+ beentry->st_backendType = B_AUTOVAC_LAUNCHER;
+ }
+ else if (IsAutoVacuumWorkerProcess())
+ {
+ /* Autovacuum Worker */
+ beentry->st_backendType = B_AUTOVAC_WORKER;
+ }
+ else if (am_walsender)
+ {
+ /* Wal sender */
+ beentry->st_backendType = B_WAL_SENDER;
+ }
+ else if (IsBackgroundWorker)
+ {
+ /* bgworker */
+ beentry->st_backendType = B_BG_WORKER;
+ }
+ else
+ {
+ /* client-backend */
+ beentry->st_backendType = B_BACKEND;
+ }
+ }
+ else
+ {
+ /* Must be an auxiliary process */
+ Assert(MyAuxProcType != NotAnAuxProcess);
+ switch (MyAuxProcType)
+ {
+ case StartupProcess:
+ beentry->st_backendType = B_STARTUP;
+ break;
+ case BgWriterProcess:
+ beentry->st_backendType = B_BG_WRITER;
+ break;
+ case CheckpointerProcess:
+ beentry->st_backendType = B_CHECKPOINTER;
+ break;
+ case WalWriterProcess:
+ beentry->st_backendType = B_WAL_WRITER;
+ break;
+ case WalReceiverProcess:
+ beentry->st_backendType = B_WAL_RECEIVER;
+ break;
+ default:
+ elog(FATAL, "unrecognized process type: %d",
+ (int) MyAuxProcType);
+ proc_exit(1);
+ }
+ }
+
do
{
pgstat_increment_changecount_before(beentry);
@@ -2708,7 +2804,15 @@ pgstat_bestart(void)
beentry->st_state_start_timestamp = 0;
beentry->st_xact_start_timestamp = 0;
beentry->st_databaseid = MyDatabaseId;
- beentry->st_userid = userid;
+
+ /* We have userid for client-backends, wal-sender and bgworker processes */
+ if (beentry->st_backendType == B_BACKEND
+ || beentry->st_backendType == B_WAL_SENDER
+ || beentry->st_backendType == B_BG_WORKER)
+ beentry->st_userid = GetSessionUserId();
+ else
+ beentry->st_userid = InvalidOid;
+
beentry->st_clientaddr = clientaddr;
if (MyProcPort && MyProcPort->remote_hostname)
strlcpy(beentry->st_clienthostname, MyProcPort->remote_hostname,
@@ -3046,24 +3150,24 @@ pgstat_read_current_status(void)
localtable = (LocalPgBackendStatus *)
MemoryContextAlloc(pgStatLocalContext,
- sizeof(LocalPgBackendStatus) * MaxBackends);
+ sizeof(LocalPgBackendStatus) * NumBackendStatSlots);
localappname = (char *)
MemoryContextAlloc(pgStatLocalContext,
- NAMEDATALEN * MaxBackends);
+ NAMEDATALEN * NumBackendStatSlots);
localactivity = (char *)
MemoryContextAlloc(pgStatLocalContext,
- pgstat_track_activity_query_size * MaxBackends);
+ pgstat_track_activity_query_size * NumBackendStatSlots);
#ifdef USE_SSL
localsslstatus = (PgBackendSSLStatus *)
MemoryContextAlloc(pgStatLocalContext,
- sizeof(PgBackendSSLStatus) * MaxBackends);
+ sizeof(PgBackendSSLStatus) * NumBackendStatSlots);
#endif
localNumBackends = 0;
beentry = BackendStatusArray;
localentry = localtable;
- for (i = 1; i <= MaxBackends; i++)
+ for (i = 1; i <= NumBackendStatSlots; i++)
{
/*
* Follow the protocol of retrying if st_changecount changes while we
@@ -3829,7 +3933,47 @@ pgstat_get_crashed_backend_activity(int pid, char *buffer, int buflen)
return NULL;
}
+const char *
+pgstat_get_backend_desc(BackendType backendType)
+{
+ const char *backendDesc = "unknown process type";
+
+ switch (backendType)
+ {
+ case B_AUTOVAC_LAUNCHER:
+ backendDesc = "autovacuum launcher";
+ break;
+ case B_AUTOVAC_WORKER:
+ backendDesc = "autovacuum worker";
+ break;
+ case B_BACKEND:
+ backendDesc = "client backend";
+ break;
+ case B_BG_WORKER:
+ backendDesc = "background worker";
+ break;
+ case B_BG_WRITER:
+ backendDesc = "background writer";
+ break;
+ case B_CHECKPOINTER:
+ backendDesc = "checkpointer";
+ break;
+ case B_STARTUP:
+ backendDesc = "startup";
+ break;
+ case B_WAL_RECEIVER:
+ backendDesc = "walreceiver";
+ break;
+ case B_WAL_SENDER:
+ backendDesc = "walsender";
+ break;
+ case B_WAL_WRITER:
+ backendDesc = "walwriter";
+ break;
+ }
+ return backendDesc;
+}
/* ------------------------------------------------------------
* Local support functions follow
* ------------------------------------------------------------