PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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_IDLE , STATE_RUNNING , STATE_IDLEINTRANSACTION ,
  STATE_FASTPATH , STATE_IDLEINTRANSACTION_ABORTED , STATE_DISABLED
}
 

Functions

Size BackendStatusShmemSize (void)
 
void BackendStatusShmemInit (void)
 
void pgstat_beinit (void)
 
void pgstat_bestart (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_tempfile (size_t filesize)
 
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)
 
BackendType pgstat_get_backend_type_by_proc_number (ProcNumber procNumber)
 
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)
 
char * pgstat_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; \
pg_read_barrier(); \
} while (0)

Definition at line 220 of file backend_status.h.

◆ PGSTAT_BEGIN_WRITE_ACTIVITY

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

Definition at line 205 of file backend_status.h.

◆ pgstat_end_read_activity

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

Definition at line 226 of file backend_status.h.

◆ PGSTAT_END_WRITE_ACTIVITY

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

Definition at line 212 of file backend_status.h.

◆ pgstat_read_activity_complete

#define pgstat_read_activity_complete (   before_changecount,
  after_changecount 
)
Value:
((before_changecount) == (after_changecount) && \
((before_changecount) & 1) == 0)

Definition at line 232 of file backend_status.h.

Typedef Documentation

◆ BackendState

typedef enum BackendState BackendState

◆ LocalPgBackendStatus

◆ PgBackendGSSStatus

◆ PgBackendSSLStatus

◆ PgBackendStatus

Enumeration Type Documentation

◆ BackendState

Enumerator
STATE_UNDEFINED 
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_IDLE
@ STATE_IDLEINTRANSACTION
@ STATE_DISABLED
@ STATE_FASTPATH
@ STATE_RUNNING

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 */
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:974
size_t Size
Definition: c.h:559
int i
Definition: isn.c:72
#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
static pg_noinline void Size size
Definition: slab.c:607
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(), size, 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: */
90 /* BackendClientHostnameBuffer: */
93 /* BackendActivityBuffer: */
96#ifdef USE_SSL
97 /* BackendSslStatusBuffer: */
100#endif
101#ifdef ENABLE_GSS
102 /* BackendGssStatusBuffer: */
105#endif
106 return size;
107}
Size add_size(Size s1, Size s2)
Definition: shmem.c:488

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

Referenced by CalculateShmemSize().

◆ 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)
#define Assert(condition)
Definition: c.h:812
ProcNumber MyProcNumber
Definition: globals.c:89
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_bestart()

void pgstat_bestart ( void  )

Definition at line 271 of file backend_status.c.

