PostgreSQL Source Code git master
Loading...
Searching...
No Matches
backend_status.h File Reference
#include "datatype/timestamp.h"
#include "libpq/pqcomm.h"
#include "miscadmin.h"
#include "storage/procnumber.h"
#include "utils/backend_progress.h"
Include dependency graph for backend_status.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  PgBackendSSLStatus
 
struct  PgBackendGSSStatus
 
struct  PgBackendStatus
 
struct  LocalPgBackendStatus
 

Macros

#define PGSTAT_BEGIN_WRITE_ACTIVITY(beentry)
 
#define PGSTAT_END_WRITE_ACTIVITY(beentry)
 
#define pgstat_begin_read_activity(beentry, before_changecount)
 
#define pgstat_end_read_activity(beentry, after_changecount)
 
#define pgstat_read_activity_complete(before_changecount, after_changecount)
 

Typedefs

typedef enum BackendState BackendState
 
typedef struct PgBackendSSLStatus PgBackendSSLStatus
 
typedef struct PgBackendGSSStatus PgBackendGSSStatus
 
typedef struct PgBackendStatus PgBackendStatus
 
typedef struct LocalPgBackendStatus LocalPgBackendStatus
 

Enumerations

enum  BackendState {
  STATE_UNDEFINED , STATE_STARTING , STATE_IDLE , STATE_RUNNING ,
  STATE_IDLEINTRANSACTION , STATE_FASTPATH , STATE_IDLEINTRANSACTION_ABORTED , STATE_DISABLED
}
 

Functions

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 (int64 query_id, bool force)
 
void pgstat_report_plan_id (int64 plan_id, bool force)
 
void pgstat_report_tempfile (size_t filesize)
 
void pgstat_report_appname (const char *appname)
 
void pgstat_report_xact_timestamp (TimestampTz tstamp)
 
const charpgstat_get_backend_current_activity (int pid, bool checkUser)
 
const charpgstat_get_crashed_backend_activity (int pid, char *buffer, int buflen)
 
int64 pgstat_get_my_query_id (void)
 
int64 pgstat_get_my_plan_id (void)
 
int pgstat_fetch_stat_numbackends (void)
 
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)
 
charpgstat_clip_activity (const char *raw_activity)
 

Variables

PGDLLIMPORT bool pgstat_track_activities
 
PGDLLIMPORT int pgstat_track_activity_query_size
 
PGDLLIMPORT PgBackendStatusMyBEEntry
 

Macro Definition Documentation

◆ pgstat_begin_read_activity

#define pgstat_begin_read_activity (   beentry,
  before_changecount 
)
Value:
do { \
(before_changecount) = (beentry)->st_changecount; \
} while (0)
static int fb(int x)

Definition at line 224 of file backend_status.h.

225 { \
226 (before_changecount) = (beentry)->st_changecount; \
228 } while (0)

◆ PGSTAT_BEGIN_WRITE_ACTIVITY

#define PGSTAT_BEGIN_WRITE_ACTIVITY (   beentry)
Value:
do { \
(beentry)->st_changecount++; \
} while (0)

Definition at line 209 of file backend_status.h.

210 { \
212 (beentry)->st_changecount++; \
214 } while (0)

◆ pgstat_end_read_activity

#define pgstat_end_read_activity (   beentry,
  after_changecount 
)
Value:
do { \
(after_changecount) = (beentry)->st_changecount; \
} while (0)

Definition at line 230 of file backend_status.h.

231 { \
233 (after_changecount) = (beentry)->st_changecount; \
234 } while (0)

◆ PGSTAT_END_WRITE_ACTIVITY

#define PGSTAT_END_WRITE_ACTIVITY (   beentry)
Value:
do { \
(beentry)->st_changecount++; \
Assert(((beentry)->st_changecount & 1) == 0); \
} while (0)

Definition at line 216 of file backend_status.h.

