123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321 |
- /* ----------
- * backend_status.h
- * Definitions related to backend status reporting
- *
- * Copyright (c) 2001-2022, PostgreSQL Global Development Group
- *
- * src/include/utils/backend_status.h
- * ----------
- */
- #ifndef BACKEND_STATUS_H
- #define BACKEND_STATUS_H
- #include "datatype/timestamp.h"
- #include "libpq/pqcomm.h"
- #include "miscadmin.h" /* for BackendType */
- #include "utils/backend_progress.h"
- /* ----------
- * Backend states
- * ----------
- */
- typedef enum BackendState
- {
- STATE_UNDEFINED,
- STATE_IDLE,
- STATE_RUNNING,
- STATE_IDLEINTRANSACTION,
- STATE_FASTPATH,
- STATE_IDLEINTRANSACTION_ABORTED,
- STATE_DISABLED
- } BackendState;
- /* ----------
- * Shared-memory data structures
- * ----------
- */
- /*
- * PgBackendSSLStatus
- *
- * For each backend, we keep the SSL status in a separate struct, that
- * is only filled in if SSL is enabled.
- *
- * All char arrays must be null-terminated.
- */
- typedef struct PgBackendSSLStatus
- {
- /* Information about SSL connection */
- int ssl_bits;
- char ssl_version[NAMEDATALEN];
- char ssl_cipher[NAMEDATALEN];
- char ssl_client_dn[NAMEDATALEN];
- /*
- * serial number is max "20 octets" per RFC 5280, so this size should be
- * fine
- */
- char ssl_client_serial[NAMEDATALEN];
- char ssl_issuer_dn[NAMEDATALEN];
- } PgBackendSSLStatus;
- /*
- * PgBackendGSSStatus
- *
- * For each backend, we keep the GSS status in a separate struct, that
- * is only filled in if GSS is enabled.
- *
- * All char arrays must be null-terminated.
- */
- typedef struct PgBackendGSSStatus
- {
- /* Information about GSSAPI connection */
- char gss_princ[NAMEDATALEN]; /* GSSAPI Principal used to auth */
- bool gss_auth; /* If GSSAPI authentication was used */
- bool gss_enc; /* If encryption is being used */
- } PgBackendGSSStatus;
- /* ----------
- * PgBackendStatus
- *
- * Each live backend maintains a PgBackendStatus struct in shared memory
- * showing its current activity. (The structs are allocated according to
- * BackendId, but that is not critical.) Note that this is unrelated to the
- * cumulative stats system (i.e. pgstat.c et al).
- *
- * Each auxiliary process also maintains a PgBackendStatus struct in shared
- * memory.
- * ----------
- */
- typedef struct PgBackendStatus
- {
- /*
- * To avoid locking overhead, we use the following protocol: a backend
- * increments st_changecount before modifying its entry, and again after
- * finishing a modification. A would-be reader should note the value of
- * st_changecount, copy the entry into private memory, then check
- * st_changecount again. If the value hasn't changed, and if it's even,
- * the copy is valid; otherwise start over. This makes updates cheap
- * while reads are potentially expensive, but that's the tradeoff we want.
- *
- * The above protocol needs memory barriers to ensure that the apparent
- * order of execution is as it desires. Otherwise, for example, the CPU
- * might rearrange the code so that st_changecount is incremented twice
- * before the modification on a machine with weak memory ordering. Hence,
- * use the macros defined below for manipulating st_changecount, rather
- * than touching it directly.
- */
- int st_changecount;
- /* The entry is valid iff st_procpid > 0, unused if st_procpid == 0 */
- int st_procpid;
- /* Type of backends */
- BackendType st_backendType;
- /* Times when current backend, transaction, and activity started */
- TimestampTz st_proc_start_timestamp;
- TimestampTz st_xact_start_timestamp;
- TimestampTz st_activity_start_timestamp;
- TimestampTz st_state_start_timestamp;
- /* Database OID, owning user's OID, connection client address */
- Oid st_databaseid;
- Oid st_userid;
- SockAddr st_clientaddr;
- char *st_clienthostname; /* MUST be null-terminated */
- /* Information about SSL connection */
- bool st_ssl;
- PgBackendSSLStatus *st_sslstatus;
- /* Information about GSSAPI connection */
- bool st_gss;
- PgBackendGSSStatus *st_gssstatus;
- /* current state */
- BackendState st_state;
- /* application name; MUST be null-terminated */
- char *st_appname;
- /*
- * Current command string; MUST be null-terminated. Note that this string
- * possibly is truncated in the middle of a multi-byte character. As
- * activity strings are stored more frequently than read, that allows to
- * move the cost of correct truncation to the display side. Use
- * pgstat_clip_activity() to truncate correctly.
- */
- char *st_activity_raw;
- /*
- * Command progress reporting. Any command which wishes can advertise
- * that it is running by setting st_progress_command,
- * st_progress_command_target, and st_progress_param[].
- * st_progress_command_target should be the OID of the relation which the
- * command targets (we assume there's just one, as this is meant for
- * utility commands), but the meaning of each element in the
- * st_progress_param array is command-specific.
- */
- ProgressCommandType st_progress_command;
- Oid st_progress_command_target;
- int64 st_progress_param[PGSTAT_NUM_PROGRESS_PARAM];
- /* query identifier, optionally computed using post_parse_analyze_hook */
- uint64 st_query_id;
- } PgBackendStatus;
- /*
- * Macros to load and store st_changecount with appropriate memory barriers.
- *
- * Use PGSTAT_BEGIN_WRITE_ACTIVITY() before, and PGSTAT_END_WRITE_ACTIVITY()
- * after, modifying the current process's PgBackendStatus data. Note that,
- * since there is no mechanism for cleaning up st_changecount after an error,
- * THESE MACROS FORM A CRITICAL SECTION. Any error between them will be
- * promoted to PANIC, causing a database restart to clean up shared memory!
- * Hence, keep the critical section as short and straight-line as possible.
- * Aside from being safer, that minimizes the window in which readers will
- * have to loop.
- *
- * Reader logic should follow this sketch:
- *
- * for (;;)
- * {
- * int before_ct, after_ct;
- *
- * pgstat_begin_read_activity(beentry, before_ct);
- * ... copy beentry data to local memory ...
- * pgstat_end_read_activity(beentry, after_ct);
- * if (pgstat_read_activity_complete(before_ct, after_ct))
- * break;
- * CHECK_FOR_INTERRUPTS();
- * }
- *
- * For extra safety, we generally use volatile beentry pointers, although
- * the memory barriers should theoretically be sufficient.
- */
- #define PGSTAT_BEGIN_WRITE_ACTIVITY(beentry) \
- do { \
- START_CRIT_SECTION(); \
- (beentry)->st_changecount++; \
- pg_write_barrier(); \
- } while (0)
- #define PGSTAT_END_WRITE_ACTIVITY(beentry) \
- do { \
- pg_write_barrier(); \
- (beentry)->st_changecount++; \
- Assert(((beentry)->st_changecount & 1) == 0); \
- END_CRIT_SECTION(); \
- } while (0)
- #define pgstat_begin_read_activity(beentry, before_changecount) \
- do { \
- (before_changecount) = (beentry)->st_changecount; \
- pg_read_barrier(); \
- } while (0)
- #define pgstat_end_read_activity(beentry, after_changecount) \
- do { \
- pg_read_barrier(); \
- (after_changecount) = (beentry)->st_changecount; \
- } while (0)
- #define pgstat_read_activity_complete(before_changecount, after_changecount) \
- ((before_changecount) == (after_changecount) && \
- ((before_changecount) & 1) == 0)
- /* ----------
- * LocalPgBackendStatus
- *
- * When we build the backend status array, we use LocalPgBackendStatus to be
- * able to add new values to the struct when needed without adding new fields
- * to the shared memory. It contains the backend status as a first member.
- * ----------
- */
- typedef struct LocalPgBackendStatus
- {
- /*
- * Local version of the backend status entry.
- */
- PgBackendStatus backendStatus;
- /*
- * The xid of the current transaction if available, InvalidTransactionId
- * if not.
- */
- TransactionId backend_xid;
- /*
- * The xmin of the current session if available, InvalidTransactionId if
- * not.
- */
- TransactionId backend_xmin;
- } LocalPgBackendStatus;
- /* ----------
- * GUC parameters
- * ----------
- */
- extern PGDLLIMPORT bool pgstat_track_activities;
- extern PGDLLIMPORT int pgstat_track_activity_query_size;
- /* ----------
- * Other global variables
- * ----------
- */
- extern PGDLLIMPORT PgBackendStatus *MyBEEntry;
- /* ----------
- * Functions called from postmaster
- * ----------
- */
- extern Size BackendStatusShmemSize(void);
- extern void CreateSharedBackendStatus(void);
- /* ----------
- * Functions called from backends
- * ----------
- */
- /* Initialization functions */
- extern void pgstat_beinit(void);
- extern void pgstat_bestart(void);
- extern void pgstat_clear_backend_activity_snapshot(void);
- /* Activity reporting functions */
- extern void pgstat_report_activity(BackendState state, const char *cmd_str);
- extern void pgstat_report_query_id(uint64 query_id, bool force);
- extern void pgstat_report_tempfile(size_t filesize);
- extern void pgstat_report_appname(const char *appname);
- extern void pgstat_report_xact_timestamp(TimestampTz tstamp);
- extern const char *pgstat_get_backend_current_activity(int pid, bool checkUser);
- extern const char *pgstat_get_crashed_backend_activity(int pid, char *buffer,
- int buflen);
- extern uint64 pgstat_get_my_query_id(void);
- /* ----------
- * Support functions for the SQL-callable functions to
- * generate the pgstat* views.
- * ----------
- */
- extern int pgstat_fetch_stat_numbackends(void);
- extern PgBackendStatus *pgstat_fetch_stat_beentry(int beid);
- extern LocalPgBackendStatus *pgstat_fetch_stat_local_beentry(int beid);
- extern char *pgstat_clip_activity(const char *raw_activity);
- #endif /* BACKEND_STATUS_H */
|