PostgreSQL Source Code git master
backend_status.c File Reference
#include "postgres.h"
#include "access/xact.h"
#include "libpq/libpq-be.h"
#include "miscadmin.h"
#include "pg_trace.h"
#include "pgstat.h"
#include "storage/ipc.h"
#include "storage/proc.h"
#include "storage/procarray.h"
#include "utils/ascii.h"
#include "utils/guc.h"
#include "utils/memutils.h"
Include dependency graph for backend_status.c:

Go to the source code of this file.

Macros

#define NumBackendStatSlots   (MaxBackends + NUM_AUXILIARY_PROCS)
 

Functions

static void pgstat_beshutdown_hook (int code, Datum arg)
 
static void pgstat_read_current_status (void)
 
static void pgstat_setup_backend_status_context (void)
 
Size BackendStatusShmemSize (void)
 
void BackendStatusShmemInit (void)
 
void pgstat_beinit (void)
 
void pgstat_bestart_initial (void)
 
void pgstat_bestart_security (void)
 
void pgstat_bestart_final (void)
 
void pgstat_clear_backend_activity_snapshot (void)
 
void pgstat_report_activity (BackendState state, const char *cmd_str)
 
void pgstat_report_query_id (uint64 query_id, bool force)
 
void pgstat_report_plan_id (uint64 plan_id, bool force)
 
void pgstat_report_appname (const char *appname)
 
void pgstat_report_xact_timestamp (TimestampTz tstamp)
 
const char * pgstat_get_backend_current_activity (int pid, bool checkUser)
 
const char * pgstat_get_crashed_backend_activity (int pid, char *buffer, int buflen)
 
uint64 pgstat_get_my_query_id (void)
 
uint64 pgstat_get_my_plan_id (void)
 
BackendType pgstat_get_backend_type_by_proc_number (ProcNumber procNumber)
 
static int cmp_lbestatus (const void *a, const void *b)
 
PgBackendStatuspgstat_get_beentry_by_proc_number (ProcNumber procNumber)
 
LocalPgBackendStatuspgstat_get_local_beentry_by_proc_number (ProcNumber procNumber)
 
LocalPgBackendStatuspgstat_get_local_beentry_by_index (int idx)
 
int pgstat_fetch_stat_numbackends (void)
 
char * pgstat_clip_activity (const char *raw_activity)
 

Variables

bool pgstat_track_activities = false
 
int pgstat_track_activity_query_size = 1024
 
PgBackendStatusMyBEEntry = NULL
 
static PgBackendStatusBackendStatusArray = NULL
 
static char * BackendAppnameBuffer = NULL
 
static char * BackendClientHostnameBuffer = NULL
 
static char * BackendActivityBuffer = NULL
 
static Size BackendActivityBufferSize = 0
 
static LocalPgBackendStatuslocalBackendStatusTable = NULL
 
static int localNumBackends = 0
 
static MemoryContext backendStatusSnapContext
 

Macro Definition Documentation

◆ NumBackendStatSlots

#define NumBackendStatSlots   (MaxBackends + NUM_AUXILIARY_PROCS)

Definition at line 35 of file backend_status.c.

Function Documentation

◆ BackendStatusShmemInit()

void BackendStatusShmemInit ( void  )

Definition at line 114 of file backend_status.c.

115{
116 Size size;
117 bool found;
118 int i;
119 char *buffer;
120
121 /* Create or attach to the shared array */
124 ShmemInitStruct("Backend Status Array", size, &found);
125
126 if (!found)
127 {
128 /*
129 * We're the first - initialize.
130 */
131 MemSet(BackendStatusArray, 0, size);
132 }
133
134 /* Create or attach to the shared appname buffer */
136 BackendAppnameBuffer = (char *)
137 ShmemInitStruct("Backend Application Name Buffer", size, &found);
138
139 if (!found)
140 {
142
143 /* Initialize st_appname pointers. */
144 buffer = BackendAppnameBuffer;
145 for (i = 0; i < NumBackendStatSlots; i++)
146 {
148 buffer += NAMEDATALEN;
149 }
150 }
151
152 /* Create or attach to the shared client hostname buffer */
155 ShmemInitStruct("Backend Client Host Name Buffer", size, &found);
156
157 if (!found)
158 {
160
161 /* Initialize st_clienthostname pointers. */
163 for (i = 0; i < NumBackendStatSlots; i++)
164 {
166 buffer += NAMEDATALEN;
167 }
168 }
169
170 /* Create or attach to the shared activity buffer */
173 BackendActivityBuffer = (char *)
174 ShmemInitStruct("Backend Activity Buffer",
176 &found);
177
178 if (!found)
179 {
181
182 /* Initialize st_activity pointers. */
183 buffer = BackendActivityBuffer;
184 for (i = 0; i < NumBackendStatSlots; i++)
185 {
188 }
189 }
190
191#ifdef USE_SSL
192 /* Create or attach to the shared SSL status buffer */
194 BackendSslStatusBuffer = (PgBackendSSLStatus *)
195 ShmemInitStruct("Backend SSL Status Buffer", size, &found);
196
197 if (!found)
198 {
200
201 MemSet(BackendSslStatusBuffer, 0, size);
202
203 /* Initialize st_sslstatus pointers. */
204 ptr = BackendSslStatusBuffer;
205 for (i = 0; i < NumBackendStatSlots; i++)
206 {
208 ptr++;
209 }
210 }
211#endif
212
213#ifdef ENABLE_GSS
214 /* Create or attach to the shared GSSAPI status buffer */
216 BackendGssStatusBuffer = (PgBackendGSSStatus *)
217 ShmemInitStruct("Backend GSS Status Buffer", size, &found);
218
219 if (!found)
220 {
222
223 MemSet(BackendGssStatusBuffer, 0, size);
224
225 /* Initialize st_gssstatus pointers. */
226 ptr = BackendGssStatusBuffer;
227 for (i = 0; i < NumBackendStatSlots; i++)
228 {
230 ptr++;
231 }
232 }
233#endif
234}
#define NumBackendStatSlots
static char * BackendClientHostnameBuffer
static char * BackendActivityBuffer
static char * BackendAppnameBuffer
static PgBackendStatus * BackendStatusArray
static Size BackendActivityBufferSize
int pgstat_track_activity_query_size
#define MemSet(start, val, len)
Definition: c.h:991
size_t Size
Definition: c.h:576
int i
Definition: isn.c:74
#define NAMEDATALEN
Size mul_size(Size s1, Size s2)
Definition: shmem.c:505
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
Definition: shmem.c:382
PgBackendGSSStatus * st_gssstatus
PgBackendSSLStatus * st_sslstatus
char * st_clienthostname

