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