Show more processes in pg_stat_activity.

Previously, auxiliary processes and background workers not connected
to a database (such as the logical replication launcher) weren't
shown.  Include them, so that we can see the associated wait state
information.  Add a new column to identify the processes type, so that
people can filter them out easily using SQL if they wish.

Before this patch was written, there was discussion about whether we
should expose this information in a separate view, so as to avoid
contaminating pg_stat_activity with things people might not want to
see.  But putting everything in pg_stat_activity was a more popular
choice, so that's what the patch does.

Kuntal Ghosh, reviewed by Amit Langote and Michael Paquier.  Some
revisions and bug fixes by me.

Discussion: http://postgr.es/m/CA+TgmoYES5nhkEGw9nZXU8_FhA8XEm8NTm3-SO+3ML1B81Hkww@mail.gmail.com
This commit is contained in:
Robert Haas 2017-03-26 22:02:22 -04:00
parent 2f0903ea19
commit fc70a4b0df
14 changed files with 305 additions and 53 deletions

View File

@ -620,8 +620,8 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser
<row>
<entry><structfield>backend_start</></entry>
<entry><type>timestamp with time zone</></entry>
<entry>Time when this process was started, i.e., when the
client connected to the server
<entry>Time when this process was started. For client backends,
this is the time the client connected to the server.
</entry>
</row>
<row>
@ -797,6 +797,17 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser
<xref linkend="guc-track-activity-query-size">.
</entry>
</row>
<row>
<entry><structfield>backend_type</structfield></entry>
<entry><type>text</type></entry>
<entry>Type of current backend. Possible types are
<literal>autovacuum launcher</>, <literal>autovacuum worker</>,
<literal>background worker</>, <literal>background writer</>,
<literal>client backend</>, <literal>checkpointer</>,
<literal>startup</>, <literal>walreceiver</>,
<literal>walsender</> and <literal>walwriter</>.
</entry>
</row>
</tbody>
</tgroup>
</table>

View File

@ -387,6 +387,10 @@ AuxiliaryProcessMain(int argc, char *argv[])
/* finish setting up bufmgr.c */
InitBufferPoolBackend();
/* Initialize backend status information */
pgstat_initialize();
pgstat_bestart();
/* register a before-shutdown callback for LWLock cleanup */
before_shmem_exit(ShutdownAuxiliaryProcess, 0);
}

View File

@ -716,7 +716,8 @@ CREATE VIEW pg_stat_activity AS
S.state,
S.backend_xid,
s.backend_xmin,
S.query
S.query,
S.backend_type
FROM pg_stat_get_activity(NULL) AS S
LEFT JOIN pg_database AS D ON (S.datid = D.oid)
LEFT JOIN pg_authid AS U ON (S.usesysid = U.oid);

View File

