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-2022, 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 
82 
83 
84 /* ----------
85  * PgBackendStatus
86  *
87  * Each live backend maintains a PgBackendStatus struct in shared memory
88  * showing its current activity. (The structs are allocated according to
89  * BackendId, but that is not critical.) Note that this is unrelated to the
90  * cumulative stats system (i.e. pgstat.c et al).
91  *
92  * Each auxiliary process also maintains a PgBackendStatus struct in shared
93  * memory.
94  * ----------
95  */
96 typedef struct PgBackendStatus
97 {
98  /*
99  * To avoid locking overhead, we use the following protocol: a backend
100  * increments st_changecount before modifying its entry, and again after
101  * finishing a modification. A would-be reader should note the value of
102  * st_changecount, copy the entry into private memory, then check
103  * st_changecount again. If the value hasn't changed, and if it's even,
104  * the copy is valid; otherwise start over. This makes updates cheap
105  * while reads are potentially expensive, but that's the tradeoff we want.
106  *
107  * The above protocol needs memory barriers to ensure that the apparent
108  * order of execution is as it desires. Otherwise, for example, the CPU
109  * might rearrange the code so that st_changecount is incremented twice
110  * before the modification on a machine with weak memory ordering. Hence,
111  * use the macros defined below for manipulating st_changecount, rather
112  * than touching it directly.
113  */
115 
116  /* The entry is valid iff st_procpid > 0, unused if st_procpid == 0 */
118 
119  /* Type of backends */
121 
122  /* Times when current backend, transaction, and activity started */
127 
128  /* Database OID, owning user's OID, connection client address */
132  char *st_clienthostname; /* MUST be null-terminated */
133 
134  /* Information about SSL connection */
135  bool st_ssl;
137 
138  /* Information about GSSAPI connection */
139  bool st_gss;
141 
142  /* current state */
144 
145  /* application name; MUST be null-terminated */
146  char *st_appname;
147 
148  /*
149  * Current command string; MUST be null-terminated. Note that this string
150  * possibly is truncated in the middle of a multi-byte character. As
151  * activity strings are stored more frequently than read, that allows to
152  * move the cost of correct truncation to the display side. Use
153  * pgstat_clip_activity() to truncate correctly.
154  */
156 
157  /*
158  * Command progress reporting. Any command which wishes can advertise
159  * that it is running by setting st_progress_command,
160  * st_progress_command_target, and st_progress_param[].
161  * st_progress_command_target should be the OID of the relation which the
162  * command targets (we assume there's just one, as this is meant for
163  * utility commands), but the meaning of each element in the
164  * st_progress_param array is command-specific.
165  */
169 
170  /* query identifier, optionally computed using post_parse_analyze_hook */
171  uint64 st_query_id;
173 
174 
175 /*
176  * Macros to load and store st_changecount with appropriate memory barriers.
177  *
178  * Use PGSTAT_BEGIN_WRITE_ACTIVITY() before, and PGSTAT_END_WRITE_ACTIVITY()
179  * after, modifying the current process's PgBackendStatus data. Note that,
180  * since there is no mechanism for cleaning up st_changecount after an error,
181  * THESE MACROS FORM A CRITICAL SECTION. Any error between them will be
182  * promoted to PANIC, causing a database restart to clean up shared memory!
183  * Hence, keep the critical section as short and straight-line as possible.
184  * Aside from being safer, that minimizes the window in which readers will
185  * have to loop.
186  *
187  * Reader logic should follow this sketch:
188  *
189  * for (;;)
190  * {
191  * int before_ct, after_ct;
192  *
193  * pgstat_begin_read_activity(beentry, before_ct);
194  * ... copy beentry data to local memory ...
195  * pgstat_end_read_activity(beentry, after_ct);
196  * if (pgstat_read_activity_complete(before_ct, after_ct))
197  * break;
198  * CHECK_FOR_INTERRUPTS();
199  * }
200  *
201  * For extra safety, we generally use volatile beentry pointers, although
202  * the memory barriers should theoretically be sufficient.
203  */
204 #define PGSTAT_BEGIN_WRITE_ACTIVITY(beentry) \
205  do { \
206  START_CRIT_SECTION(); \
207  (beentry)->st_changecount++; \
208  pg_write_barrier(); \
209  } while (0)
210 
211 #define PGSTAT_END_WRITE_ACTIVITY(beentry) \
212  do { \
213  pg_write_barrier(); \
214  (beentry)->st_changecount++; \
215  Assert(((beentry)->st_changecount & 1) == 0); \
216  END_CRIT_SECTION(); \
217  } while (0)
218 
219 #define pgstat_begin_read_activity(beentry, before_changecount) \
220  do { \
221  (before_changecount) = (beentry)->st_changecount; \
222  pg_read_barrier(); \
223  } while (0)
224 
225 #define pgstat_end_read_activity(beentry, after_changecount) \
226  do { \
227  pg_read_barrier(); \
228  (after_changecount) = (beentry)->st_changecount; \
229  } while (0)
230 
231 #define pgstat_read_activity_complete(before_changecount, after_changecount) \
232  ((before_changecount) == (after_changecount) && \
233  ((before_changecount) & 1) == 0)
234 
235 
236 /* ----------
237  * LocalPgBackendStatus
238  *
239  * When we build the backend status array, we use LocalPgBackendStatus to be
240  * able to add new values to the struct when needed without adding new fields
241  * to the shared memory. It contains the backend status as a first member.
242  * ----------
243  */
244 typedef struct LocalPgBackendStatus
245 {
246  /*
247  * Local version of the backend status entry.
248  */
250 
251  /*
252  * The backend ID. For auxiliary processes, this will be set to a value
253  * greater than MaxBackends (since auxiliary processes do not have proper
254  * backend IDs).
255  */
257 
258  /*
259  * The xid of the current transaction if available, InvalidTransactionId
260  * if not.
261  */
263 
264  /*
265  * The xmin of the current session if available, InvalidTransactionId if
266  * not.
267  */
270 
271 
272 /* ----------
273  * GUC parameters
274  * ----------
275  */
278 
279 
280 /* ----------
281  * Other global variables
282  * ----------
283  */
285 
286 
287 /* ----------
288  * Functions called from postmaster
289  * ----------
290  */
291 extern Size BackendStatusShmemSize(void);
292 extern void CreateSharedBackendStatus(void);
293 
294 
295 /* ----------
296  * Functions called from backends
297  * ----------
298  */
299 
300 /* Initialization functions */
301 extern void pgstat_beinit(void);
302 extern void pgstat_bestart(void);
303 
305 
306 /* Activity reporting functions */
307 extern void pgstat_report_activity(BackendState state, const char *cmd_str);
308 extern void pgstat_report_query_id(uint64 query_id, bool force);
309 extern void pgstat_report_tempfile(size_t filesize);
310 extern void pgstat_report_appname(const char *appname);
311 extern void pgstat_report_xact_timestamp(TimestampTz tstamp);
312 extern const char *pgstat_get_backend_current_activity(int pid, bool checkUser);
313 extern const char *pgstat_get_crashed_backend_activity(int pid, char *buffer,
314  int buflen);
315 extern uint64 pgstat_get_my_query_id(void);
316 
317 
318 /* ----------
319  * Support functions for the SQL-callable functions to
320  * generate the pgstat* views.
321  * ----------
322  */
323 extern int pgstat_fetch_stat_numbackends(void);
326 extern char *pgstat_clip_activity(const char *raw_activity);
327 
328 
329 #endif /* BACKEND_STATUS_H */
#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
struct LocalPgBackendStatus LocalPgBackendStatus
void CreateSharedBackendStatus(void)
BackendState
@ STATE_UNDEFINED
@ STATE_IDLEINTRANSACTION_ABORTED
@ STATE_IDLE
@ STATE_IDLEINTRANSACTION
@ STATE_DISABLED
@ STATE_FASTPATH
@ STATE_RUNNING
LocalPgBackendStatus * pgstat_fetch_stat_local_beentry(int beid)
PGDLLIMPORT int pgstat_track_activity_query_size
void pgstat_report_query_id(uint64 query_id, bool force)
struct PgBackendStatus PgBackendStatus
PgBackendStatus * pgstat_fetch_stat_beentry(BackendId beid)
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)
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:1288
uint32 TransactionId
Definition: c.h:588
size_t Size
Definition: c.h:541
int64 TimestampTz
Definition: timestamp.h:39
BackendType
Definition: miscadmin.h:317
#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:318