3 * Definitions related to backend status reporting
5 * Copyright (c) 2001-2022, PostgreSQL Global Development Group
7 * src/include/utils/backend_status.h
10 #ifndef BACKEND_STATUS_H
11 #define BACKEND_STATUS_H
13 #include "datatype/timestamp.h"
14 #include "libpq/pqcomm.h"
15 #include "miscadmin.h" /* for BackendType */
16 #include "utils/backend_progress.h"
23 typedef enum BackendState
28 STATE_IDLEINTRANSACTION
,
30 STATE_IDLEINTRANSACTION_ABORTED
,
36 * Shared-memory data structures
43 * For each backend, we keep the SSL status in a separate struct, that
44 * is only filled in if SSL is enabled.
46 * All char arrays must be null-terminated.
48 typedef struct PgBackendSSLStatus
50 /* Information about SSL connection */
52 char ssl_version
[NAMEDATALEN
];
53 char ssl_cipher
[NAMEDATALEN
];
54 char ssl_client_dn
[NAMEDATALEN
];
57 * serial number is max "20 octets" per RFC 5280, so this size should be
60 char ssl_client_serial
[NAMEDATALEN
];
62 char ssl_issuer_dn
[NAMEDATALEN
];
68 * For each backend, we keep the GSS status in a separate struct, that
69 * is only filled in if GSS is enabled.
71 * All char arrays must be null-terminated.
73 typedef struct PgBackendGSSStatus
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 */
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 this is unrelated to the
89 * cumulative stats system (i.e. pgstat.c et al).
91 * Each auxiliary process also maintains a PgBackendStatus struct in shared
95 typedef struct PgBackendStatus
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.
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.
115 /* The entry is valid iff st_procpid > 0, unused if st_procpid == 0 */
118 /* Type of backends */
119 BackendType st_backendType
;
121 /* Times when current backend, transaction, and activity started */
122 TimestampTz st_proc_start_timestamp
;
123 TimestampTz st_xact_start_timestamp
;
124 TimestampTz st_activity_start_timestamp
;
125 TimestampTz st_state_start_timestamp
;
127 /* Database OID, owning user's OID, connection client address */
130 SockAddr st_clientaddr
;
131 char *st_clienthostname
; /* MUST be null-terminated */
133 /* Information about SSL connection */
135 PgBackendSSLStatus
*st_sslstatus
;
137 /* Information about GSSAPI connection */
139 PgBackendGSSStatus
*st_gssstatus
;
142 BackendState st_state
;
144 /* application name; MUST be null-terminated */
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.
154 char *st_activity_raw
;
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.
165 ProgressCommandType st_progress_command
;
166 Oid st_progress_command_target
;
167 int64 st_progress_param
[PGSTAT_NUM_PROGRESS_PARAM
];
169 /* query identifier, optionally computed using post_parse_analyze_hook */
175 * Macros to load and store st_changecount with appropriate memory barriers.
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
186 * Reader logic should follow this sketch:
190 * int before_ct, after_ct;
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))
197 * CHECK_FOR_INTERRUPTS();
200 * For extra safety, we generally use volatile beentry pointers, although
201 * the memory barriers should theoretically be sufficient.
203 #define PGSTAT_BEGIN_WRITE_ACTIVITY(beentry) \
205 START_CRIT_SECTION(); \
206 (beentry)->st_changecount++; \
207 pg_write_barrier(); \
210 #define PGSTAT_END_WRITE_ACTIVITY(beentry) \
212 pg_write_barrier(); \
213 (beentry)->st_changecount++; \
214 Assert(((beentry)->st_changecount & 1) == 0); \
215 END_CRIT_SECTION(); \
218 #define pgstat_begin_read_activity(beentry, before_changecount) \
220 (before_changecount) = (beentry)->st_changecount; \
224 #define pgstat_end_read_activity(beentry, after_changecount) \
227 (after_changecount) = (beentry)->st_changecount; \
230 #define pgstat_read_activity_complete(before_changecount, after_changecount) \
231 ((before_changecount) == (after_changecount) && \
232 ((before_changecount) & 1) == 0)
236 * LocalPgBackendStatus
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.
243 typedef struct LocalPgBackendStatus
246 * Local version of the backend status entry.
248 PgBackendStatus backendStatus
;
251 * The xid of the current transaction if available, InvalidTransactionId
254 TransactionId backend_xid
;
257 * The xmin of the current session if available, InvalidTransactionId if
260 TransactionId backend_xmin
;
261 } LocalPgBackendStatus
;
268 extern PGDLLIMPORT
bool pgstat_track_activities
;
269 extern PGDLLIMPORT
int pgstat_track_activity_query_size
;
273 * Other global variables
276 extern PGDLLIMPORT PgBackendStatus
*MyBEEntry
;
280 * Functions called from postmaster
283 extern Size
BackendStatusShmemSize(void);
284 extern void CreateSharedBackendStatus(void);
288 * Functions called from backends
292 /* Initialization functions */
293 extern void pgstat_beinit(void);
294 extern void pgstat_bestart(void);
296 extern void pgstat_clear_backend_activity_snapshot(void);
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
,
307 extern uint64
pgstat_get_my_query_id(void);
311 * Support functions for the SQL-callable functions to
312 * generate the pgstat* views.
315 extern int pgstat_fetch_stat_numbackends(void);
316 extern PgBackendStatus
*pgstat_fetch_stat_beentry(int beid
);
317 extern LocalPgBackendStatus
*pgstat_fetch_stat_local_beentry(int beid
);
318 extern char *pgstat_clip_activity(const char *raw_activity
);
321 #endif /* BACKEND_STATUS_H */