217 { \
219 (beentry)->st_changecount++; \
220 Assert(((beentry)->st_changecount & 1) == 0); \
222 } while (0)

◆ pgstat_read_activity_complete

#define pgstat_read_activity_complete (   before_changecount,
  after_changecount 
)
Value:

Definition at line 236 of file backend_status.h.

Typedef Documentation

◆ BackendState

◆ LocalPgBackendStatus

◆ PgBackendGSSStatus

◆ PgBackendSSLStatus

◆ PgBackendStatus

Enumeration Type Documentation

◆ BackendState

Enumerator
STATE_UNDEFINED 
STATE_STARTING 
STATE_IDLE 
STATE_RUNNING 
STATE_IDLEINTRANSACTION 
STATE_FASTPATH 
STATE_IDLEINTRANSACTION_ABORTED 
STATE_DISABLED 

Definition at line 24 of file backend_status.h.

25{
BackendState
@ STATE_UNDEFINED
@ STATE_IDLEINTRANSACTION_ABORTED
@ STATE_STARTING
@ STATE_IDLE
@ STATE_IDLEINTRANSACTION
@ STATE_DISABLED
@ STATE_FASTPATH
@ STATE_RUNNING

Function Documentation

◆ pgstat_beinit()

void pgstat_beinit ( void  )
extern

Definition at line 210 of file backend_status.c.

211{
212 /* Initialize MyBEEntry */
216
217 /* Set up a process-exit hook to clean up */
219}
#define NumBackendStatSlots
PgBackendStatus * MyBEEntry
static void pgstat_beshutdown_hook(int code, Datum arg)
static PgBackendStatus * BackendStatusArray
#define Assert(condition)
Definition c.h:943
ProcNumber MyProcNumber
Definition globals.c:90
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition ipc.c:372
#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_bestart_final()

void pgstat_bestart_final ( void  )
extern

Definition at line 432 of file backend_status.c.

433{
435 Oid userid;
436
437 /* pgstats state must be initialized from pgstat_beinit() */
438 Assert(beentry != NULL);
439
440 /* We have userid for client-backends, wal-sender and bgworker processes */
444 userid = GetSessionUserId();
445 else
446 userid = InvalidOid;
447
448 /*
449 * Update my status entry, following the protocol of bumping
450 * st_changecount before and after. We use a volatile pointer here to
451 * ensure the compiler doesn't try to get cute.
452 */
454
455 beentry->st_databaseid = MyDatabaseId;
456 beentry->st_userid = userid;
457 beentry->st_state = STATE_UNDEFINED;
458
460
461 /* Create the backend statistics entry */
464
465 /* Update app name to current GUC setting */
468}
void pgstat_report_appname(const char *appname)
#define PGSTAT_END_WRITE_ACTIVITY(beentry)
#define PGSTAT_BEGIN_WRITE_ACTIVITY(beentry)
Oid MyDatabaseId
Definition globals.c:94
char * application_name
Definition guc_tables.c:579
@ B_WAL_SENDER
Definition miscadmin.h:347
@ B_BG_WORKER
Definition miscadmin.h:346
@ B_BACKEND
Definition miscadmin.h:342
Oid GetSessionUserId(void)
Definition miscinit.c:509
BackendType MyBackendType
Definition miscinit.c:65
void pgstat_create_backend(ProcNumber procnum)
bool pgstat_tracks_backend_bktype(BackendType bktype)
#define InvalidOid
unsigned int Oid

References application_name, Assert, B_BACKEND, B_BG_WORKER, B_WAL_SENDER, fb(), GetSessionUserId(), InvalidOid, MyBackendType, MyBEEntry, MyDatabaseId, MyProcNumber, PGSTAT_BEGIN_WRITE_ACTIVITY, pgstat_create_backend(), PGSTAT_END_WRITE_ACTIVITY, pgstat_report_appname(), pgstat_tracks_backend_bktype(), and STATE_UNDEFINED.

Referenced by AuxiliaryProcessMainCommon(), and InitPostgres().

◆ pgstat_bestart_initial()

void pgstat_bestart_initial ( void  )
extern

Definition at line 235 of file backend_status.c.

236{
239
240 /* pgstats state must be initialized from pgstat_beinit() */
241 Assert(vbeentry != NULL);
242
243 /*
244 * To minimize the time spent modifying the PgBackendStatus entry, and
245 * avoid risk of errors inside the critical section, we first copy the
246 * shared-memory struct to a local variable, then modify the data in the
247 * local variable, then copy the local variable back to shared memory.
248 * Only the last step has to be inside the critical section.
249 *
250 * Most of the data we copy from shared memory is just going to be
251 * overwritten, but the struct's not so large that it's worth the
252 * maintenance hassle to copy only the needful fields.
253 */
256 sizeof(PgBackendStatus));
257
258 /*
259 * Now fill in all the fields of lbeentry, except for strings that are
260 * out-of-line data. Those have to be handled separately, below.
261 */
262 lbeentry.st_procpid = MyProcPid;
263 lbeentry.st_backendType = MyBackendType;
264 lbeentry.st_proc_start_timestamp = MyStartTimestamp;
265 lbeentry.st_activity_start_timestamp = 0;
266 lbeentry.st_state_start_timestamp = 0;
267 lbeentry.st_xact_start_timestamp = 0;
268 lbeentry.st_databaseid = InvalidOid;
269 lbeentry.st_userid = InvalidOid;
270
271 /*
272 * We may not have a MyProcPort (eg, if this is the autovacuum process).
273 * If so, use all-zeroes client address, which is dealt with specially in
274 * pg_stat_get_backend_client_addr and pg_stat_get_backend_client_port.
275 */
276 if (MyProcPort)
277 memcpy(&lbeentry.st_clientaddr, &MyProcPort->raddr,
278 sizeof(lbeentry.st_clientaddr));
279 else
280 MemSet(&lbeentry.st_clientaddr, 0, sizeof(lbeentry.st_clientaddr));
281
282 lbeentry.st_ssl = false;
283 lbeentry.st_gss = false;
284
285 lbeentry.st_state = STATE_STARTING;
286 lbeentry.st_progress_command = PROGRESS_COMMAND_INVALID;
287 lbeentry.st_progress_command_target = InvalidOid;
288 lbeentry.st_query_id = INT64CONST(0);
289 lbeentry.st_plan_id = INT64CONST(0);
290
291 /*
292 * we don't zero st_progress_param here to save cycles; nobody should
293 * examine it until st_progress_command has been set to something other
294 * than PROGRESS_COMMAND_INVALID
295 */
296
297 /*
298 * We're ready to enter the critical section that fills the shared-memory
299 * status entry. We follow the protocol of bumping st_changecount before
300 * and after; and make sure it's even afterwards. We use a volatile
301 * pointer here to ensure the compiler doesn't try to get cute.
302 */
304
305 /* make sure we'll memcpy the same st_changecount back */
306 lbeentry.st_changecount = vbeentry->st_changecount;
307
309 &lbeentry,
310 sizeof(PgBackendStatus));
311
312 /*
313 * We can write the out-of-line strings and structs using the pointers
314 * that are in lbeentry; this saves some de-volatilizing messiness.
315 */
316 lbeentry.st_appname[0] = '\0';
318 strlcpy(lbeentry.st_clienthostname, MyProcPort->remote_hostname,
320 else
321 lbeentry.st_clienthostname[0] = '\0';
322 lbeentry.st_activity_raw[0] = '\0';
323 /* Also make sure the last byte in each string area is always 0 */
324 lbeentry.st_appname[NAMEDATALEN - 1] = '\0';
325 lbeentry.st_clienthostname[NAMEDATALEN - 1] = '\0';
326 lbeentry.st_activity_raw[pgstat_track_activity_query_size - 1] = '\0';
327
328 /* These structs can just start from zeroes each time */
329#ifdef USE_SSL
330 memset(lbeentry.st_sslstatus, 0, sizeof(PgBackendSSLStatus));
331#endif
332#ifdef ENABLE_GSS
333 memset(lbeentry.st_gssstatus, 0, sizeof(PgBackendGSSStatus));
334#endif
335
337}
@ PROGRESS_COMMAND_INVALID
int pgstat_track_activity_query_size
#define INT64CONST(x)
Definition c.h:630
#define unvolatize(underlying_type, expr)
Definition c.h:1328
#define MemSet(start, val, len)
Definition c.h:1107
memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets))
int MyProcPid
Definition globals.c:47
TimestampTz MyStartTimestamp
Definition globals.c:49
struct Port * MyProcPort
Definition globals.c:51
#define NAMEDATALEN
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition strlcpy.c:45
char * remote_hostname
Definition libpq-be.h:136
SockAddr raddr
Definition libpq-be.h:134