272{
273 volatile PgBackendStatus *vbeentry = MyBEEntry;
274 PgBackendStatus lbeentry;
275#ifdef USE_SSL
276 PgBackendSSLStatus lsslstatus;
277#endif
278#ifdef ENABLE_GSS
279 PgBackendGSSStatus lgssstatus;
280#endif
281
282 /* pgstats state must be initialized from pgstat_beinit() */
283 Assert(vbeentry != NULL);
284
285 /*
286 * To minimize the time spent modifying the PgBackendStatus entry, and
287 * avoid risk of errors inside the critical section, we first copy the
288 * shared-memory struct to a local variable, then modify the data in the
289 * local variable, then copy the local variable back to shared memory.
290 * Only the last step has to be inside the critical section.
291 *
292 * Most of the data we copy from shared memory is just going to be
293 * overwritten, but the struct's not so large that it's worth the
294 * maintenance hassle to copy only the needful fields.
295 */
296 memcpy(&lbeentry,
297 unvolatize(PgBackendStatus *, vbeentry),
298 sizeof(PgBackendStatus));
299
300 /* These structs can just start from zeroes each time, though */
301#ifdef USE_SSL
302 memset(&lsslstatus, 0, sizeof(lsslstatus));
303#endif
304#ifdef ENABLE_GSS
305 memset(&lgssstatus, 0, sizeof(lgssstatus));
306#endif
307
308 /*
309 * Now fill in all the fields of lbeentry, except for strings that are
310 * out-of-line data. Those have to be handled separately, below.
311 */
312 lbeentry.st_procpid = MyProcPid;
313 lbeentry.st_backendType = MyBackendType;
315 lbeentry.st_activity_start_timestamp = 0;
316 lbeentry.st_state_start_timestamp = 0;
317 lbeentry.st_xact_start_timestamp = 0;
318 lbeentry.st_databaseid = MyDatabaseId;
319
320 /* We have userid for client-backends, wal-sender and bgworker processes */
321 if (lbeentry.st_backendType == B_BACKEND
322 || lbeentry.st_backendType == B_WAL_SENDER
323 || lbeentry.st_backendType == B_BG_WORKER)
324 lbeentry.st_userid = GetSessionUserId();
325 else
326 lbeentry.st_userid = InvalidOid;
327
328 /*
329 * We may not have a MyProcPort (eg, if this is the autovacuum process).
330 * If so, use all-zeroes client address, which is dealt with specially in
331 * pg_stat_get_backend_client_addr and pg_stat_get_backend_client_port.
332 */
333 if (MyProcPort)
334 memcpy(&lbeentry.st_clientaddr, &MyProcPort->raddr,
335 sizeof(lbeentry.st_clientaddr));
336 else
337 MemSet(&lbeentry.st_clientaddr, 0, sizeof(lbeentry.st_clientaddr));
338
339#ifdef USE_SSL
341 {
342 lbeentry.st_ssl = true;
349 }
350 else
351 {
352 lbeentry.st_ssl = false;
353 }
354#else
355 lbeentry.st_ssl = false;
356#endif
357
358#ifdef ENABLE_GSS
359 if (MyProcPort && MyProcPort->gss != NULL)
360 {
361 const char *princ = be_gssapi_get_princ(MyProcPort);
362
363 lbeentry.st_gss = true;
367 if (princ)
368 strlcpy(lgssstatus.gss_princ, princ, NAMEDATALEN);
369 }
370 else
371 {
372 lbeentry.st_gss = false;
373 }
374#else
375 lbeentry.st_gss = false;
376#endif
377
378 lbeentry.st_state = STATE_UNDEFINED;
381 lbeentry.st_query_id = UINT64CONST(0);
382
383 /*
384 * we don't zero st_progress_param here to save cycles; nobody should
385 * examine it until st_progress_command has been set to something other
386 * than PROGRESS_COMMAND_INVALID
387 */
388
389 /*
390 * We're ready to enter the critical section that fills the shared-memory
391 * status entry. We follow the protocol of bumping st_changecount before
392 * and after; and make sure it's even afterwards. We use a volatile
393 * pointer here to ensure the compiler doesn't try to get cute.
394 */
396
397 /* make sure we'll memcpy the same st_changecount back */
398 lbeentry.st_changecount = vbeentry->st_changecount;
399
400 memcpy(unvolatize(PgBackendStatus *, vbeentry),
401 &lbeentry,
402 sizeof(PgBackendStatus));
403
404 /*
405 * We can write the out-of-line strings and structs using the pointers
406 * that are in lbeentry; this saves some de-volatilizing messiness.
407 */
408 lbeentry.st_appname[0] = '\0';
412 else
413 lbeentry.st_clienthostname[0] = '\0';
414 lbeentry.st_activity_raw[0] = '\0';
415 /* Also make sure the last byte in each string area is always 0 */
416 lbeentry.st_appname[NAMEDATALEN - 1] = '\0';
417 lbeentry.st_clienthostname[NAMEDATALEN - 1] = '\0';
419
420#ifdef USE_SSL
421 memcpy(lbeentry.st_sslstatus, &lsslstatus, sizeof(PgBackendSSLStatus));
422#endif
423#ifdef ENABLE_GSS
424 memcpy(lbeentry.st_gssstatus, &lgssstatus, sizeof(PgBackendGSSStatus));
425#endif
426
428
429 /* Create the backend statistics entry */
432
433 /* Update app name to current GUC setting */
436}
@ PROGRESS_COMMAND_INVALID
void pgstat_report_appname(const char *appname)
#define PGSTAT_END_WRITE_ACTIVITY(beentry)
#define PGSTAT_BEGIN_WRITE_ACTIVITY(beentry)
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)
#define unvolatize(underlying_type, expr)
Definition: c.h:1201
#define UINT64CONST(x)
Definition: c.h:500
int MyProcPid
Definition: globals.c:46
TimestampTz MyStartTimestamp
Definition: globals.c:48
struct Port * MyProcPort
Definition: globals.c:50
Oid MyDatabaseId
Definition: globals.c:93
char * application_name
Definition: guc_tables.c:543
@ 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:556
BackendType MyBackendType
Definition: miscinit.c:64
void pgstat_create_backend(ProcNumber procnum)
bool pgstat_tracks_backend_bktype(BackendType bktype)
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define InvalidOid
Definition: postgres_ext.h:36
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]
BackendType st_backendType
TimestampTz st_state_start_timestamp
TimestampTz st_proc_start_timestamp
BackendState st_state
TimestampTz st_activity_start_timestamp
ProgressCommandType st_progress_command
SockAddr st_clientaddr
TimestampTz st_xact_start_timestamp
Oid st_progress_command_target
bool ssl_in_use
Definition: libpq-be.h:202
char * remote_hostname
Definition: libpq-be.h:140
void * gss
Definition: libpq-be.h:196
SockAddr raddr
Definition: libpq-be.h:138

