codekingpro/portable-devtools
115k
1/* ----------2 * backend_status.h3 * Definitions related to backend status reporting4 *5 * Copyright (c) 2001-2023, PostgreSQL Global Development Group6 *7 * src/include/utils/backend_status.h8 * ----------9 */10#ifndef BACKEND_STATUS_H11#define BACKEND_STATUS_H12 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 states22 * ----------23 */24typedef enum BackendState25{26 STATE_UNDEFINED,27 STATE_IDLE,28 STATE_RUNNING,29 STATE_IDLEINTRANSACTION,30 STATE_FASTPATH,31 STATE_IDLEINTRANSACTION_ABORTED,32 STATE_DISABLED33} BackendState;34 35 36/* ----------37 * Shared-memory data structures38 * ----------39 */40 41/*42 * PgBackendSSLStatus43 *44 * For each backend, we keep the SSL status in a separate struct, that45 * is only filled in if SSL is enabled.46 *47 * All char arrays must be null-terminated.48 */49typedef struct PgBackendSSLStatus50{51 /* Information about SSL connection */52 int ssl_bits;53 char ssl_version[NAMEDATALEN];54 char ssl_cipher[NAMEDATALEN];55 char ssl_client_dn[NAMEDATALEN];56 57 /*58 * serial number is max "20 octets" per RFC 5280, so this size should be59 * fine60 */61 char ssl_client_serial[NAMEDATALEN];62 63 char ssl_issuer_dn[NAMEDATALEN];64} PgBackendSSLStatus;65 66/*67 * PgBackendGSSStatus68 *69 * For each backend, we keep the GSS status in a separate struct, that70 * is only filled in if GSS is enabled.71 *72 * All char arrays must be null-terminated.73 */74typedef struct PgBackendGSSStatus75{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 82} PgBackendGSSStatus;83 84 85/* ----------86 * PgBackendStatus87 *88 * Each live backend maintains a PgBackendStatus struct in shared memory89 * showing its current activity. (The structs are allocated according to90 * BackendId, but that is not critical.) Note that this is unrelated to the91 * cumulative stats system (i.e. pgstat.c et al).92 *93 * Each auxiliary process also maintains a PgBackendStatus struct in shared94 * memory.95 * ----------96 */97typedef struct PgBackendStatus98{99 /*100 * To avoid locking overhead, we use the following protocol: a backend101 * increments st_changecount before modifying its entry, and again after102 * finishing a modification. A would-be reader should note the value of103 * st_changecount, copy the entry into private memory, then check104 * 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 cheap106 * while reads are potentially expensive, but that's the tradeoff we want.107 *108 * The above protocol needs memory barriers to ensure that the apparent109 * order of execution is as it desires. Otherwise, for example, the CPU110 * might rearrange the code so that st_changecount is incremented twice111 * before the modification on a machine with weak memory ordering. Hence,112 * use the macros defined below for manipulating st_changecount, rather113 * than touching it directly.114 */115 int st_changecount;116 117 /* The entry is valid iff st_procpid > 0, unused if st_procpid == 0 */118 int st_procpid;119 120 /* Type of backends */121 BackendType st_backendType;122 123 /* Times when current backend, transaction, and activity started */124 TimestampTz st_proc_start_timestamp;125 TimestampTz st_xact_start_timestamp;126 TimestampTz st_activity_start_timestamp;127 TimestampTz st_state_start_timestamp;128 129 /* Database OID, owning user's OID, connection client address */130 Oid st_databaseid;131 Oid st_userid;132 SockAddr st_clientaddr;133 char *st_clienthostname; /* MUST be null-terminated */134 135 /* Information about SSL connection */136 bool st_ssl;137 PgBackendSSLStatus *st_sslstatus;138 139 /* Information about GSSAPI connection */140 bool st_gss;141 PgBackendGSSStatus *st_gssstatus;142 143 /* current state */144 BackendState st_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 string151 * possibly is truncated in the middle of a multi-byte character. As152 * activity strings are stored more frequently than read, that allows to153 * move the cost of correct truncation to the display side. Use154 * pgstat_clip_activity() to truncate correctly.155 */156 char *st_activity_raw;157 158 /*159 * Command progress reporting. Any command which wishes can advertise160 * 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 the163 * command targets (we assume there's just one, as this is meant for164 * utility commands), but the meaning of each element in the165 * st_progress_param array is command-specific.166 */167 ProgressCommandType st_progress_command;168 Oid st_progress_command_target;169 int64 st_progress_param[PGSTAT_NUM_PROGRESS_PARAM];170 171 /* query identifier, optionally computed using post_parse_analyze_hook */172 uint64 st_query_id;173} PgBackendStatus;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 be183 * 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 will186 * 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, although203 * 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 * LocalPgBackendStatus239 *240 * When we build the backend status array, we use LocalPgBackendStatus to be241 * able to add new values to the struct when needed without adding new fields242 * to the shared memory. It contains the backend status as a first member.243 * ----------244 */245typedef struct LocalPgBackendStatus246{247 /*248 * Local version of the backend status entry.249 */250 PgBackendStatus backendStatus;251 252 /*253 * The backend ID. For auxiliary processes, this will be set to a value254 * greater than MaxBackends (since auxiliary processes do not have proper255 * backend IDs).256 */257 BackendId backend_id;258 259 /*260 * The xid of the current transaction if available, InvalidTransactionId261 * if not.262 */263 TransactionId backend_xid;264 265 /*266 * The xmin of the current session if available, InvalidTransactionId if267 * not.268 */269 TransactionId backend_xmin;270 271 /*272 * Number of cached subtransactions in the current session.273 */274 int backend_subxact_count;275 276 /*277 * The number of subtransactions in the current session which exceeded the278 * cached subtransaction limit.279 */280 bool backend_subxact_overflowed;281} LocalPgBackendStatus;282 283 284/* ----------285 * GUC parameters286 * ----------287 */288extern PGDLLIMPORT bool pgstat_track_activities;289extern PGDLLIMPORT int pgstat_track_activity_query_size;290 291 292/* ----------293 * Other global variables294 * ----------295 */296extern PGDLLIMPORT PgBackendStatus *MyBEEntry;297 298 299/* ----------300 * Functions called from postmaster301 * ----------302 */303extern Size BackendStatusShmemSize(void);304extern void CreateSharedBackendStatus(void);305 306 307/* ----------308 * Functions called from backends309 * ----------310 */311 312/* Initialization functions */313extern void pgstat_beinit(void);314extern void pgstat_bestart(void);315 316extern void pgstat_clear_backend_activity_snapshot(void);317 318/* Activity reporting functions */319extern void pgstat_report_activity(BackendState state, const char *cmd_str);320extern void pgstat_report_query_id(uint64 query_id, bool force);321extern void pgstat_report_tempfile(size_t filesize);322extern void pgstat_report_appname(const char *appname);323extern void pgstat_report_xact_timestamp(TimestampTz tstamp);324extern const char *pgstat_get_backend_current_activity(int pid, bool checkUser);325extern const char *pgstat_get_crashed_backend_activity(int pid, char *buffer,326 int buflen);327extern uint64 pgstat_get_my_query_id(void);328 329 330/* ----------331 * Support functions for the SQL-callable functions to332 * generate the pgstat* views.333 * ----------334 */335extern int pgstat_fetch_stat_numbackends(void);336extern PgBackendStatus *pgstat_get_beentry_by_backend_id(BackendId beid);337extern LocalPgBackendStatus *pgstat_get_local_beentry_by_backend_id(BackendId beid);338extern LocalPgBackendStatus *pgstat_get_local_beentry_by_index(int idx);339extern char *pgstat_clip_activity(const char *raw_activity);340 341 342#endif /* BACKEND_STATUS_H */343 