References Assert, fb(), INT64CONST, InvalidOid, memcpy(), 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, STATE_STARTING, strlcpy(), and unvolatize.

Referenced by AuxiliaryProcessMainCommon(), and InitPostgres().

◆ pgstat_bestart_security()

void pgstat_bestart_security ( void  )
extern

Definition at line 350 of file backend_status.c.

351{
353 bool ssl = false;
354 bool gss = false;
355#ifdef USE_SSL
357 PgBackendSSLStatus *st_sslstatus;
358#endif
359#ifdef ENABLE_GSS
361 PgBackendGSSStatus *st_gssstatus;
362#endif
363
364 /* pgstats state must be initialized from pgstat_beinit() */
365 Assert(beentry != NULL);
366 Assert(MyProcPort); /* otherwise there's no point */
367
368#ifdef USE_SSL
369 st_sslstatus = beentry->st_sslstatus;
370 memset(&lsslstatus, 0, sizeof(lsslstatus));
371
373 {
374 ssl = true;
381 }
382#endif
383
384#ifdef ENABLE_GSS
385 st_gssstatus = beentry->st_gssstatus;
386 memset(&lgssstatus, 0, sizeof(lgssstatus));
387
388 if (MyProcPort->gss != NULL)
389 {
390 const char *princ = be_gssapi_get_princ(MyProcPort);
391
392 gss = true;
396 if (princ)
397 strlcpy(lgssstatus.gss_princ, princ, NAMEDATALEN);
398 }
399#endif
400
401 /*
402 * Update my status entry, following the protocol of bumping
403 * st_changecount before and after. We use a volatile pointer here to
404 * ensure the compiler doesn't try to get cute.
405 */
407
408 beentry->st_ssl = ssl;
409 beentry->st_gss = gss;
410
411#ifdef USE_SSL
412 memcpy(st_sslstatus, &lsslstatus, sizeof(PgBackendSSLStatus));
413#endif
414#ifdef ENABLE_GSS
415 memcpy(st_gssstatus, &lgssstatus, sizeof(PgBackendGSSStatus));
416#endif
417
419}
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)
bool ssl_in_use
Definition libpq-be.h:208
void * gss
Definition libpq-be.h:202

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(), fb(), Port::gss, memcpy(), MyBEEntry, MyProcPort, NAMEDATALEN, PGSTAT_BEGIN_WRITE_ACTIVITY, PGSTAT_END_WRITE_ACTIVITY, Port::ssl_in_use, and strlcpy().