References application_name, Assert, B_BACKEND, B_BG_WORKER, B_WAL_SENDER, 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(), GetSessionUserId(), Port::gss, PgBackendGSSStatus::gss_auth, PgBackendGSSStatus::gss_delegation, PgBackendGSSStatus::gss_enc, PgBackendGSSStatus::gss_princ, InvalidOid, MemSet, MyBackendType, MyBEEntry, MyDatabaseId, MyProcNumber, MyProcPid, MyProcPort, MyStartTimestamp, NAMEDATALEN, PGSTAT_BEGIN_WRITE_ACTIVITY, pgstat_create_backend(), PGSTAT_END_WRITE_ACTIVITY, pgstat_report_appname(), pgstat_track_activity_query_size, pgstat_tracks_backend_bktype(), PROGRESS_COMMAND_INVALID, Port::raddr, Port::remote_hostname, 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_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_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_UNDEFINED, strlcpy(), UINT64CONST, and unvolatize.

Referenced by AuxiliaryProcessMainCommon(), and InitPostgres().

◆ pgstat_clear_backend_activity_snapshot()

void pgstat_clear_backend_activity_snapshot ( void  )

Definition at line 469 of file backend_status.c.

470{
471 /* Release memory, if any was allocated */
473 {
476 }
477
478 /* Reset variables */
481}
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 1191 of file backend_status.c.