References BackendActivityBuffer, BackendActivityBufferSize, BackendAppnameBuffer, BackendClientHostnameBuffer, BackendStatusArray, i, MemSet, mul_size(), NAMEDATALEN, NumBackendStatSlots, pgstat_track_activity_query_size, ShmemInitStruct(), PgBackendStatus::st_activity_raw, PgBackendStatus::st_appname, PgBackendStatus::st_clienthostname, PgBackendStatus::st_gssstatus, and PgBackendStatus::st_sslstatus.

Referenced by CreateOrAttachShmemStructs().

◆ BackendStatusShmemSize()

Size BackendStatusShmemSize ( void  )

Definition at line 81 of file backend_status.c.

82{
83 Size size;
84
85 /* BackendStatusArray: */
87 /* BackendAppnameBuffer: */
88 size = add_size(size,
90 /* BackendClientHostnameBuffer: */
91 size = add_size(size,
93 /* BackendActivityBuffer: */
94 size = add_size(size,
96#ifdef USE_SSL
97 /* BackendSslStatusBuffer: */
98 size = add_size(size,
100#endif
101#ifdef ENABLE_GSS
102 /* BackendGssStatusBuffer: */
103 size = add_size(size,
105#endif
106 return size;
107}
Size add_size(Size s1, Size s2)
Definition: shmem.c:488

References add_size(), mul_size(), NAMEDATALEN, NumBackendStatSlots, and pgstat_track_activity_query_size.

Referenced by CalculateShmemSize().

◆ cmp_lbestatus()

static int cmp_lbestatus ( const void *  a,
const void *  b 
)
static

Definition at line 1200 of file backend_status.c.

1201{
1202 const LocalPgBackendStatus *lbestatus1 = (const LocalPgBackendStatus *) a;
1203 const LocalPgBackendStatus *lbestatus2 = (const LocalPgBackendStatus *) b;
1204
1205 return lbestatus1->proc_number - lbestatus2->proc_number;
1206}
int b
Definition: isn.c:71
int a
Definition: isn.c:70

References a, b, and LocalPgBackendStatus::proc_number.

Referenced by pgstat_get_local_beentry_by_proc_number().

◆ pgstat_beinit()

void pgstat_beinit ( void  )

Definition at line 245 of file backend_status.c.

246{
247 /* Initialize MyBEEntry */
251
252 /* Set up a process-exit hook to clean up */
254}
PgBackendStatus * MyBEEntry
static void pgstat_beshutdown_hook(int code, Datum arg)
ProcNumber MyProcNumber
Definition: globals.c:89
Assert(PointerIsAligned(start, uint64))
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:365
#define INVALID_PROC_NUMBER
Definition: procnumber.h:26

References Assert(), BackendStatusArray, INVALID_PROC_NUMBER, MyBEEntry, MyProcNumber, NumBackendStatSlots, on_shmem_exit(), and pgstat_beshutdown_hook().

Referenced by AuxiliaryProcessMainCommon(), and InitPostgres().

◆ pgstat_beshutdown_hook()

static void pgstat_beshutdown_hook ( int  code,
Datum  arg 
)
static

Definition at line 509 of file backend_status.c.

510{
511 volatile PgBackendStatus *beentry = MyBEEntry;
512
513 /*
514 * Clear my status entry, following the protocol of bumping st_changecount
515 * before and after. We use a volatile pointer here to ensure the
516 * compiler doesn't try to get cute.
517 */
519
520 beentry->st_procpid = 0; /* mark invalid */
521
523
524 /* so that functions can check if backend_status.c is up via MyBEEntry */
525 MyBEEntry = NULL;
526}
#define PGSTAT_END_WRITE_ACTIVITY(beentry)
#define PGSTAT_BEGIN_WRITE_ACTIVITY(beentry)

References MyBEEntry, PGSTAT_BEGIN_WRITE_ACTIVITY, PGSTAT_END_WRITE_ACTIVITY, and PgBackendStatus::st_procpid.

Referenced by pgstat_beinit().

◆ pgstat_bestart_final()

void pgstat_bestart_final ( void  )

Definition at line 467 of file backend_status.c.

468{
469 volatile PgBackendStatus *beentry = MyBEEntry;
470 Oid userid;
471
472 /* pgstats state must be initialized from pgstat_beinit() */
473 Assert(beentry != NULL);
474
475 /* We have userid for client-backends, wal-sender and bgworker processes */
479 userid = GetSessionUserId();
480 else
481 userid = InvalidOid;
482
483 /*
484 * Update my status entry, following the protocol of bumping
485 * st_changecount before and after. We use a volatile pointer here to
486 * ensure the compiler doesn't try to get cute.
487 */
489
490 beentry->st_databaseid = MyDatabaseId;
491 beentry->st_userid = userid;
492 beentry->st_state = STATE_UNDEFINED;
493
495
496 /* Create the backend statistics entry */
499
500 /* Update app name to current GUC setting */
503}
void pgstat_report_appname(const char *appname)
@ STATE_UNDEFINED
Oid MyDatabaseId
Definition: globals.c:93
char * application_name
Definition: guc_tables.c:548
@ B_WAL_SENDER
Definition: miscadmin.h:346
@ B_BG_WORKER
Definition: miscadmin.h:345
@ B_BACKEND
Definition: miscadmin.h:341
Oid GetSessionUserId(void)
Definition: miscinit.c:559
BackendType MyBackendType
Definition: miscinit.c:64
void pgstat_create_backend(ProcNumber procnum)
bool pgstat_tracks_backend_bktype(BackendType bktype)
#define InvalidOid
Definition: postgres_ext.h:35
unsigned int Oid
Definition: postgres_ext.h:30
BackendState st_state

References application_name, Assert(), B_BACKEND, B_BG_WORKER, B_WAL_SENDER, GetSessionUserId(), InvalidOid, MyBackendType, MyBEEntry, MyDatabaseId, MyProcNumber, PGSTAT_BEGIN_WRITE_ACTIVITY, pgstat_create_backend(), PGSTAT_END_WRITE_ACTIVITY, pgstat_report_appname(), pgstat_tracks_backend_bktype(), PgBackendStatus::st_databaseid, PgBackendStatus::st_state, PgBackendStatus::st_userid, and STATE_UNDEFINED.

Referenced by AuxiliaryProcessMainCommon(), and InitPostgres().

◆ pgstat_bestart_initial()

void pgstat_bestart_initial ( void  )

Definition at line 270 of file backend_status.c.

271{
272 volatile PgBackendStatus *vbeentry = MyBEEntry;
273 PgBackendStatus lbeentry;
274
275 /* pgstats state must be initialized from pgstat_beinit() */
276 Assert(vbeentry != NULL);
277
278 /*
279 * To minimize the time spent modifying the PgBackendStatus entry, and
280 * avoid risk of errors inside the critical section, we first copy the
281 * shared-memory struct to a local variable, then modify the data in the
282 * local variable, then copy the local variable back to shared memory.
283 * Only the last step has to be inside the critical section.
284 *
285 * Most of the data we copy from shared memory is just going to be
286 * overwritten, but the struct's not so large that it's worth the
287 * maintenance hassle to copy only the needful fields.
288 */
289 memcpy(&lbeentry,
290 unvolatize(PgBackendStatus *, vbeentry),
291 sizeof(PgBackendStatus));
292
293 /*
294 * Now fill in all the fields of lbeentry, except for strings that are
295 * out-of-line data. Those have to be handled separately, below.
296 */
297 lbeentry.st_procpid = MyProcPid;
298 lbeentry.st_backendType = MyBackendType;
300 lbeentry.st_activity_start_timestamp = 0;
301 lbeentry.st_state_start_timestamp = 0;
302 lbeentry.st_xact_start_timestamp = 0;
303 lbeentry.st_databaseid = InvalidOid;
304 lbeentry.st_userid = InvalidOid;
305
306 /*
307 * We may not have a MyProcPort (eg, if this is the autovacuum process).
308 * If so, use all-zeroes client address, which is dealt with specially in
309 * pg_stat_get_backend_client_addr and pg_stat_get_backend_client_port.
310 */
311 if (MyProcPort)
312 memcpy(&lbeentry.st_clientaddr, &MyProcPort->raddr,
313 sizeof(lbeentry.st_clientaddr));
314 else
315 MemSet(&lbeentry.st_clientaddr, 0, sizeof(lbeentry.st_clientaddr));
316
317 lbeentry.st_ssl = false;
318 lbeentry.st_gss = false;
319
320 lbeentry.st_state = STATE_STARTING;
323 lbeentry.st_query_id = UINT64CONST(0);
324 lbeentry.st_plan_id = UINT64CONST(0);
325
326 /*
327 * we don't zero st_progress_param here to save cycles; nobody should
328 * examine it until st_progress_command has been set to something other
329 * than PROGRESS_COMMAND_INVALID
330 */
331
332 /*
333 * We're ready to enter the critical section that fills the shared-memory
334 * status entry. We follow the protocol of bumping st_changecount before
335 * and after; and make sure it's even afterwards. We use a volatile
336 * pointer here to ensure the compiler doesn't try to get cute.
337 */
339
340 /* make sure we'll memcpy the same st_changecount back */
341 lbeentry.st_changecount = vbeentry->st_changecount;
342
343 memcpy(unvolatize(PgBackendStatus *, vbeentry),
344 &lbeentry,
345 sizeof(PgBackendStatus));
346
347 /*
348 * We can write the out-of-line strings and structs using the pointers
349 * that are in lbeentry; this saves some de-volatilizing messiness.
350 */
351 lbeentry.st_appname[0] = '\0';
355 else
356 lbeentry.st_clienthostname[0] = '\0';
357 lbeentry.st_activity_raw[0] = '\0';
358 /* Also make sure the last byte in each string area is always 0 */
359 lbeentry.st_appname[NAMEDATALEN - 1] = '\0';
360 lbeentry.st_clienthostname[NAMEDATALEN - 1] = '\0';
362
363 /* These structs can just start from zeroes each time */
364#ifdef USE_SSL
365 memset(lbeentry.st_sslstatus, 0, sizeof(PgBackendSSLStatus));
366#endif
367#ifdef ENABLE_GSS
368 memset(lbeentry.st_gssstatus, 0, sizeof(PgBackendGSSStatus));
369#endif
370
372}
@ PROGRESS_COMMAND_INVALID
@ STATE_STARTING
#define unvolatize(underlying_type, expr)
Definition: c.h:1218
#define UINT64CONST(x)
Definition: c.h:517
int MyProcPid
Definition: globals.c:46
TimestampTz MyStartTimestamp
Definition: globals.c:48
struct Port * MyProcPort
Definition: globals.c:50
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
BackendType st_backendType
TimestampTz st_state_start_timestamp
TimestampTz st_proc_start_timestamp
TimestampTz st_activity_start_timestamp
ProgressCommandType st_progress_command
SockAddr st_clientaddr
TimestampTz st_xact_start_timestamp
Oid st_progress_command_target
char * remote_hostname
Definition: libpq-be.h:142
SockAddr raddr
Definition: libpq-be.h:140

References Assert(), InvalidOid, MemSet, MyBackendType, MyBEEntry, MyProcPid, MyProcPort, MyStartTimestamp, NAMEDATALEN, PGSTAT_BEGIN_WRITE_ACTIVITY, PGSTAT_END_WRITE_ACTIVITY, pgstat_track_activity_query_size, PROGRESS_COMMAND_INVALID, Port::raddr, Port::remote_hostname, PgBackendStatus::st_activity_raw, PgBackendStatus::st_activity_start_timestamp, PgBackendStatus::st_appname, PgBackendStatus::st_backendType, PgBackendStatus::st_changecount, PgBackendStatus::st_clientaddr, PgBackendStatus::st_clienthostname, PgBackendStatus::st_databaseid, PgBackendStatus::st_gss, PgBackendStatus::st_gssstatus, PgBackendStatus::st_plan_id, PgBackendStatus::st_proc_start_timestamp, PgBackendStatus::st_procpid, PgBackendStatus::st_progress_command, PgBackendStatus::st_progress_command_target, PgBackendStatus::st_query_id, PgBackendStatus::st_ssl, PgBackendStatus::st_sslstatus, PgBackendStatus::st_state, PgBackendStatus::st_state_start_timestamp, PgBackendStatus::st_userid, PgBackendStatus::st_xact_start_timestamp, STATE_STARTING, strlcpy(), UINT64CONST, and unvolatize.

Referenced by AuxiliaryProcessMainCommon(), and InitPostgres().

◆ pgstat_bestart_security()

void pgstat_bestart_security ( void  )

Definition at line 385 of file backend_status.c.

386{
387 volatile PgBackendStatus *beentry = MyBEEntry;
388 bool ssl = false;
389 bool gss = false;
390#ifdef USE_SSL
391 PgBackendSSLStatus lsslstatus;
392 PgBackendSSLStatus *st_sslstatus;
393#endif
394#ifdef ENABLE_GSS
395 PgBackendGSSStatus lgssstatus;
396 PgBackendGSSStatus *st_gssstatus;
397#endif
398
399 /* pgstats state must be initialized from pgstat_beinit() */
400 Assert(beentry != NULL);
401 Assert(MyProcPort); /* otherwise there's no point */
402
403#ifdef USE_SSL
404 st_sslstatus = beentry->st_sslstatus;
405 memset(&lsslstatus, 0, sizeof(lsslstatus));
406
408 {
409 ssl = true;
416 }
417#endif
418
419#ifdef ENABLE_GSS
420 st_gssstatus = beentry->st_gssstatus;
421 memset(&lgssstatus, 0, sizeof(lgssstatus));
422
423 if (MyProcPort->gss != NULL)
424 {
425 const char *princ = be_gssapi_get_princ(MyProcPort);
426
427 gss = true;
431 if (princ)
432 strlcpy(lgssstatus.gss_princ, princ, NAMEDATALEN);
433 }
434#endif
435
436 /*
437 * Update my status entry, following the protocol of bumping
438 * st_changecount before and after. We use a volatile pointer here to
439 * ensure the compiler doesn't try to get cute.
440 */
442
443 beentry->st_ssl = ssl;
444 beentry->st_gss = gss;
445
446#ifdef USE_SSL
447 memcpy(st_sslstatus, &lsslstatus, sizeof(PgBackendSSLStatus));
448#endif
449#ifdef ENABLE_GSS
450 memcpy(st_gssstatus, &lgssstatus, sizeof(PgBackendGSSStatus));
451#endif
452
454}
bool be_gssapi_get_auth(Port *port)
bool be_gssapi_get_enc(Port *port)
const char * be_gssapi_get_princ(Port *port)
bool be_gssapi_get_delegation(Port *port)
const char * be_tls_get_version(Port *port)
int be_tls_get_cipher_bits(Port *port)
const char * be_tls_get_cipher(Port *port)
void be_tls_get_peer_serial(Port *port, char *ptr, size_t len)
void be_tls_get_peer_issuer_name(Port *port, char *ptr, size_t len)
void be_tls_get_peer_subject_name(Port *port, char *ptr, size_t len)
char gss_princ[NAMEDATALEN]
char ssl_version[NAMEDATALEN]
char ssl_cipher[NAMEDATALEN]
char ssl_client_dn[NAMEDATALEN]
char ssl_client_serial[NAMEDATALEN]
char ssl_issuer_dn[NAMEDATALEN]
bool ssl_in_use
Definition: libpq-be.h:211
void * gss
Definition: libpq-be.h:205

References Assert(), be_gssapi_get_auth(), be_gssapi_get_delegation(), be_gssapi_get_enc(), be_gssapi_get_princ(), be_tls_get_cipher(), be_tls_get_cipher_bits(), be_tls_get_peer_issuer_name(), be_tls_get_peer_serial(), be_tls_get_peer_subject_name(), be_tls_get_version(), Port::gss, PgBackendGSSStatus::gss_auth, PgBackendGSSStatus::gss_delegation, PgBackendGSSStatus::gss_enc, PgBackendGSSStatus::gss_princ, MyBEEntry, MyProcPort, NAMEDATALEN, PGSTAT_BEGIN_WRITE_ACTIVITY, PGSTAT_END_WRITE_ACTIVITY, PgBackendSSLStatus::ssl_bits, PgBackendSSLStatus::ssl_cipher, PgBackendSSLStatus::ssl_client_dn, PgBackendSSLStatus::ssl_client_serial, Port::ssl_in_use, PgBackendSSLStatus::ssl_issuer_dn, PgBackendSSLStatus::ssl_version, PgBackendStatus::st_gss, PgBackendStatus::st_gssstatus, PgBackendStatus::st_ssl, PgBackendStatus::st_sslstatus, and strlcpy().

Referenced by InitPostgres().

◆ pgstat_clear_backend_activity_snapshot()

void pgstat_clear_backend_activity_snapshot ( void  )

Definition at line 536 of file backend_status.c.

537{
538 /* Release memory, if any was allocated */
540 {
543 }
544
545 /* Reset variables */
548}
static LocalPgBackendStatus * localBackendStatusTable
static int localNumBackends
static MemoryContext backendStatusSnapContext
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:454

References backendStatusSnapContext, localBackendStatusTable, localNumBackends, and MemoryContextDelete().

Referenced by pgstat_clear_snapshot().

◆ pgstat_clip_activity()

char * pgstat_clip_activity ( const char *  raw_activity)

Definition at line 1315 of file backend_status.c.

1316{
1317 char *activity;
1318 int rawlen;
1319 int cliplen;
1320
1321 /*
1322 * Some callers, like pgstat_get_backend_current_activity(), do not
1323 * guarantee that the buffer isn't concurrently modified. We try to take
1324 * care that the buffer is always terminated by a NUL byte regardless, but
1325 * let's still be paranoid about the string's length. In those cases the
1326 * underlying buffer is guaranteed to be pgstat_track_activity_query_size
1327 * large.
1328 */
1329 activity = pnstrdup(raw_activity, pgstat_track_activity_query_size - 1);
1330
1331 /* now double-guaranteed to be NUL terminated */
1332 rawlen = strlen(activity);
1333
1334 /*
1335 * All supported server-encodings make it possible to determine the length
1336 * of a multi-byte character from its first byte (this is not the case for
1337 * client encodings, see GB18030). As st_activity is always stored using
1338 * server encoding, this allows us to perform multi-byte aware truncation,
1339 * even if the string earlier was truncated in the middle of a multi-byte
1340 * character.
1341 */
1342 cliplen = pg_mbcliplen(activity, rawlen,
1344
1345 activity[cliplen] = '\0';
1346
1347 return activity;
1348}
int pg_mbcliplen(const char *mbstr, int len, int limit)
Definition: mbutils.c:1083
static int cliplen(const char *str, int len, int limit)
Definition: mbutils.c:1150
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1710

References cliplen(), pg_mbcliplen(), pgstat_track_activity_query_size, and pnstrdup().

Referenced by pg_stat_get_activity(), pg_stat_get_backend_activity(), and pgstat_get_backend_current_activity().

◆ pgstat_fetch_stat_numbackends()

int pgstat_fetch_stat_numbackends ( void  )

Definition at line 1299 of file backend_status.c.

1300{
1302
1303 return localNumBackends;
1304}
static void pgstat_read_current_status(void)

References localNumBackends, and pgstat_read_current_status().

Referenced by pg_stat_get_activity(), pg_stat_get_backend_idset(), pg_stat_get_db_numbackends(), and pg_stat_get_progress_info().

◆ pgstat_get_backend_current_activity()

const char * pgstat_get_backend_current_activity ( int  pid,
bool  checkUser 
)

Definition at line 996 of file backend_status.c.

997{
998 PgBackendStatus *beentry;
999 int i;
1000
1001 beentry = BackendStatusArray;
1002 for (i = 1; i <= MaxBackends; i++)
1003 {
1004 /*
1005 * Although we expect the target backend's entry to be stable, that
1006 * doesn't imply that anyone else's is. To avoid identifying the
1007 * wrong backend, while we check for a match to the desired PID we
1008 * must follow the protocol of retrying if st_changecount changes
1009 * while we examine the entry, or if it's odd. (This might be
1010 * unnecessary, since fetching or storing an int is almost certainly
1011 * atomic, but let's play it safe.) We use a volatile pointer here to
1012 * ensure the compiler doesn't try to get cute.
1013 */
1014 volatile PgBackendStatus *vbeentry = beentry;
1015 bool found;
1016
1017 for (;;)
1018 {
1019 int before_changecount;
1020 int after_changecount;
1021
1022 pgstat_begin_read_activity(vbeentry, before_changecount);
1023
1024 found = (vbeentry->st_procpid == pid);
1025
1026 pgstat_end_read_activity(vbeentry, after_changecount);
1027
1028 if (pgstat_read_activity_complete(before_changecount,
1029 after_changecount))
1030 break;
1031
1032 /* Make sure we can break out of loop if stuck... */
1034 }
1035
1036 if (found)
1037 {
1038 /* Now it is safe to use the non-volatile pointer */
1039 if (checkUser && !superuser() && beentry->st_userid != GetUserId())
1040 return "<insufficient privilege>";
1041 else if (*(beentry->st_activity_raw) == '\0')
1042 return "<command string not enabled>";
1043 else
1044 {
1045 /* this'll leak a bit of memory, but that seems acceptable */
1046 return pgstat_clip_activity(beentry->st_activity_raw);
1047 }
1048 }
1049
1050 beentry++;
1051 }
1052
1053 /* If we get here, caller is in error ... */
1054 return "<backend information not available>";
1055}
char * pgstat_clip_activity(const char *raw_activity)
#define pgstat_read_activity_complete(before_changecount, after_changecount)
#define pgstat_end_read_activity(beentry, after_changecount)
#define pgstat_begin_read_activity(beentry, before_changecount)
int MaxBackends
Definition: globals.c:145
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:122
Oid GetUserId(void)
Definition: miscinit.c:520
bool superuser(void)
Definition: superuser.c:46

References BackendStatusArray, CHECK_FOR_INTERRUPTS, GetUserId(), i, MaxBackends, pgstat_begin_read_activity, pgstat_clip_activity(), pgstat_end_read_activity, pgstat_read_activity_complete, PgBackendStatus::st_activity_raw, PgBackendStatus::st_procpid, PgBackendStatus::st_userid, and superuser().

Referenced by DeadLockReport().

◆ pgstat_get_backend_type_by_proc_number()

BackendType pgstat_get_backend_type_by_proc_number ( ProcNumber  procNumber)

Definition at line 1181 of file backend_status.c.

1182{
1183 volatile PgBackendStatus *status = &BackendStatusArray[procNumber];
1184
1185 /*
1186 * We bypass the changecount mechanism since fetching and storing an int
1187 * is almost certainly atomic.
1188 */
1189 return status->st_backendType;
1190}

References BackendStatusArray, and PgBackendStatus::st_backendType.

Referenced by pg_signal_backend().

◆ pgstat_get_beentry_by_proc_number()

◆ pgstat_get_crashed_backend_activity()

const char * pgstat_get_crashed_backend_activity ( int  pid,
char *  buffer,
int  buflen 
)

Definition at line 1074 of file backend_status.c.

1075{
1076 volatile PgBackendStatus *beentry;
1077 int i;
1078
1079 beentry = BackendStatusArray;
1080
1081 /*
1082 * We probably shouldn't get here before shared memory has been set up,
1083 * but be safe.
1084 */
1085 if (beentry == NULL || BackendActivityBuffer == NULL)
1086 return NULL;
1087
1088 for (i = 1; i <= MaxBackends; i++)
1089 {
1090 if (beentry->st_procpid == pid)
1091 {
1092 /* Read pointer just once, so it can't change after validation */
1093 const char *activity = beentry->st_activity_raw;
1094 const char *activity_last;
1095
1096 /*
1097 * We mustn't access activity string before we verify that it
1098 * falls within the BackendActivityBuffer. To make sure that the
1099 * entire string including its ending is contained within the
1100 * buffer, subtract one activity length from the buffer size.
1101 */
1104
1105 if (activity < BackendActivityBuffer ||
1106 activity > activity_last)
1107 return NULL;
1108
1109 /* If no string available, no point in a report */
1110 if (activity[0] == '\0')
1111 return NULL;
1112
1113 /*
1114 * Copy only ASCII-safe characters so we don't run into encoding
1115 * problems when reporting the message; and be sure not to run off
1116 * the end of memory. As only ASCII characters are reported, it
1117 * doesn't seem necessary to perform multibyte aware clipping.
1118 */
1119 ascii_safe_strlcpy(buffer, activity,
1121
1122 return buffer;
1123 }
1124
1125 beentry++;
1126 }
1127
1128 /* PID not found */
1129 return NULL;
1130}
void ascii_safe_strlcpy(char *dest, const char *src, size_t destsiz)
Definition: ascii.c:174
#define Min(x, y)
Definition: c.h:975

References ascii_safe_strlcpy(), BackendActivityBuffer, BackendActivityBufferSize, BackendStatusArray, i, MaxBackends, Min, pgstat_track_activity_query_size, PgBackendStatus::st_activity_raw, and PgBackendStatus::st_procpid.

Referenced by LogChildExit().

◆ pgstat_get_local_beentry_by_index()

LocalPgBackendStatus * pgstat_get_local_beentry_by_index ( int  idx)

Definition at line 1279 of file backend_status.c.

1280{
1282
1283 if (idx < 1 || idx > localNumBackends)
1284 return NULL;
1285
1286 return &localBackendStatusTable[idx - 1];
1287}
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:259

References idx(), localBackendStatusTable, localNumBackends, and pgstat_read_current_status().

Referenced by pg_stat_get_activity(), pg_stat_get_backend_idset(), pg_stat_get_db_numbackends(), and pg_stat_get_progress_info().

◆ pgstat_get_local_beentry_by_proc_number()

LocalPgBackendStatus * pgstat_get_local_beentry_by_proc_number ( ProcNumber  procNumber)

Definition at line 1248 of file backend_status.c.

1249{
1251
1253
1254 /*
1255 * Since the localBackendStatusTable is in order by proc_number, we can
1256 * use bsearch() to search it efficiently.
1257 */
1258 key.proc_number = procNumber;
1261}
static int cmp_lbestatus(const void *a, const void *b)

References cmp_lbestatus(), sort-test::key, localBackendStatusTable, localNumBackends, and pgstat_read_current_status().

Referenced by pg_stat_get_backend_subxact(), and pgstat_get_beentry_by_proc_number().

◆ pgstat_get_my_plan_id()

uint64 pgstat_get_my_plan_id ( void  )

Definition at line 1158 of file backend_status.c.

1159{
1160 if (!MyBEEntry)
1161 return 0;
1162
1163 /* No need for a lock, for roughly the same reasons as above. */
1164 return MyBEEntry->st_plan_id;
1165}

References MyBEEntry, and PgBackendStatus::st_plan_id.

Referenced by ExecSerializePlan().

◆ pgstat_get_my_query_id()

uint64 pgstat_get_my_query_id ( void  )

Definition at line 1138 of file backend_status.c.

1139{
1140 if (!MyBEEntry)
1141 return 0;
1142
1143 /*
1144 * There's no need for a lock around pgstat_begin_read_activity /
1145 * pgstat_end_read_activity here as it's only called from
1146 * pg_stat_get_activity which is already protected, or from the same
1147 * backend which means that there won't be concurrent writes.
1148 */
1149 return MyBEEntry->st_query_id;
1150}

References MyBEEntry, and PgBackendStatus::st_query_id.

Referenced by _brin_begin_parallel(), _bt_begin_parallel(), ExecSerializePlan(), log_status_format(), parallel_vacuum_init(), write_csvlog(), and write_jsonlog().

◆ pgstat_read_current_status()

static void pgstat_read_current_status ( void  )
static

Definition at line 820 of file backend_status.c.

821{
822 volatile PgBackendStatus *beentry;
823 LocalPgBackendStatus *localtable;
824 LocalPgBackendStatus *localentry;
825 char *localappname,
826 *localclienthostname,
827 *localactivity;
828#ifdef USE_SSL
829 PgBackendSSLStatus *localsslstatus;
830#endif
831#ifdef ENABLE_GSS
832 PgBackendGSSStatus *localgssstatus;
833#endif
834 ProcNumber procNumber;
835
837 return; /* already done */
838
840
841 /*
842 * Allocate storage for local copy of state data. We can presume that
843 * none of these requests overflow size_t, because we already calculated
844 * the same values using mul_size during shmem setup. However, with
845 * probably-silly values of pgstat_track_activity_query_size and
846 * max_connections, the localactivity buffer could exceed 1GB, so use
847 * "huge" allocation for that one.
848 */
849 localtable = (LocalPgBackendStatus *)
852 localappname = (char *)
855 localclienthostname = (char *)
858 localactivity = (char *)
862#ifdef USE_SSL
863 localsslstatus = (PgBackendSSLStatus *)
866#endif
867#ifdef ENABLE_GSS
868 localgssstatus = (PgBackendGSSStatus *)
871#endif
872
874
875 beentry = BackendStatusArray;
876 localentry = localtable;
877 for (procNumber = 0; procNumber < NumBackendStatSlots; procNumber++)
878 {
879 /*
880 * Follow the protocol of retrying if st_changecount changes while we
881 * copy the entry, or if it's odd. (The check for odd is needed to
882 * cover the case where we are able to completely copy the entry while
883 * the source backend is between increment steps.) We use a volatile
884 * pointer here to ensure the compiler doesn't try to get cute.
885 */
886 for (;;)
887 {
888 int before_changecount;
889 int after_changecount;
890
891 pgstat_begin_read_activity(beentry, before_changecount);
892
893 localentry->backendStatus.st_procpid = beentry->st_procpid;
894 /* Skip all the data-copying work if entry is not in use */
895 if (localentry->backendStatus.st_procpid > 0)
896 {
897 memcpy(&localentry->backendStatus, unvolatize(PgBackendStatus *, beentry), sizeof(PgBackendStatus));
898
899 /*
900 * For each PgBackendStatus field that is a pointer, copy the
901 * pointed-to data, then adjust the local copy of the pointer
902 * field to point at the local copy of the data.
903 *
904 * strcpy is safe even if the string is modified concurrently,
905 * because there's always a \0 at the end of the buffer.
906 */
907 strcpy(localappname, beentry->st_appname);
908 localentry->backendStatus.st_appname = localappname;
909 strcpy(localclienthostname, beentry->st_clienthostname);
910 localentry->backendStatus.st_clienthostname = localclienthostname;
911 strcpy(localactivity, beentry->st_activity_raw);
912 localentry->backendStatus.st_activity_raw = localactivity;
913#ifdef USE_SSL
914 if (beentry->st_ssl)
915 {
916 memcpy(localsslstatus, beentry->st_sslstatus, sizeof(PgBackendSSLStatus));
917 localentry->backendStatus.st_sslstatus = localsslstatus;
918 }
919#endif
920#ifdef ENABLE_GSS
921 if (beentry->st_gss)
922 {
923 memcpy(localgssstatus, beentry->st_gssstatus, sizeof(PgBackendGSSStatus));
924 localentry->backendStatus.st_gssstatus = localgssstatus;
925 }
926#endif
927 }
928
929 pgstat_end_read_activity(beentry, after_changecount);
930
931 if (pgstat_read_activity_complete(before_changecount,
932 after_changecount))
933 break;
934
935 /* Make sure we can break out of loop if stuck... */
937 }
938
939 /* Only valid entries get included into the local array */
940 if (localentry->backendStatus.st_procpid > 0)
941 {
942 /*
943 * The BackendStatusArray index is exactly the ProcNumber of the
944 * source backend. Note that this means localBackendStatusTable
945 * is in order by proc_number. pgstat_get_beentry_by_proc_number()
946 * depends on that.
947 */
948 localentry->proc_number = procNumber;
950 &localentry->backend_xid,
951 &localentry->backend_xmin,
952 &localentry->backend_subxact_count,
953 &localentry->backend_subxact_overflowed);
954
955 localentry++;
956 localappname += NAMEDATALEN;
957 localclienthostname += NAMEDATALEN;
958 localactivity += pgstat_track_activity_query_size;
959#ifdef USE_SSL
960 localsslstatus++;
961#endif
962#ifdef ENABLE_GSS
963 localgssstatus++;
964#endif
966 }
967
968 beentry++;
969 }
970
971 /* Set the pointer only after completion of a valid table */
972 localBackendStatusTable = localtable;
973}
static void pgstat_setup_backend_status_context(void)
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1181
void * MemoryContextAllocHuge(MemoryContext context, Size size)
Definition: mcxt.c:1643
void ProcNumberGetTransactionIds(ProcNumber procNumber, TransactionId *xid, TransactionId *xmin, int *nsubxid, bool *overflowed)
Definition: procarray.c:3160
int ProcNumber
Definition: procnumber.h:24
TransactionId backend_xid
TransactionId backend_xmin

References LocalPgBackendStatus::backend_subxact_count, LocalPgBackendStatus::backend_subxact_overflowed, LocalPgBackendStatus::backend_xid, LocalPgBackendStatus::backend_xmin, LocalPgBackendStatus::backendStatus, BackendStatusArray, backendStatusSnapContext, CHECK_FOR_INTERRUPTS, localBackendStatusTable, localNumBackends, MemoryContextAlloc(), MemoryContextAllocHuge(), NAMEDATALEN, NumBackendStatSlots, pgstat_begin_read_activity, pgstat_end_read_activity, pgstat_read_activity_complete, pgstat_setup_backend_status_context(), pgstat_track_activity_query_size, LocalPgBackendStatus::proc_number, ProcNumberGetTransactionIds(), PgBackendStatus::st_activity_raw, PgBackendStatus::st_appname, PgBackendStatus::st_clienthostname, PgBackendStatus::st_gss, PgBackendStatus::st_gssstatus, PgBackendStatus::st_procpid, PgBackendStatus::st_ssl, PgBackendStatus::st_sslstatus, and unvolatize.

Referenced by pgstat_fetch_stat_numbackends(), pgstat_get_local_beentry_by_index(), and pgstat_get_local_beentry_by_proc_number().

◆ pgstat_report_activity()

void pgstat_report_activity ( BackendState  state,
const char *  cmd_str 
)

Definition at line 572 of file backend_status.c.

573{
574 volatile PgBackendStatus *beentry = MyBEEntry;
575 TimestampTz start_timestamp;
576 TimestampTz current_timestamp;
577 int len = 0;
578
579 TRACE_POSTGRESQL_STATEMENT_STATUS(cmd_str);
580
581 if (!beentry)
582 return;
583
585 {
586 if (beentry->st_state != STATE_DISABLED)
587 {
588 volatile PGPROC *proc = MyProc;
589
590 /*
591 * track_activities is disabled, but we last reported a
592 * non-disabled state. As our final update, change the state and
593 * clear fields we will not be updating anymore.
594 */
596 beentry->st_state = STATE_DISABLED;
597 beentry->st_state_start_timestamp = 0;
598 beentry->st_activity_raw[0] = '\0';
599 beentry->st_activity_start_timestamp = 0;
600 /* st_xact_start_timestamp and wait_event_info are also disabled */
601 beentry->st_xact_start_timestamp = 0;
602 beentry->st_query_id = UINT64CONST(0);
603 beentry->st_plan_id = UINT64CONST(0);
604 proc->wait_event_info = 0;
606 }
607 return;
608 }
609
610 /*
611 * To minimize the time spent modifying the entry, and avoid risk of
612 * errors inside the critical section, fetch all the needed data first.
613 */
614 start_timestamp = GetCurrentStatementStartTimestamp();
615 if (cmd_str != NULL)
616 {
617 /*
618 * Compute length of to-be-stored string unaware of multi-byte
619 * characters. For speed reasons that'll get corrected on read, rather
620 * than computed every write.
621 */
622 len = Min(strlen(cmd_str), pgstat_track_activity_query_size - 1);
623 }
624 current_timestamp = GetCurrentTimestamp();
625
626 /*
627 * If the state has changed from "active" or "idle in transaction",
628 * calculate the duration.
629 */
630 if ((beentry->st_state == STATE_RUNNING ||
631 beentry->st_state == STATE_FASTPATH ||
632 beentry->st_state == STATE_IDLEINTRANSACTION ||
634 state != beentry->st_state)
635 {
636 long secs;
637 int usecs;
638
640 current_timestamp,
641 &secs, &usecs);
642
643 if (beentry->st_state == STATE_RUNNING ||
644 beentry->st_state == STATE_FASTPATH)
645 pgstat_count_conn_active_time((PgStat_Counter) secs * 1000000 + usecs);
646 else
647 pgstat_count_conn_txn_idle_time((PgStat_Counter) secs * 1000000 + usecs);
648 }
649
650 /*
651 * Now update the status entry
652 */
654
655 beentry->st_state = state;
656 beentry->st_state_start_timestamp = current_timestamp;
657
658 /*
659 * If a new query is started, we reset the query identifier as it'll only
660 * be known after parse analysis, to avoid reporting last query's
661 * identifier.
662 */
663 if (state == STATE_RUNNING)
664 {
665 beentry->st_query_id = UINT64CONST(0);
666 beentry->st_plan_id = UINT64CONST(0);
667 }
668
669 if (cmd_str != NULL)
670 {
671 memcpy(beentry->st_activity_raw, cmd_str, len);
672 beentry->st_activity_raw[len] = '\0';
673 beentry->st_activity_start_timestamp = start_timestamp;
674 }
675
677}
void TimestampDifference(TimestampTz start_time, TimestampTz stop_time, long *secs, int *microsecs)
Definition: timestamp.c:1720
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1644
bool pgstat_track_activities
@ STATE_IDLEINTRANSACTION_ABORTED
@ STATE_IDLEINTRANSACTION
@ STATE_DISABLED
@ STATE_FASTPATH
@ STATE_RUNNING
int64 TimestampTz
Definition: timestamp.h:39
const void size_t len
#define pgstat_count_conn_txn_idle_time(n)
Definition: pgstat.h:626
#define pgstat_count_conn_active_time(n)
Definition: pgstat.h:624
int64 PgStat_Counter
Definition: pgstat.h:65
PGPROC * MyProc
Definition: proc.c:66
Definition: proc.h:163
uint32 wait_event_info
Definition: proc.h:280
Definition: regguts.h:323
TimestampTz GetCurrentStatementStartTimestamp(void)
Definition: xact.c:879

References GetCurrentStatementStartTimestamp(), GetCurrentTimestamp(), len, Min, MyBEEntry, MyProc, PGSTAT_BEGIN_WRITE_ACTIVITY, pgstat_count_conn_active_time, pgstat_count_conn_txn_idle_time, PGSTAT_END_WRITE_ACTIVITY, pgstat_track_activities, pgstat_track_activity_query_size, PgBackendStatus::st_activity_raw, PgBackendStatus::st_activity_start_timestamp, PgBackendStatus::st_plan_id, PgBackendStatus::st_query_id, PgBackendStatus::st_state, PgBackendStatus::st_state_start_timestamp, PgBackendStatus::st_xact_start_timestamp, STATE_DISABLED, STATE_FASTPATH, STATE_IDLEINTRANSACTION, STATE_IDLEINTRANSACTION_ABORTED, STATE_RUNNING, TimestampDifference(), UINT64CONST, and PGPROC::wait_event_info.

Referenced by _brin_parallel_build_main(), _bt_parallel_build_main(), _gin_parallel_build_main(), apply_handle_begin(), apply_handle_begin_prepare(), apply_handle_commit(), apply_handle_commit_prepared(), apply_handle_prepare(), apply_handle_rollback_prepared(), apply_handle_stream_commit(), apply_handle_stream_prepare(), apply_handle_stream_start(), apply_handle_stream_stop(), apply_spooled_messages(), autovac_report_activity(), autovac_report_workitem(), exec_bind_message(), exec_execute_message(), exec_parse_message(), exec_replication_command(), exec_simple_query(), initialize_worker_spi(), LogicalRepApplyLoop(), pa_stream_abort(), parallel_vacuum_main(), ParallelQueryMain(), PostgresMain(), and worker_spi_main().

◆ pgstat_report_appname()

void pgstat_report_appname ( const char *  appname)

Definition at line 764 of file backend_status.c.

765{
766 volatile PgBackendStatus *beentry = MyBEEntry;
767 int len;
768
769 if (!beentry)
770 return;
771
772 /* This should be unnecessary if GUC did its job, but be safe */
773 len = pg_mbcliplen(appname, strlen(appname), NAMEDATALEN - 1);
774
775 /*
776 * Update my status entry, following the protocol of bumping
777 * st_changecount before and after. We use a volatile pointer here to
778 * ensure the compiler doesn't try to get cute.
779 */
781
782 memcpy(beentry->st_appname, appname, len);
783 beentry->st_appname[len] = '\0';
784
786}

References len, MyBEEntry, NAMEDATALEN, pg_mbcliplen(), PGSTAT_BEGIN_WRITE_ACTIVITY, PGSTAT_END_WRITE_ACTIVITY, and PgBackendStatus::st_appname.

Referenced by assign_application_name(), and pgstat_bestart_final().

◆ pgstat_report_plan_id()

void pgstat_report_plan_id ( uint64  plan_id,
bool  force 
)

Definition at line 725 of file backend_status.c.

726{
727 volatile PgBackendStatus *beentry = MyBEEntry;
728
729 /*
730 * if track_activities is disabled, st_plan_id should already have been
731 * reset
732 */
733 if (!beentry || !pgstat_track_activities)
734 return;
735
736 /*
737 * We only report the top-level plan identifiers. The stored plan_id is
738 * reset when a backend calls pgstat_report_activity(STATE_RUNNING), or
739 * with an explicit call to this function using the force flag. If the
740 * saved plan identifier is not zero it means that it's not a top-level
741 * command, so ignore the one provided unless it's an explicit call to
742 * reset the identifier.
743 */
744 if (beentry->st_plan_id != 0 && !force)
745 return;
746
747 /*
748 * Update my status entry, following the protocol of bumping
749 * st_changecount before and after. We use a volatile pointer here to
750 * ensure the compiler doesn't try to get cute.
751 */
753 beentry->st_plan_id = plan_id;
755}

References MyBEEntry, PGSTAT_BEGIN_WRITE_ACTIVITY, PGSTAT_END_WRITE_ACTIVITY, pgstat_track_activities, and PgBackendStatus::st_plan_id.

Referenced by exec_bind_message(), exec_execute_message(), exec_simple_query(), and planner().

◆ pgstat_report_query_id()

void pgstat_report_query_id ( uint64  query_id,
bool  force 
)

Definition at line 686 of file backend_status.c.

687{
688 volatile PgBackendStatus *beentry = MyBEEntry;
689
690 /*
691 * if track_activities is disabled, st_query_id should already have been
692 * reset
693 */
694 if (!beentry || !pgstat_track_activities)
695 return;
696
697 /*
698 * We only report the top-level query identifiers. The stored query_id is
699 * reset when a backend calls pgstat_report_activity(STATE_RUNNING), or
700 * with an explicit call to this function using the force flag. If the
701 * saved query identifier is not zero it means that it's not a top-level
702 * command, so ignore the one provided unless it's an explicit call to
703 * reset the identifier.
704 */
705 if (beentry->st_query_id != 0 && !force)
706 return;
707
708 /*
709 * Update my status entry, following the protocol of bumping
710 * st_changecount before and after. We use a volatile pointer here to
711 * ensure the compiler doesn't try to get cute.
712 */
714 beentry->st_query_id = query_id;
716}

References MyBEEntry, PGSTAT_BEGIN_WRITE_ACTIVITY, PGSTAT_END_WRITE_ACTIVITY, pgstat_track_activities, and PgBackendStatus::st_query_id.

Referenced by _brin_parallel_build_main(), _bt_parallel_build_main(), exec_bind_message(), exec_execute_message(), exec_simple_query(), ExecutorStart(), parallel_vacuum_main(), parse_analyze_fixedparams(), parse_analyze_varparams(), and parse_analyze_withcb().

◆ pgstat_report_xact_timestamp()

void pgstat_report_xact_timestamp ( TimestampTz  tstamp)

Definition at line 793 of file backend_status.c.

794{
795 volatile PgBackendStatus *beentry = MyBEEntry;
796
797 if (!pgstat_track_activities || !beentry)
798 return;
799
800 /*
801 * Update my status entry, following the protocol of bumping
802 * st_changecount before and after. We use a volatile pointer here to
803 * ensure the compiler doesn't try to get cute.
804 */
806
807 beentry->st_xact_start_timestamp = tstamp;
808
810}

References MyBEEntry, PGSTAT_BEGIN_WRITE_ACTIVITY, PGSTAT_END_WRITE_ACTIVITY, pgstat_track_activities, and PgBackendStatus::st_xact_start_timestamp.

Referenced by AbortTransaction(), CommitTransaction(), PrepareTransaction(), and StartTransaction().

◆ pgstat_setup_backend_status_context()

static void pgstat_setup_backend_status_context ( void  )
static

Definition at line 551 of file backend_status.c.

552{
555 "Backend Status Snapshot",
557}
MemoryContext TopMemoryContext
Definition: mcxt.c:149
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_SMALL_SIZES
Definition: memutils.h:170

References ALLOCSET_SMALL_SIZES, AllocSetContextCreate, backendStatusSnapContext, and TopMemoryContext.

Referenced by pgstat_read_current_status().

Variable Documentation

◆ BackendActivityBuffer

char* BackendActivityBuffer = NULL
static

Definition at line 53 of file backend_status.c.

Referenced by BackendStatusShmemInit(), and pgstat_get_crashed_backend_activity().

◆ BackendActivityBufferSize

Size BackendActivityBufferSize = 0
static

Definition at line 54 of file backend_status.c.

Referenced by BackendStatusShmemInit(), and pgstat_get_crashed_backend_activity().

◆ BackendAppnameBuffer

char* BackendAppnameBuffer = NULL
static

Definition at line 51 of file backend_status.c.

Referenced by BackendStatusShmemInit().

◆ BackendClientHostnameBuffer

char* BackendClientHostnameBuffer = NULL
static

Definition at line 52 of file backend_status.c.

Referenced by BackendStatusShmemInit().

◆ BackendStatusArray

◆ backendStatusSnapContext

◆ localBackendStatusTable

◆ localNumBackends

◆ MyBEEntry

◆ pgstat_track_activities

◆ pgstat_track_activity_query_size