Referenced by InitPostgres().

◆ pgstat_clear_backend_activity_snapshot()

void pgstat_clear_backend_activity_snapshot ( void  )
extern

Definition at line 501 of file backend_status.c.

502{
503 /* Release memory, if any was allocated */
505 {
508 }
509
510 /* Reset variables */
513}
static LocalPgBackendStatus * localBackendStatusTable
static int localNumBackends
static MemoryContext backendStatusSnapContext
void MemoryContextDelete(MemoryContext context)
Definition mcxt.c:472

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

Referenced by pgstat_clear_snapshot().

◆ pgstat_clip_activity()

char * pgstat_clip_activity ( const char raw_activity)
extern

Definition at line 1255 of file backend_status.c.

1256{
1257 char *activity;
1258 int rawlen;
1259 int cliplen;
1260
1261 /*
1262 * Some callers, like pgstat_get_backend_current_activity(), do not
1263 * guarantee that the buffer isn't concurrently modified. We try to take
1264 * care that the buffer is always terminated by a NUL byte regardless, but
1265 * let's still be paranoid about the string's length. In those cases the
1266 * underlying buffer is guaranteed to be pgstat_track_activity_query_size
1267 * large.
1268 */
1270
1271 /* now double-guaranteed to be NUL terminated */
1273
1274 /*
1275 * All supported server-encodings make it possible to determine the length
1276 * of a multi-byte character from its first byte (this is not the case for
1277 * client encodings, see GB18030). As st_activity is always stored using
1278 * server encoding, this allows us to perform multi-byte aware truncation,
1279 * even if the string earlier was truncated in the middle of a multi-byte
1280 * character.
1281 */
1284
1285 activity[cliplen] = '\0';
1286
1287 return activity;
1288}
int pg_mbcliplen(const char *mbstr, int len, int limit)
Definition mbutils.c:1211
static int cliplen(const char *str, int len, int limit)
Definition mbutils.c:1278
char * pnstrdup(const char *in, Size len)
Definition mcxt.c:1792