1192{
1193 char *activity;
1194 int rawlen;
1195 int cliplen;
1196
1197 /*
1198 * Some callers, like pgstat_get_backend_current_activity(), do not
1199 * guarantee that the buffer isn't concurrently modified. We try to take
1200 * care that the buffer is always terminated by a NUL byte regardless, but
1201 * let's still be paranoid about the string's length. In those cases the
1202 * underlying buffer is guaranteed to be pgstat_track_activity_query_size
1203 * large.
1204 */
1205 activity = pnstrdup(raw_activity, pgstat_track_activity_query_size - 1);
1206
1207 /* now double-guaranteed to be NUL terminated */
1208 rawlen = strlen(activity);
1209
1210 /*
1211 * All supported server-encodings make it possible to determine the length
1212 * of a multi-byte character from its first byte (this is not the case for
1213 * client encodings, see GB18030). As st_activity is always stored using
1214 * server encoding, this allows us to perform multi-byte aware truncation,
1215 * even if the string earlier was truncated in the middle of a multi-byte
1216 * character.
1217 */
1218 cliplen = pg_mbcliplen(activity, rawlen,
1220
1221 activity[cliplen] = '\0';
1222
1223 return activity;
1224}
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:1707

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 1175 of file backend_status.c.

1176{
1178
1179 return localNumBackends;
1180}
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 887 of file backend_status.c.

888{
889 PgBackendStatus *beentry;
890 int i;
891
892 beentry = BackendStatusArray;
893 for (i = 1; i <= MaxBackends; i++)
894 {
895 /*
896 * Although we expect the target backend's entry to be stable, that
897 * doesn't imply that anyone else's is. To avoid identifying the
898 * wrong backend, while we check for a match to the desired PID we
899 * must follow the protocol of retrying if st_changecount changes
900 * while we examine the entry, or if it's odd. (This might be
901 * unnecessary, since fetching or storing an int is almost certainly
902 * atomic, but let's play it safe.) We use a volatile pointer here to
903 * ensure the compiler doesn't try to get cute.
904 */
905 volatile PgBackendStatus *vbeentry = beentry;
906 bool found;
907
908 for (;;)
909 {
910 int before_changecount;
911 int after_changecount;
912
913 pgstat_begin_read_activity(vbeentry, before_changecount);
914
915 found = (vbeentry->st_procpid == pid);
916
917 pgstat_end_read_activity(vbeentry, after_changecount);
918
919 if (pgstat_read_activity_complete(before_changecount,
920 after_changecount))
921 break;
922
923 /* Make sure we can break out of loop if stuck... */
925 }
926
927 if (found)
928 {
929 /* Now it is safe to use the non-volatile pointer */
930 if (checkUser && !superuser() && beentry->st_userid != GetUserId())
931 return "<insufficient privilege>";
932 else if (*(beentry->st_activity_raw) == '\0')
933 return "<command string not enabled>";
934 else
935 {
936 /* this'll leak a bit of memory, but that seems acceptable */
937 return pgstat_clip_activity(beentry->st_activity_raw);
938 }
939 }
940
941 beentry++;
942 }
943
944 /* If we get here, caller is in error ... */
945 return "<backend information not available>";
946}
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:517
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 1057 of file backend_status.c.

1058{
1059 volatile PgBackendStatus *status = &BackendStatusArray[procNumber];
1060
1061 /*
1062 * We bypass the changecount mechanism since fetching and storing an int
1063 * is almost certainly atomic.
1064 */
1065 return status->st_backendType;
1066}

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 965 of file backend_status.c.

966{
967 volatile PgBackendStatus *beentry;
968 int i;
969
970 beentry = BackendStatusArray;
971
972 /*
973 * We probably shouldn't get here before shared memory has been set up,
974 * but be safe.
975 */
976 if (beentry == NULL || BackendActivityBuffer == NULL)
977 return NULL;
978
979 for (i = 1; i <= MaxBackends; i++)
980 {
981 if (beentry->st_procpid == pid)
982 {
983 /* Read pointer just once, so it can't change after validation */
984 const char *activity = beentry->st_activity_raw;
985 const char *activity_last;
986
987 /*
988 * We mustn't access activity string before we verify that it
989 * falls within the BackendActivityBuffer. To make sure that the
990 * entire string including its ending is contained within the
991 * buffer, subtract one activity length from the buffer size.
992 */
995
996 if (activity < BackendActivityBuffer ||
997 activity > activity_last)
998 return NULL;
999
1000 /* If no string available, no point in a report */
1001 if (activity[0] == '\0')
1002 return NULL;
1003
1004 /*
1005 * Copy only ASCII-safe characters so we don't run into encoding
1006 * problems when reporting the message; and be sure not to run off
1007 * the end of memory. As only ASCII characters are reported, it
1008 * doesn't seem necessary to perform multibyte aware clipping.
1009 */
1010 ascii_safe_strlcpy(buffer, activity,
1012
1013 return buffer;
1014 }
1015
1016 beentry++;
1017 }
1018
1019 /* PID not found */
1020 return NULL;
1021}
void ascii_safe_strlcpy(char *dest, const char *src, size_t destsiz)
Definition: ascii.c:174
#define Min(x, y)
Definition: c.h:958

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 1155 of file backend_status.c.

1156{
1158
1159 if (idx < 1 || idx > localNumBackends)
1160 return NULL;
1161
1162 return &localBackendStatusTable[idx - 1];
1163}
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 1124 of file backend_status.c.

1125{
1127
1129
1130 /*
1131 * Since the localBackendStatusTable is in order by proc_number, we can
1132 * use bsearch() to search it efficiently.
1133 */
1134 key.proc_number = procNumber;
1137}
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_query_id()

uint64 pgstat_get_my_query_id ( void  )

Definition at line 1029 of file backend_status.c.

1030{
1031 if (!MyBEEntry)
1032 return 0;
1033
1034 /*
1035 * There's no need for a lock around pgstat_begin_read_activity /
1036 * pgstat_end_read_activity here as it's only called from
1037 * pg_stat_get_activity which is already protected, or from the same
1038 * backend which means that there won't be concurrent writes.
1039 */
1040 return MyBEEntry->st_query_id;
1041}

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 
)

Definition at line 505 of file backend_status.c.

506{
507 volatile PgBackendStatus *beentry = MyBEEntry;
508 TimestampTz start_timestamp;
509 TimestampTz current_timestamp;
510 int len = 0;
511
512 TRACE_POSTGRESQL_STATEMENT_STATUS(cmd_str);
513
514 if (!beentry)
515 return;
516
518 {
519 if (beentry->st_state != STATE_DISABLED)
520 {
521 volatile PGPROC *proc = MyProc;
522
523 /*
524 * track_activities is disabled, but we last reported a
525 * non-disabled state. As our final update, change the state and
526 * clear fields we will not be updating anymore.
527 */
529 beentry->st_state = STATE_DISABLED;
530 beentry->st_state_start_timestamp = 0;
531 beentry->st_activity_raw[0] = '\0';
532 beentry->st_activity_start_timestamp = 0;
533 /* st_xact_start_timestamp and wait_event_info are also disabled */
534 beentry->st_xact_start_timestamp = 0;
535 beentry->st_query_id = UINT64CONST(0);
536 proc->wait_event_info = 0;
538 }
539 return;
540 }
541
542 /*
543 * To minimize the time spent modifying the entry, and avoid risk of
544 * errors inside the critical section, fetch all the needed data first.
545 */
546 start_timestamp = GetCurrentStatementStartTimestamp();
547 if (cmd_str != NULL)
548 {
549 /*
550 * Compute length of to-be-stored string unaware of multi-byte
551 * characters. For speed reasons that'll get corrected on read, rather
552 * than computed every write.
553 */
554 len = Min(strlen(cmd_str), pgstat_track_activity_query_size - 1);
555 }
556 current_timestamp = GetCurrentTimestamp();
557
558 /*
559 * If the state has changed from "active" or "idle in transaction",
560 * calculate the duration.
561 */
562 if ((beentry->st_state == STATE_RUNNING ||
563 beentry->st_state == STATE_FASTPATH ||
564 beentry->st_state == STATE_IDLEINTRANSACTION ||
566 state != beentry->st_state)
567 {
568 long secs;
569 int usecs;
570
572 current_timestamp,
573 &secs, &usecs);
574
575 if (beentry->st_state == STATE_RUNNING ||
576 beentry->st_state == STATE_FASTPATH)
577 pgstat_count_conn_active_time((PgStat_Counter) secs * 1000000 + usecs);
578 else
579 pgstat_count_conn_txn_idle_time((PgStat_Counter) secs * 1000000 + usecs);
580 }
581
582 /*
583 * Now update the status entry
584 */
586
587 beentry->st_state = state;
588 beentry->st_state_start_timestamp = current_timestamp;
589
590 /*
591 * If a new query is started, we reset the query identifier as it'll only
592 * be known after parse analysis, to avoid reporting last query's
593 * identifier.
594 */
595 if (state == STATE_RUNNING)
596 beentry->st_query_id = UINT64CONST(0);
597
598 if (cmd_str != NULL)
599 {
600 memcpy((char *) beentry->st_activity_raw, cmd_str, len);
601 beentry->st_activity_raw[len] = '\0';
602 beentry->st_activity_start_timestamp = start_timestamp;
603 }
604
606}
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
int64 TimestampTz
Definition: timestamp.h:39
const void size_t len
#define pgstat_count_conn_txn_idle_time(n)
Definition: pgstat.h:634
#define pgstat_count_conn_active_time(n)
Definition: pgstat.h:632
int64 PgStat_Counter
Definition: pgstat.h:121
PGPROC * MyProc
Definition: proc.c:66
Definition: proc.h:162
uint32 wait_event_info
Definition: proc.h:279
Definition: regguts.h:323
TimestampTz GetCurrentStatementStartTimestamp(void)
Definition: xact.c:878

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_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(), 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 655 of file backend_status.c.

656{
657 volatile PgBackendStatus *beentry = MyBEEntry;
658 int len;
659
660 if (!beentry)
661 return;
662
663 /* This should be unnecessary if GUC did its job, but be safe */
664 len = pg_mbcliplen(appname, strlen(appname), NAMEDATALEN - 1);
665
666 /*
667 * Update my status entry, following the protocol of bumping
668 * st_changecount before and after. We use a volatile pointer here to
669 * ensure the compiler doesn't try to get cute.
670 */
672
673 memcpy((char *) beentry->st_appname, appname, len);
674 beentry->st_appname[len] = '\0';
675
677}

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

◆ pgstat_report_query_id()

void pgstat_report_query_id ( uint64  query_id,
bool  force 
)

Definition at line 615 of file backend_status.c.

616{
617 volatile PgBackendStatus *beentry = MyBEEntry;
618
619 /*
620 * if track_activities is disabled, st_query_id should already have been
621 * reset
622 */
623 if (!beentry || !pgstat_track_activities)
624 return;
625
626 /*
627 * We only report the top-level query identifiers. The stored query_id is
628 * reset when a backend calls pgstat_report_activity(STATE_RUNNING), or
629 * with an explicit call to this function using the force flag. If the
630 * saved query identifier is not zero it means that it's not a top-level
631 * command, so ignore the one provided unless it's an explicit call to
632 * reset the identifier.
633 */
634 if (beentry->st_query_id != 0 && !force)
635 return;
636
637 /*
638 * Update my status entry, following the protocol of bumping
639 * st_changecount before and after. We use a volatile pointer here to
640 * ensure the compiler doesn't try to get cute.
641 */
643 beentry->st_query_id = query_id;
645}

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

void pgstat_report_tempfile ( size_t  filesize)

Definition at line 175 of file pgstat_database.c.

176{
177 PgStat_StatDBEntry *dbent;
178
180 return;
181
183 dbent->temp_bytes += filesize;
184 dbent->temp_files++;
185}
bool pgstat_track_counts
Definition: pgstat.c:204
PgStat_StatDBEntry * pgstat_prep_database_pending(Oid dboid)
PgStat_Counter temp_bytes
Definition: pgstat.h:406
PgStat_Counter temp_files
Definition: pgstat.h:405

References MyDatabaseId, pgstat_prep_database_pending(), pgstat_track_counts, PgStat_StatDBEntry::temp_bytes, and PgStat_StatDBEntry::temp_files.

Referenced by ReportTemporaryFileUsage().

◆ pgstat_report_xact_timestamp()

void pgstat_report_xact_timestamp ( TimestampTz  tstamp)

Definition at line 684 of file backend_status.c.

685{
686 volatile PgBackendStatus *beentry = MyBEEntry;
687
688 if (!pgstat_track_activities || !beentry)
689 return;
690
691 /*
692 * Update my status entry, following the protocol of bumping
693 * st_changecount before and after. We use a volatile pointer here to
694 * ensure the compiler doesn't try to get cute.
695 */
697
698 beentry->st_xact_start_timestamp = tstamp;
699
701}

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

Variable Documentation

◆ MyBEEntry

◆ pgstat_track_activities

◆ pgstat_track_activity_query_size