@ -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"
@ -102,6 +103,18 @@
#define PGSTAT_FUNCTION_HASH_SIZE 512
/* ----------
* 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
* ------------------------------------------------------------

View File

@ -25,6 +25,7 @@
#include "access/xlog.h"
#include "libpq/pqsignal.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "postmaster/startup.h"
#include "storage/ipc.h"
#include "storage/latch.h"

View File

@ -2011,8 +2011,8 @@ WalSndLoop(WalSndSendDataCallback send_data)
last_reply_timestamp = GetCurrentTimestamp();
waiting_for_ping_response = false;
/* Report to pgstat that this process is a WAL sender */
pgstat_report_activity(STATE_RUNNING, "walsender");
/* Report to pgstat that this process is running */
pgstat_report_activity(STATE_RUNNING, NULL);
/*
* Loop until we reach the end of this timeline or the client requests to

View File

@ -941,6 +941,33 @@ AuxiliaryProcKill(int code, Datum arg)
SpinLockRelease(ProcStructLock);
}
/*
* AuxiliaryPidGetProc -- get PGPROC for an auxiliary process
* given its PID
*
* Returns NULL if not found.
*/
PGPROC *
AuxiliaryPidGetProc(int pid)
{
PGPROC *result = NULL;
int index;
if (pid == 0) /* never match dummy PGPROCs */
return NULL;
for (index = 0; index < NUM_AUXILIARY_PROCS; index++)
{
PGPROC *proc = &AuxiliaryProcs[index];
if (proc->pid == pid)
{
result = proc;
break;
}
}
return result;
}
/*
* ProcQueue package: routines for putting processes to sleep

View File

@ -20,6 +20,7 @@
#include "funcapi.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "postmaster/postmaster.h"
#include "storage/proc.h"
#include "storage/procarray.h"
#include "utils/acl.h"
@ -538,7 +539,7 @@ pg_stat_get_progress_info(PG_FUNCTION_ARGS)
Datum
pg_stat_get_activity(PG_FUNCTION_ARGS)
{
#define PG_STAT_GET_ACTIVITY_COLS 23
#define PG_STAT_GET_ACTIVITY_COLS 24
int num_backends = pgstat_fetch_stat_numbackends();
int curr_backend;
int pid = PG_ARGISNULL(0) ? -1 : PG_GETARG_INT32(0);
@ -582,8 +583,8 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
LocalPgBackendStatus *local_beentry;
PgBackendStatus *beentry;
PGPROC *proc;
const char *wait_event_type;
const char *wait_event;
const char *wait_event_type = NULL;
const char *wait_event = NULL;
MemSet(values, 0, sizeof(values));
MemSet(nulls, 0, sizeof(nulls));
@ -615,9 +616,18 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
continue;
/* Values available to all callers */
values[0] = ObjectIdGetDatum(beentry->st_databaseid);
if (beentry->st_databaseid != InvalidOid)
values[0] = ObjectIdGetDatum(beentry->st_databaseid);
else
nulls[0] = true;
values[1] = Int32GetDatum(beentry->st_procpid);
values[2] = ObjectIdGetDatum(beentry->st_userid);
if (beentry->st_userid != InvalidOid)
values[2] = ObjectIdGetDatum(beentry->st_userid);
else
nulls[2] = true;
if (beentry->st_appname)
values[3] = CStringGetTextDatum(beentry->st_appname);
else
@ -635,17 +645,17 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
if (beentry->st_ssl)
{
values[17] = BoolGetDatum(true); /* ssl */
values[18] = CStringGetTextDatum(beentry->st_sslstatus->ssl_version);
values[19] = CStringGetTextDatum(beentry->st_sslstatus->ssl_cipher);
values[20] = Int32GetDatum(beentry->st_sslstatus->ssl_bits);
values[21] = BoolGetDatum(beentry->st_sslstatus->ssl_compression);
values[22] = CStringGetTextDatum(beentry->st_sslstatus->ssl_clientdn);
values[18] = BoolGetDatum(true); /* ssl */
values[19] = CStringGetTextDatum(beentry->st_sslstatus->ssl_version);
values[20] = CStringGetTextDatum(beentry->st_sslstatus->ssl_cipher);
values[21] = Int32GetDatum(beentry->st_sslstatus->ssl_bits);
values[22] = BoolGetDatum(beentry->st_sslstatus->ssl_compression);
values[23] = CStringGetTextDatum(beentry->st_sslstatus->ssl_clientdn);
}
else
{
values[17] = BoolGetDatum(false); /* ssl */
nulls[18] = nulls[19] = nulls[20] = nulls[21] = nulls[22] = true;
values[18] = BoolGetDatum(false); /* ssl */
nulls[19] = nulls[20] = nulls[21] = nulls[22] = nulls[23] = true;
}
/* Values only available to role member */
@ -690,10 +700,24 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
wait_event = pgstat_get_wait_event(raw_wait_event);
}
else
else if (beentry->st_backendType != B_BACKEND)
{
wait_event_type = NULL;
wait_event = NULL;
/*
* For an auxiliary process, retrieve process info from
* AuxiliaryProcs stored in shared-memory.
*/
proc = AuxiliaryPidGetProc(beentry->st_procpid);
if (proc != NULL)
{
uint32 raw_wait_event;
raw_wait_event =
UINT32_ACCESS_ONCE(proc->wait_event_info);
wait_event_type =
pgstat_get_wait_event_type(raw_wait_event);
wait_event = pgstat_get_wait_event(raw_wait_event);
}
}
if (wait_event_type)
@ -793,6 +817,9 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
nulls[14] = true;
}
}
/* Add backend type */
values[17] =
CStringGetTextDatum(pgstat_get_backend_desc(beentry->st_backendType));
}
else
{
@ -808,6 +835,7 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
nulls[12] = true;
nulls[13] = true;
nulls[14] = true;
nulls[17] = true;
}
tuplestore_putvalues(tupstore, tupdesc, values, nulls);