References cliplen(), fb(), 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  )
extern

Definition at line 1239 of file backend_status.c.

1240{
1242
1243 return localNumBackends;
1244}
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 
)
extern

Definition at line 961 of file backend_status.c.

962{
964 int i;
965
967 for (i = 1; i <= MaxBackends; i++)
968 {
969 /*
970 * Although we expect the target backend's entry to be stable, that
971 * doesn't imply that anyone else's is. To avoid identifying the
972 * wrong backend, while we check for a match to the desired PID we
973 * must follow the protocol of retrying if st_changecount changes
974 * while we examine the entry, or if it's odd. (This might be
975 * unnecessary, since fetching or storing an int is almost certainly
976 * atomic, but let's play it safe.) We use a volatile pointer here to
977 * ensure the compiler doesn't try to get cute.
978 */
979 volatile PgBackendStatus *vbeentry = beentry;
980 bool found;
981
982 for (;;)
983 {
986
988
989 found = (vbeentry->st_procpid == pid);
990
992
995 break;
996
997 /* Make sure we can break out of loop if stuck... */
999 }
1000
1001 if (found)
1002 {
1003 /* Now it is safe to use the non-volatile pointer */
1004 if (checkUser && !superuser() && beentry->st_userid != GetUserId())
1005 return "<insufficient privilege>";
1006 else if (*(beentry->st_activity_raw) == '\0')
1007 return "<command string not enabled>";
1008 else
1009 {
1010 /* this'll leak a bit of memory, but that seems acceptable */
1011 return pgstat_clip_activity(beentry->st_activity_raw);
1012 }
1013 }
1014
1015 beentry++;
1016 }
1017
1018 /* If we get here, caller is in error ... */
1019 return "<backend information not available>";
1020}
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:146
int i
Definition isn.c:77
#define CHECK_FOR_INTERRUPTS()
Definition miscadmin.h:123
Oid GetUserId(void)
Definition miscinit.c:470
bool superuser(void)
Definition superuser.c:47

References BackendStatusArray, CHECK_FOR_INTERRUPTS, fb(), GetUserId(), i, MaxBackends, pgstat_begin_read_activity, pgstat_clip_activity(), pgstat_end_read_activity, pgstat_read_activity_complete, and superuser().

