2
0

backend_status.h 9.2 KB

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