View File

@ -665,7 +665,12 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
/* The autovacuum launcher is done here */
if (IsAutoVacuumLauncherProcess())
{
/* report this backend in the PgBackendStatus array */
pgstat_bestart();
return;
}
/*
* Start a new transaction here before first access to db, and get a
@ -874,7 +879,10 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
* transaction we started before returning.
*/
if (!bootstrap)
{
pgstat_bestart();
CommitTransactionCommand();
}
return;
}

View File

@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 201703242
#define CATALOG_VERSION_NO 201703261
#endif

View File

@ -2811,7 +2811,7 @@ DATA(insert OID = 3057 ( pg_stat_get_autoanalyze_count PGNSP PGUID 12 1 0 0 0 f
DESCR("statistics: number of auto analyzes for a table");
DATA(insert OID = 1936 ( pg_stat_get_backend_idset PGNSP PGUID 12 1 100 0 0 f f f f t t s r 0 0 23 "" _null_ _null_ _null_ _null_ _null_ pg_stat_get_backend_idset _null_ _null_ _null_ ));
DESCR("statistics: currently active backend IDs");
DATA(insert OID = 2022 ( pg_stat_get_activity PGNSP PGUID 12 1 100 0 0 f f f f f t s r 1 0 2249 "23" "{23,26,23,26,25,25,25,25,25,1184,1184,1184,1184,869,25,23,28,28,16,25,25,23,16,25}" "{i,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}" "{pid,datid,pid,usesysid,application_name,state,query,wait_event_type,wait_event,xact_start,query_start,backend_start,state_change,client_addr,client_hostname,client_port,backend_xid,backend_xmin,ssl,sslversion,sslcipher,sslbits,sslcompression,sslclientdn}" _null_ _null_ pg_stat_get_activity _null_ _null_ _null_ ));
DATA(insert OID = 2022 ( pg_stat_get_activity PGNSP PGUID 12 1 100 0 0 f f f f f t s r 1 0 2249 "23" "{23,26,23,26,25,25,25,25,25,1184,1184,1184,1184,869,25,23,28,28,25,16,25,25,23,16,25}" "{i,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}" "{pid,datid,pid,usesysid,application_name,state,query,wait_event_type,wait_event,xact_start,query_start,backend_start,state_change,client_addr,client_hostname,client_port,backend_xid,backend_xmin,backend_type,ssl,sslversion,sslcipher,sslbits,sslcompression,sslclientdn}" _null_ _null_ pg_stat_get_activity _null_ _null_ _null_ ));
DESCR("statistics: information about currently active backends");
DATA(insert OID = 3318 ( pg_stat_get_progress_info PGNSP PGUID 12 1 100 0 0 f f f f t t s r 1 0 2249 "25" "{25,23,26,26,20,20,20,20,20,20,20,20,20,20}" "{i,o,o,o,o,o,o,o,o,o,o,o,o,o}" "{cmdtype,pid,datid,relid,param1,param2,param3,param4,param5,param6,param7,param8,param9,param10}" _null_ _null_ pg_stat_get_progress_info _null_ _null_ _null_ ));
DESCR("statistics: information about progress of backends running maintenance command");

View File

@ -695,6 +695,25 @@ typedef struct PgStat_GlobalStats
} PgStat_GlobalStats;
/* ----------
* Backend types
* ----------
*/
typedef enum BackendType
{
B_AUTOVAC_LAUNCHER,
B_AUTOVAC_WORKER,
B_BACKEND,
B_BG_WORKER,
B_BG_WRITER,
B_CHECKPOINTER,
B_STARTUP,
B_WAL_RECEIVER,
B_WAL_SENDER,
B_WAL_WRITER
} BackendType;
/* ----------
* Backend states
* ----------
@ -927,6 +946,9 @@ typedef struct PgBackendSSLStatus
* showing its current activity. (The structs are allocated according to
* BackendId, but that is not critical.) Note that the collector process
* has no involvement in, or even access to, these structs.
*
* Each auxiliary process also maintains a PgBackendStatus struct in shared
* memory.
* ----------
*/
typedef struct PgBackendStatus
@ -951,6 +973,9 @@ typedef struct PgBackendStatus
/* The entry is valid iff st_procpid > 0, unused if st_procpid == 0 */
int st_procpid;
/* Type of backends */
BackendType st_backendType;
/* Times when current backend, transaction, and activity started */
TimestampTz st_proc_start_timestamp;
TimestampTz st_xact_start_timestamp;
@ -1149,6 +1174,7 @@ extern const char *pgstat_get_wait_event_type(uint32 wait_event_info);
extern const char *pgstat_get_backend_current_activity(int pid, bool checkUser);
extern const char *pgstat_get_crashed_backend_activity(int pid, char *buffer,
int buflen);
extern const char *pgstat_get_backend_desc(BackendType backendType);
extern void pgstat_progress_start_command(ProgressCommandType cmdtype,
Oid relid);

View File

@ -272,7 +272,6 @@ extern PGPROC *PreparedXactProcs;
*/
#define NUM_AUXILIARY_PROCS 4
/* configurable options */
extern int DeadlockTimeout;
extern int StatementTimeout;
@ -309,6 +308,8 @@ extern void LockErrorCleanup(void);
extern void ProcWaitForSignal(uint32 wait_event_info);
extern void ProcSendSignal(int pid);
extern PGPROC *AuxiliaryPidGetProc(int pid);
extern void BecomeLockGroupLeader(void);
extern bool BecomeLockGroupMember(PGPROC *leader, int pid);

View File

@ -1727,8 +1727,9 @@ pg_stat_activity| SELECT s.datid,
s.state,
s.backend_xid,
s.backend_xmin,
s.query
FROM ((pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, ssl, sslversion, sslcipher, sslbits, sslcompression, sslclientdn)
s.query,
s.backend_type
FROM ((pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, sslcompression, sslclientdn)
LEFT JOIN pg_database d ON ((s.datid = d.oid)))
LEFT JOIN pg_authid u ON ((s.usesysid = u.oid)));
pg_stat_all_indexes| SELECT c.oid AS relid,
@ -1859,7 +1860,7 @@ pg_stat_replication| SELECT s.pid,
w.replay_lag,
w.sync_priority,
w.sync_state
FROM ((pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, ssl, sslversion, sslcipher, sslbits, sslcompression, sslclientdn)
FROM ((pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, sslcompression, sslclientdn)
JOIN pg_stat_get_wal_senders() w(pid, state, sent_location, write_location, flush_location, replay_location, write_lag, flush_lag, replay_lag, sync_priority, sync_state) ON ((s.pid = w.pid)))
LEFT JOIN pg_authid u ON ((s.usesysid = u.oid)));
pg_stat_ssl| SELECT s.pid,
@ -1869,7 +1870,7 @@ pg_stat_ssl| SELECT s.pid,
s.sslbits AS bits,
s.sslcompression AS compression,
s.sslclientdn AS clientdn
FROM pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, ssl, sslversion, sslcipher, sslbits, sslcompression, sslclientdn);
FROM pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, sslcompression, sslclientdn);
pg_stat_subscription| SELECT su.oid AS subid,
su.subname,
st.pid,