Referenced by DeadLockReport().

◆ pgstat_get_beentry_by_proc_number()

◆ pgstat_get_crashed_backend_activity()

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

Definition at line 1039 of file backend_status.c.

1040{
1041 volatile PgBackendStatus *beentry;
1042 int i;
1043
1045
1046 /*
1047 * We probably shouldn't get here before shared memory has been set up,
1048 * but be safe.
1049 */
1051 return NULL;
1052
1053 for (i = 1; i <= MaxBackends; i++)
1054 {
1055 if (beentry->st_procpid == pid)
1056 {
1057 /* Read pointer just once, so it can't change after validation */
1058 const char *activity = beentry->st_activity_raw;
1059 const char *activity_last;
1060
1061 /*
1062 * We mustn't access activity string before we verify that it
1063 * falls within the BackendActivityBuffer. To make sure that the
1064 * entire string including its ending is contained within the
1065 * buffer, subtract one activity length from the buffer size.
1066 */
1069
1072 return NULL;
1073
1074 /* If no string available, no point in a report */
1075 if (activity[0] == '\0')
1076 return NULL;
1077
1078 /*
1079 * Copy only ASCII-safe characters so we don't run into encoding
1080 * problems when reporting the message; and be sure not to run off
1081 * the end of memory. As only ASCII characters are reported, it
1082 * doesn't seem necessary to perform multibyte aware clipping.
1083 */
1086
1087 return buffer;
1088 }
1089
1090 beentry++;
1091 }
1092
1093 /* PID not found */
1094 return NULL;
1095}
void ascii_safe_strlcpy(char *dest, const char *src, size_t destsiz)
Definition ascii.c:174
static char * BackendActivityBuffer
static Size BackendActivityBufferSize
#define Min(x, y)
Definition c.h:1091

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

Referenced by LogChildExit().

◆ pgstat_get_local_beentry_by_index()

LocalPgBackendStatus * pgstat_get_local_beentry_by_index ( int  idx)
extern

◆ pgstat_get_local_beentry_by_proc_number()

LocalPgBackendStatus * pgstat_get_local_beentry_by_proc_number ( ProcNumber  procNumber)
extern

Definition at line 1188 of file backend_status.c.

1189{
1191
1193
1194 /*
1195 * Since the localBackendStatusTable is in order by proc_number, we can
1196 * use bsearch() to search it efficiently.
1197 */
1198 key.proc_number = procNumber;
1201}
static int cmp_lbestatus(const void *a, const void *b)

References cmp_lbestatus(), fb(), 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()

int64 pgstat_get_my_plan_id ( void  )
extern

Definition at line 1123 of file backend_status.c.

1124{
1125 if (!MyBEEntry)
1126 return 0;
1127
1128 /* No need for a lock, for roughly the same reasons as above. */
1129 return MyBEEntry->st_plan_id;
1130}

References MyBEEntry, and PgBackendStatus::st_plan_id.

Referenced by ExecSerializePlan().

◆ pgstat_get_my_query_id()

int64 pgstat_get_my_query_id ( void  )
extern

Definition at line 1103 of file backend_status.c.

1104{
1105 if (!MyBEEntry)
1106 return 0;
1107
1108 /*
1109 * There's no need for a lock around pgstat_begin_read_activity /
1110 * pgstat_end_read_activity here as it's only called from
1111 * pg_stat_get_activity which is already protected, or from the same
1112 * backend which means that there won't be concurrent writes.
1113 */
1114 return MyBEEntry->st_query_id;
1115}

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_report_activity()

void pgstat_report_activity ( BackendState  state,
const char cmd_str 
)
extern

Definition at line 537 of file backend_status.c.

