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