PostgreSQL Source Code git master
backend_status.h
Go to the documentation of this file.
1/* ----------
2 * backend_status.h
3 * Definitions related to backend status reporting
4 *
5 * Copyright (c) 2001-2025, PostgreSQL Global Development Group
6 *
7 * src/include/utils/backend_status.h
8 * ----------
9 */
10#ifndef BACKEND_STATUS_H
11#define BACKEND_STATUS_H
12
13#include "datatype/timestamp.h"
14#include "libpq/pqcomm.h"
15#include "miscadmin.h" /* for BackendType */
16#include "storage/procnumber.h"
18
19
20/* ----------
21 * Backend states
22 * ----------
23 */
24typedef enum BackendState
25{
35
36
37/* ----------
38 * Shared-memory data structures
39 * ----------
40 */
41
42/*
43 * PgBackendSSLStatus
44 *
45 * For each backend, we keep the SSL status in a separate struct, that
46 * is only filled in if SSL is enabled.
47 *
48 * All char arrays must be null-terminated.
49 */
50typedef struct PgBackendSSLStatus
51{
52 /* Information about SSL connection */
57
58 /*
59 * serial number is max "20 octets" per RFC 5280, so this size should be
60 * fine
61 */
63
66
67/*
68 * PgBackendGSSStatus
69 *
70 * For each backend, we keep the GSS status in a separate struct, that
71 * is only filled in if GSS is enabled.
72 *
73 * All char arrays must be null-terminated.
74 */
75typedef struct PgBackendGSSStatus
76{
77 /* Information about GSSAPI connection */
78 char gss_princ[NAMEDATALEN]; /* GSSAPI Principal used to auth */
79 bool gss_auth; /* If GSSAPI authentication was used */
80 bool gss_enc; /* If encryption is being used */
81 bool gss_delegation; /* If credentials delegated */
82
84
85
86/* ----------
87 * PgBackendStatus
88 *
89 * Each live backend maintains a PgBackendStatus struct in shared memory
90 * showing its current activity. (The structs are allocated according to
91 * ProcNumber, but that is not critical.) Note that this is unrelated to the
92 * cumulative stats system (i.e. pgstat.c et al).
93 *
94 * Each auxiliary process also maintains a PgBackendStatus struct in shared
95 * memory.
96 * ----------
97 */
98typedef struct PgBackendStatus
99{
100 /*
101 * To avoid locking overhead, we use the following protocol: a backend
102 * increments st_changecount before modifying its entry, and again after
103 * finishing a modification. A would-be reader should note the value of
104 * st_changecount, copy the entry into private memory, then check
105 * st_changecount again. If the value hasn't changed, and if it's even,
106 * the copy is valid; otherwise start over. This makes updates cheap
107 * while reads are potentially expensive, but that's the tradeoff we want.
108 *
109 * The above protocol needs memory barriers to ensure that the apparent
110 * order of execution is as it desires. Otherwise, for example, the CPU
111 * might rearrange the code so that st_changecount is incremented twice
112 * before the modification on a machine with weak memory ordering. Hence,
113 * use the macros defined below for manipulating st_changecount, rather
114 * than touching it directly.
115 */
117
118 /* The entry is valid iff st_procpid > 0, unused if st_procpid == 0 */
120
121 /* Type of backends */
123
124 /* Times when current backend, transaction, and activity started */
129
130 /* Database OID, owning user's OID, connection client address */
134 char *st_clienthostname; /* MUST be null-terminated */
135
136 /* Information about SSL connection */
137 bool st_ssl;
139
140 /* Information about GSSAPI connection */
141 bool st_gss;
143
144 /* current state */
146
147 /* application name; MUST be null-terminated */
149
150 /*
151 * Current command string; MUST be null-terminated. Note that this string
152 * possibly is truncated in the middle of a multi-byte character. As
153 * activity strings are stored more frequently than read, that allows to
154 * move the cost of correct truncation to the display side. Use
155 * pgstat_clip_activity() to truncate correctly.
156 */
158
159 /*
160 * Command progress reporting. Any command which wishes can advertise
161 * that it is running by setting st_progress_command,
162 * st_progress_command_target, and st_progress_param[].
163 * st_progress_command_target should be the OID of the relation which the
164 * command targets (we assume there's just one, as this is meant for
165 * utility commands), but the meaning of each element in the
166 * st_progress_param array is command-specific.
167 */
171
172 /* query identifier, optionally computed using post_parse_analyze_hook */
174
175 /* plan identifier, optionally computed using planner_hook */
178
179
180/*
181 * Macros to load and store st_changecount with appropriate memory barriers.
182 *
183 * Use PGSTAT_BEGIN_WRITE_ACTIVITY() before, and PGSTAT_END_WRITE_ACTIVITY()
184 * after, modifying the current process's PgBackendStatus data. Note that,
185 * since there is no mechanism for cleaning up st_changecount after an error,
186 * THESE MACROS FORM A CRITICAL SECTION. Any error between them will be
187 * promoted to PANIC, causing a database restart to clean up shared memory!
188 * Hence, keep the critical section as short and straight-line as possible.
189 * Aside from being safer, that minimizes the window in which readers will
190 * have to loop.
191 *
192 * Reader logic should follow this sketch:
193 *
194 * for (;;)
195 * {
196 * int before_ct, after_ct;
197 *
198 * pgstat_begin_read_activity(beentry, before_ct);
199 * ... copy beentry data to local memory ...
200 * pgstat_end_read_activity(beentry, after_ct);
201 * if (pgstat_read_activity_complete(before_ct, after_ct))
202 * break;
203 * CHECK_FOR_INTERRUPTS();
204 * }
205 *
206 * For extra safety, we generally use volatile beentry pointers, although
207 * the memory barriers should theoretically be sufficient.
208 */
209#define PGSTAT_BEGIN_WRITE_ACTIVITY(beentry) \
210 do { \
211 START_CRIT_SECTION(); \
212 (beentry)->st_changecount++; \
213 pg_write_barrier(); \
214 } while (0)
215
216#define PGSTAT_END_WRITE_ACTIVITY(beentry) \
217 do { \
218 pg_write_barrier(); \
219 (beentry)->st_changecount++; \
220 Assert(((beentry)->st_changecount & 1) == 0); \
221 END_CRIT_SECTION(); \
222 } while (0)
223
224#define pgstat_begin_read_activity(beentry, before_changecount) \
225 do { \
226 (before_changecount) = (beentry)->st_changecount; \
227 pg_read_barrier(); \
228 } while (0)
229
230#define pgstat_end_read_activity(beentry, after_changecount) \
231 do { \
232 pg_read_barrier(); \
233 (after_changecount) = (beentry)->st_changecount; \
234 } while (0)
235
236#define pgstat_read_activity_complete(before_changecount, after_changecount) \
237 ((before_changecount) == (after_changecount) && \
238 ((before_changecount) & 1) == 0)
239
240
241/* ----------
242 * LocalPgBackendStatus
243 *
244 * When we build the backend status array, we use LocalPgBackendStatus to be
245 * able to add new values to the struct when needed without adding new fields
246 * to the shared memory. It contains the backend status as a first member.
247 * ----------
248 */
250{
251 /*
252 * Local version of the backend status entry.
253 */
255
256 /*
257 * The proc number.
258 */
260
261 /*
262 * The xid of the current transaction if available, InvalidTransactionId
263 * if not.
264 */
266
267 /*
268 * The xmin of the current session if available, InvalidTransactionId if
269 * not.
270 */
272
273 /*
274 * Number of cached subtransactions in the current session.
275 */
277
278 /*
279 * The number of subtransactions in the current session which exceeded the
280 * cached subtransaction limit.
281 */
284
285
286/* ----------
287 * GUC parameters
288 * ----------
289 */
292
293
294/* ----------
295 * Other global variables
296 * ----------
297 */
299
300
301/* ----------
302 * Functions called from postmaster
303 * ----------
304 */
305extern Size BackendStatusShmemSize(void);
306extern void BackendStatusShmemInit(void);
307
308
309/* ----------
310 * Functions called from backends
311 * ----------
312 */
313
314/* Initialization functions */
315extern void pgstat_beinit(void);
316extern void pgstat_bestart_initial(void);
317extern void pgstat_bestart_security(void);
318extern void pgstat_bestart_final(void);
319
321
322/* Activity reporting functions */
323extern void pgstat_report_activity(BackendState state, const char *cmd_str);
324extern void pgstat_report_query_id(uint64 query_id, bool force);
325extern void pgstat_report_plan_id(uint64 plan_id, bool force);
326extern void pgstat_report_tempfile(size_t filesize);
327extern void pgstat_report_appname(const char *appname);
328extern void pgstat_report_xact_timestamp(TimestampTz tstamp);
329extern const char *pgstat_get_backend_current_activity(int pid, bool checkUser);
330extern const char *pgstat_get_crashed_backend_activity(int pid, char *buffer,
331 int buflen);
332extern uint64 pgstat_get_my_query_id(void);
333extern uint64 pgstat_get_my_plan_id(void);
335
336
337/* ----------
338 * Support functions for the SQL-callable functions to
339 * generate the pgstat* views.
340 * ----------
341 */
342extern int pgstat_fetch_stat_numbackends(void);
346extern char *pgstat_clip_activity(const char *raw_activity);
347
348
349#endif /* BACKEND_STATUS_H */
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:262
#define PGSTAT_NUM_PROGRESS_PARAM
ProgressCommandType
int pgstat_fetch_stat_numbackends(void)
uint64 pgstat_get_my_query_id(void)
struct PgBackendGSSStatus PgBackendGSSStatus
LocalPgBackendStatus * pgstat_get_local_beentry_by_proc_number(ProcNumber procNumber)
void pgstat_clear_backend_activity_snapshot(void)
void pgstat_bestart_security(void)
struct PgBackendSSLStatus PgBackendSSLStatus
void pgstat_bestart_initial(void)
PGDLLIMPORT bool pgstat_track_activities
PGDLLIMPORT PgBackendStatus * MyBEEntry
char * pgstat_clip_activity(const char *raw_activity)
uint64 pgstat_get_my_plan_id(void)
struct LocalPgBackendStatus LocalPgBackendStatus
BackendState
@ STATE_UNDEFINED
@ STATE_IDLEINTRANSACTION_ABORTED
@ STATE_STARTING
@ STATE_IDLE
@ STATE_IDLEINTRANSACTION
@ STATE_DISABLED
@ STATE_FASTPATH
@ STATE_RUNNING
const char * pgstat_get_crashed_backend_activity(int pid, char *buffer, int buflen)
void pgstat_report_plan_id(uint64 plan_id, bool force)
void BackendStatusShmemInit(void)
PGDLLIMPORT int pgstat_track_activity_query_size
LocalPgBackendStatus * pgstat_get_local_beentry_by_index(int idx)
void pgstat_report_query_id(uint64 query_id, bool force)
struct PgBackendStatus PgBackendStatus
void pgstat_report_activity(BackendState state, const char *cmd_str)
BackendType pgstat_get_backend_type_by_proc_number(ProcNumber procNumber)
void pgstat_report_xact_timestamp(TimestampTz tstamp)
PgBackendStatus * pgstat_get_beentry_by_proc_number(ProcNumber procNumber)
void pgstat_beinit(void)
void pgstat_bestart_final(void)
Size BackendStatusShmemSize(void)
void pgstat_report_appname(const char *appname)
const char * pgstat_get_backend_current_activity(int pid, bool checkUser)
void pgstat_report_tempfile(size_t filesize)
#define PGDLLIMPORT
Definition: c.h:1291
int64_t int64
Definition: c.h:499
uint64_t uint64
Definition: c.h:503
uint32 TransactionId
Definition: c.h:623
size_t Size
Definition: c.h:576
int64 TimestampTz
Definition: timestamp.h:39
BackendType
Definition: miscadmin.h:338
#define NAMEDATALEN
unsigned int Oid
Definition: postgres_ext.h:30
int ProcNumber
Definition: procnumber.h:24
TransactionId backend_xid
PgBackendStatus backendStatus
TransactionId backend_xmin
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
PgBackendGSSStatus * st_gssstatus
BackendState st_state
TimestampTz st_activity_start_timestamp
ProgressCommandType st_progress_command
SockAddr st_clientaddr
int64 st_progress_param[PGSTAT_NUM_PROGRESS_PARAM]
PgBackendSSLStatus * st_sslstatus
TimestampTz st_xact_start_timestamp
char * st_clienthostname
Oid st_progress_command_target
Definition: regguts.h:323