538{
542 int len = 0;
543
545
546 if (!beentry)
547 return;
548
550 {
551 if (beentry->st_state != STATE_DISABLED)
552 {
553 volatile PGPROC *proc = MyProc;
554
555 /*
556 * track_activities is disabled, but we last reported a
557 * non-disabled state. As our final update, change the state and
558 * clear fields we will not be updating anymore.
559 */
561 beentry->st_state = STATE_DISABLED;
562 beentry->st_state_start_timestamp = 0;
563 beentry->st_activity_raw[0] = '\0';
564 beentry->st_activity_start_timestamp = 0;
565 /* st_xact_start_timestamp and wait_event_info are also disabled */
566 beentry->st_xact_start_timestamp = 0;
567 beentry->st_query_id = INT64CONST(0);
568 beentry->st_plan_id = INT64CONST(0);
569 proc->wait_event_info = 0;
571 }
572 return;
573 }
574
575 /*
576 * To minimize the time spent modifying the entry, and avoid risk of
577 * errors inside the critical section, fetch all the needed data first.
578 */
580 if (cmd_str != NULL)
581 {
582 /*
583 * Compute length of to-be-stored string unaware of multi-byte
584 * characters. For speed reasons that'll get corrected on read, rather
585 * than computed every write.
586 */
588 }
590
591 /*
592 * If the state has changed from "active" or "idle in transaction",
593 * calculate the duration.
594 */
595 if ((beentry->st_state == STATE_RUNNING ||
596 beentry->st_state == STATE_FASTPATH ||
597 beentry->st_state == STATE_IDLEINTRANSACTION ||
599 state != beentry->st_state)
600 {
601 long secs;
602 int usecs;
603
604 TimestampDifference(beentry->st_state_start_timestamp,
606 &secs, &usecs);
607
608 if (beentry->st_state == STATE_RUNNING ||
609 beentry->st_state == STATE_FASTPATH)
611 else
613 }
614
615 /*
616 * Now update the status entry
617 */
619
620 beentry->st_state = state;
621 beentry->st_state_start_timestamp = current_timestamp;
622
623 /*
624 * If a new query is started, we reset the query identifier as it'll only
625 * be known after parse analysis, to avoid reporting last query's
626 * identifier.
627 */
628 if (state == STATE_RUNNING)
629 {
630 beentry->st_query_id = INT64CONST(0);
631 beentry->st_plan_id = INT64CONST(0);
632 }
633
634 if (cmd_str != NULL)
635 {
636 memcpy(beentry->st_activity_raw, cmd_str, len);
637 beentry->st_activity_raw[len] = '\0';
638 beentry->st_activity_start_timestamp = start_timestamp;
639 }
640
642}
void TimestampDifference(TimestampTz start_time, TimestampTz stop_time, long *secs, int *microsecs)
Definition timestamp.c:1715
TimestampTz GetCurrentTimestamp(void)
Definition timestamp.c:1639
bool pgstat_track_activities
int64 TimestampTz
Definition timestamp.h:39
const void size_t len
#define pgstat_count_conn_txn_idle_time(n)
Definition pgstat.h:664
#define pgstat_count_conn_active_time(n)
Definition pgstat.h:662
int64 PgStat_Counter
Definition pgstat.h:71
PGPROC * MyProc
Definition proc.c:71
Definition proc.h:179
uint32 wait_event_info
Definition proc.h:378
TimestampTz GetCurrentStatementStartTimestamp(void)
Definition xact.c:881

References fb(), GetCurrentStatementStartTimestamp(), GetCurrentTimestamp(), INT64CONST, len, memcpy(), 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, STATE_DISABLED, STATE_FASTPATH, STATE_IDLEINTRANSACTION, STATE_IDLEINTRANSACTION_ABORTED, STATE_RUNNING, TimestampDifference(), 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(), DataChecksumsWorkerMain(), 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(), ProcessDatabase(), ProcessSingleRelationByOid(), ProcessSingleRelationFork(), WaitForAllTransactionsToFinish(), and worker_spi_main().

◆ pgstat_report_appname()

void pgstat_report_appname ( const char appname)
extern

Definition at line 729 of file backend_status.c.

730{
732 int len;
733
734 if (!beentry)
735 return;
736
737 /* This should be unnecessary if GUC did its job, but be safe */
738 len = pg_mbcliplen(appname, strlen(appname), NAMEDATALEN - 1);
739
740 /*
741 * Update my status entry, following the protocol of bumping
742 * st_changecount before and after. We use a volatile pointer here to
743 * ensure the compiler doesn't try to get cute.
744 */
746
747 memcpy(beentry->st_appname, appname, len);
748 beentry->st_appname[len] = '\0';
749
751}

References fb(), len, memcpy(), MyBEEntry, NAMEDATALEN, pg_mbcliplen(), PGSTAT_BEGIN_WRITE_ACTIVITY, and PGSTAT_END_WRITE_ACTIVITY.

Referenced by assign_application_name(), and pgstat_bestart_final().

◆ pgstat_report_plan_id()

void pgstat_report_plan_id ( int64  plan_id,
bool  force 
)
extern

Definition at line 690 of file backend_status.c.

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

References fb(), MyBEEntry, PGSTAT_BEGIN_WRITE_ACTIVITY, PGSTAT_END_WRITE_ACTIVITY, and pgstat_track_activities.

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

◆ pgstat_report_query_id()

void pgstat_report_query_id ( int64  query_id,
bool  force 
)
extern

Definition at line 651 of file backend_status.c.

652{
654
655 /*
656 * if track_activities is disabled, st_query_id should already have been
657 * reset
658 */
660 return;
661
662 /*
663 * We only report the top-level query identifiers. The stored query_id is
664 * reset when a backend calls pgstat_report_activity(STATE_RUNNING), or
665 * with an explicit call to this function using the force flag. If the
666 * saved query identifier is not zero it means that it's not a top-level
667 * command, so ignore the one provided unless it's an explicit call to
668 * reset the identifier.
669 */
670 if (beentry->st_query_id != INT64CONST(0) && !force)
671 return;
672
673 /*
674 * Update my status entry, following the protocol of bumping
675 * st_changecount before and after. We use a volatile pointer here to
676 * ensure the compiler doesn't try to get cute.
677 */
679 beentry->st_query_id = query_id;
681}

References fb(), INT64CONST, MyBEEntry, PGSTAT_BEGIN_WRITE_ACTIVITY, PGSTAT_END_WRITE_ACTIVITY, and pgstat_track_activities.

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_tempfile()

void pgstat_report_tempfile ( size_t  filesize)
extern

Definition at line 221 of file pgstat_database.c.

222{
224
226 return;
227
229 dbent->temp_bytes += filesize;
230 dbent->temp_files++;
231}
bool pgstat_track_counts
Definition pgstat.c:204
PgStat_StatDBEntry * pgstat_prep_database_pending(Oid dboid)

References fb(), MyDatabaseId, pgstat_prep_database_pending(), and pgstat_track_counts.

Referenced by ReportTemporaryFileUsage().

◆ pgstat_report_xact_timestamp()

void pgstat_report_xact_timestamp ( TimestampTz  tstamp)
extern

Definition at line 758 of file backend_status.c.

759{
761
763 return;
764
765 /*
766 * Update my status entry, following the protocol of bumping
767 * st_changecount before and after. We use a volatile pointer here to
768 * ensure the compiler doesn't try to get cute.
769 */
771
772 beentry->st_xact_start_timestamp = tstamp;
773
775}

References fb(), MyBEEntry, PGSTAT_BEGIN_WRITE_ACTIVITY, PGSTAT_END_WRITE_ACTIVITY, and pgstat_track_activities.

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

Variable Documentation

◆ MyBEEntry

◆ pgstat_track_activities

◆ pgstat_track_activity_query_size