/src/postgres/src/include/utils/pgstat_internal.h
Line | Count | Source |
1 | | /* ---------- |
2 | | * pgstat_internal.h |
3 | | * |
4 | | * Definitions for the PostgreSQL cumulative statistics system that should |
5 | | * only be needed by files implementing statistics support (rather than ones |
6 | | * reporting / querying stats). |
7 | | * |
8 | | * Copyright (c) 2001-2025, PostgreSQL Global Development Group |
9 | | * |
10 | | * src/include/utils/pgstat_internal.h |
11 | | * ---------- |
12 | | */ |
13 | | #ifndef PGSTAT_INTERNAL_H |
14 | | #define PGSTAT_INTERNAL_H |
15 | | |
16 | | |
17 | | #include "common/hashfn_unstable.h" |
18 | | #include "lib/dshash.h" |
19 | | #include "lib/ilist.h" |
20 | | #include "pgstat.h" |
21 | | #include "storage/lwlock.h" |
22 | | #include "utils/dsa.h" |
23 | | |
24 | | |
25 | | /* |
26 | | * Types related to shared memory storage of statistics. |
27 | | * |
28 | | * Per-object statistics are stored in the "shared stats" hashtable. That |
29 | | * table's entries (PgStatShared_HashEntry) contain a pointer to the actual stats |
30 | | * data for the object (the size of the stats data varies depending on the |
31 | | * kind of stats). The table is keyed by PgStat_HashKey. |
32 | | * |
33 | | * Once a backend has a reference to a shared stats entry, it increments the |
34 | | * entry's refcount. Even after stats data is dropped (e.g., due to a DROP |
35 | | * TABLE), the entry itself can only be deleted once all references have been |
36 | | * released. |
37 | | * |
38 | | * These refcounts, in combination with a backend local hashtable |
39 | | * (pgStatEntryRefHash, with entries pointing to PgStat_EntryRef) in front of |
40 | | * the shared hash table, mean that most stats work can happen without |
41 | | * touching the shared hash table, reducing contention. |
42 | | * |
43 | | * Once there are pending stats updates for a table PgStat_EntryRef->pending |
44 | | * is allocated to contain a working space for as-of-yet-unapplied stats |
45 | | * updates. Once the stats are flushed, PgStat_EntryRef->pending is freed. |
46 | | * |
47 | | * Each stat kind in the shared hash table has a fixed member |
48 | | * PgStatShared_Common as the first element. |
49 | | */ |
50 | | |
51 | | /* |
52 | | * Struct for shared statistics hash entry key. |
53 | | * |
54 | | * NB: We assume that this struct contains no padding. Also, 8 bytes |
55 | | * allocated for the object ID are good enough to ensure the uniqueness |
56 | | * of the hash key, hence the addition of new fields is not recommended. |
57 | | */ |
58 | | typedef struct PgStat_HashKey |
59 | | { |
60 | | PgStat_Kind kind; /* statistics entry kind */ |
61 | | Oid dboid; /* database ID. InvalidOid for shared objects. */ |
62 | | uint64 objid; /* object ID (table, function, etc.), or |
63 | | * identifier. */ |
64 | | } PgStat_HashKey; |
65 | | |
66 | | /* |
67 | | * PgStat_HashKey should not have any padding. Checking that the structure |
68 | | * size matches with the sum of each field is a check simple enough to |
69 | | * enforce this policy. |
70 | | */ |
71 | | StaticAssertDecl((sizeof(PgStat_Kind) + sizeof(uint64) + sizeof(Oid)) == |
72 | | sizeof(PgStat_HashKey), |
73 | | "PgStat_HashKey should have no padding"); |
74 | | |
75 | | /* |
76 | | * Shared statistics hash entry. Doesn't itself contain any stats, but points |
77 | | * to them (with ->body). That allows the stats entries themselves to be of |
78 | | * variable size. |
79 | | */ |
80 | | typedef struct PgStatShared_HashEntry |
81 | | { |
82 | | PgStat_HashKey key; /* hash key */ |
83 | | |
84 | | /* |
85 | | * If dropped is set, backends need to release their references so that |
86 | | * the memory for the entry can be freed. No new references may be made |
87 | | * once marked as dropped. |
88 | | */ |
89 | | bool dropped; |
90 | | |
91 | | /* |
92 | | * Refcount managing lifetime of the entry itself (as opposed to the |
93 | | * dshash entry pointing to it). The stats lifetime has to be separate |
94 | | * from the hash table entry lifetime because we allow backends to point |
95 | | * to a stats entry without holding a hash table lock (and some other |
96 | | * reasons). |
97 | | * |
98 | | * As long as the entry is not dropped, 1 is added to the refcount |
99 | | * representing that the entry should not be dropped. In addition each |
100 | | * backend that has a reference to the entry needs to increment the |
101 | | * refcount as long as it does. |
102 | | * |
103 | | * May only be incremented / decremented while holding at least a shared |
104 | | * lock on the dshash partition containing the entry. It needs to be an |
105 | | * atomic variable because multiple backends can increment the refcount |
106 | | * with just a shared lock. |
107 | | * |
108 | | * When the refcount reaches 0 the entry needs to be freed. |
109 | | */ |
110 | | pg_atomic_uint32 refcount; |
111 | | |
112 | | /* |
113 | | * Counter tracking the number of times the entry has been reused. |
114 | | * |
115 | | * Set to 0 when the entry is created, and incremented by one each time |
116 | | * the shared entry is reinitialized with pgstat_reinit_entry(). |
117 | | * |
118 | | * May only be incremented / decremented while holding at least a shared |
119 | | * lock on the dshash partition containing the entry. Like refcount, it |
120 | | * needs to be an atomic variable because multiple backends can increment |
121 | | * the generation with just a shared lock. |
122 | | */ |
123 | | pg_atomic_uint32 generation; |
124 | | |
125 | | /* |
126 | | * Pointer to shared stats. The stats entry always starts with |
127 | | * PgStatShared_Common, embedded in a larger struct containing the |
128 | | * PgStat_Kind specific stats fields. |
129 | | */ |
130 | | dsa_pointer body; |
131 | | } PgStatShared_HashEntry; |
132 | | |
133 | | /* |
134 | | * Common header struct for PgStatShared_*. |
135 | | */ |
136 | | typedef struct PgStatShared_Common |
137 | | { |
138 | | uint32 magic; /* just a validity cross-check */ |
139 | | /* lock protecting stats contents (i.e. data following the header) */ |
140 | | LWLock lock; |
141 | | } PgStatShared_Common; |
142 | | |
143 | | /* |
144 | | * A backend local reference to a shared stats entry. As long as at least one |
145 | | * such reference exists, the shared stats entry will not be released. |
146 | | * |
147 | | * If there are pending stats update to the shared stats, these are stored in |
148 | | * ->pending. |
149 | | */ |
150 | | typedef struct PgStat_EntryRef |
151 | | { |
152 | | /* |
153 | | * Pointer to the PgStatShared_HashEntry entry in the shared stats |
154 | | * hashtable. |
155 | | */ |
156 | | PgStatShared_HashEntry *shared_entry; |
157 | | |
158 | | /* |
159 | | * Pointer to the stats data (i.e. PgStatShared_HashEntry->body), resolved |
160 | | * as a local pointer, to avoid repeated dsa_get_address() calls. |
161 | | */ |
162 | | PgStatShared_Common *shared_stats; |
163 | | |
164 | | /* |
165 | | * Copy of PgStatShared_HashEntry->generation, keeping locally track of |
166 | | * the shared stats entry "generation" retrieved (number of times reused). |
167 | | */ |
168 | | uint32 generation; |
169 | | |
170 | | /* |
171 | | * Pending statistics data that will need to be flushed to shared memory |
172 | | * stats eventually. Each stats kind utilizing pending data defines what |
173 | | * format its pending data has and needs to provide a |
174 | | * PgStat_KindInfo->flush_pending_cb callback to merge pending entries |
175 | | * into the shared stats hash table. |
176 | | */ |
177 | | void *pending; |
178 | | dlist_node pending_node; /* membership in pgStatPending list */ |
179 | | } PgStat_EntryRef; |
180 | | |
181 | | |
182 | | /* |
183 | | * Some stats changes are transactional. To maintain those, a stack of |
184 | | * PgStat_SubXactStatus entries is maintained, which contain data pertaining |
185 | | * to the current transaction and its active subtransactions. |
186 | | */ |
187 | | typedef struct PgStat_SubXactStatus |
188 | | { |
189 | | int nest_level; /* subtransaction nest level */ |
190 | | |
191 | | struct PgStat_SubXactStatus *prev; /* higher-level subxact if any */ |
192 | | |
193 | | /* |
194 | | * Statistics for transactionally dropped objects need to be |
195 | | * transactionally dropped as well. Collect the stats dropped in the |
196 | | * current (sub-)transaction and only execute the stats drop when we know |
197 | | * if the transaction commits/aborts. To handle replicas and crashes, |
198 | | * stats drops are included in commit / abort records. |
199 | | */ |
200 | | dclist_head pending_drops; |
201 | | |
202 | | /* |
203 | | * Tuple insertion/deletion counts for an open transaction can't be |
204 | | * propagated into PgStat_TableStatus counters until we know if it is |
205 | | * going to commit or abort. Hence, we keep these counts in per-subxact |
206 | | * structs that live in TopTransactionContext. This data structure is |
207 | | * designed on the assumption that subxacts won't usually modify very many |
208 | | * tables. |
209 | | */ |
210 | | PgStat_TableXactStatus *first; /* head of list for this subxact */ |
211 | | } PgStat_SubXactStatus; |
212 | | |
213 | | |
214 | | /* |
215 | | * Metadata for a specific kind of statistics. |
216 | | */ |
217 | | typedef struct PgStat_KindInfo |
218 | | { |
219 | | /* |
220 | | * Do a fixed number of stats objects exist for this kind of stats (e.g. |
221 | | * bgwriter stats) or not (e.g. tables). |
222 | | */ |
223 | | bool fixed_amount:1; |
224 | | |
225 | | /* |
226 | | * Can stats of this kind be accessed from another database? Determines |
227 | | * whether a stats object gets included in stats snapshots. |
228 | | */ |
229 | | bool accessed_across_databases:1; |
230 | | |
231 | | /* Should stats be written to the on-disk stats file? */ |
232 | | bool write_to_file:1; |
233 | | |
234 | | /* |
235 | | * Should the number of entries be tracked? For variable-numbered stats, |
236 | | * to update its PgStat_ShmemControl.entry_counts. |
237 | | */ |
238 | | bool track_entry_count:1; |
239 | | |
240 | | /* |
241 | | * The size of an entry in the shared stats hash table (pointed to by |
242 | | * PgStatShared_HashEntry->body). For fixed-numbered statistics, this is |
243 | | * the size of an entry in PgStat_ShmemControl->custom_data. |
244 | | */ |
245 | | uint32 shared_size; |
246 | | |
247 | | /* |
248 | | * The offset of the statistics struct in the cached statistics snapshot |
249 | | * PgStat_Snapshot, for fixed-numbered statistics. |
250 | | */ |
251 | | uint32 snapshot_ctl_off; |
252 | | |
253 | | /* |
254 | | * The offset of the statistics struct in the containing shared memory |
255 | | * control structure PgStat_ShmemControl, for fixed-numbered statistics. |
256 | | */ |
257 | | uint32 shared_ctl_off; |
258 | | |
259 | | /* |
260 | | * The offset/size of statistics inside the shared stats entry. Used when |
261 | | * [de-]serializing statistics to / from disk respectively. Separate from |
262 | | * shared_size because [de-]serialization may not include in-memory state |
263 | | * like lwlocks. |
264 | | */ |
265 | | uint32 shared_data_off; |
266 | | uint32 shared_data_len; |
267 | | |
268 | | /* |
269 | | * The size of the pending data for this kind. E.g. how large |
270 | | * PgStat_EntryRef->pending is. Used for allocations. |
271 | | * |
272 | | * 0 signals that an entry of this kind should never have a pending entry. |
273 | | */ |
274 | | uint32 pending_size; |
275 | | |
276 | | /* |
277 | | * Perform custom actions when initializing a backend (standalone or under |
278 | | * postmaster). Optional. |
279 | | */ |
280 | | void (*init_backend_cb) (void); |
281 | | |
282 | | /* |
283 | | * For variable-numbered stats: flush pending stats. Required if pending |
284 | | * data is used. See flush_static_cb when dealing with stats data that |
285 | | * that cannot use PgStat_EntryRef->pending. |
286 | | */ |
287 | | bool (*flush_pending_cb) (PgStat_EntryRef *sr, bool nowait); |
288 | | |
289 | | /* |
290 | | * For variable-numbered stats: delete pending stats. Optional. |
291 | | */ |
292 | | void (*delete_pending_cb) (PgStat_EntryRef *sr); |
293 | | |
294 | | /* |
295 | | * For variable-numbered stats: reset the reset timestamp. Optional. |
296 | | */ |
297 | | void (*reset_timestamp_cb) (PgStatShared_Common *header, TimestampTz ts); |
298 | | |
299 | | /* |
300 | | * For variable-numbered stats. Optional. |
301 | | */ |
302 | | void (*to_serialized_name) (const PgStat_HashKey *key, |
303 | | const PgStatShared_Common *header, NameData *name); |
304 | | bool (*from_serialized_name) (const NameData *name, PgStat_HashKey *key); |
305 | | |
306 | | /* |
307 | | * For fixed-numbered statistics: Initialize shared memory state. |
308 | | * |
309 | | * "stats" is the pointer to the allocated shared memory area. |
310 | | */ |
311 | | void (*init_shmem_cb) (void *stats); |
312 | | |
313 | | /* |
314 | | * For fixed-numbered or variable-numbered statistics: Flush pending stats |
315 | | * entries, for stats kinds that do not use PgStat_EntryRef->pending. |
316 | | * |
317 | | * Returns true if some of the stats could not be flushed, due to lock |
318 | | * contention for example. Optional. |
319 | | * |
320 | | * "pgstat_report_fixed" needs to be set to trigger the flush of pending |
321 | | * stats. |
322 | | */ |
323 | | bool (*flush_static_cb) (bool nowait); |
324 | | |
325 | | /* |
326 | | * For fixed-numbered statistics: Reset All. |
327 | | */ |
328 | | void (*reset_all_cb) (TimestampTz ts); |
329 | | |
330 | | /* |
331 | | * For fixed-numbered statistics: Build snapshot for entry |
332 | | */ |
333 | | void (*snapshot_cb) (void); |
334 | | |
335 | | /* name of the kind of stats */ |
336 | | const char *const name; |
337 | | } PgStat_KindInfo; |
338 | | |
339 | | |
340 | | /* |
341 | | * List of SLRU names that we keep stats for. There is no central registry of |
342 | | * SLRUs, so we use this fixed list instead. The "other" entry is used for |
343 | | * all SLRUs without an explicit entry (e.g. SLRUs in extensions). |
344 | | * |
345 | | * This is only defined here so that SLRU_NUM_ELEMENTS is known for later type |
346 | | * definitions. |
347 | | */ |
348 | | static const char *const slru_names[] = { |
349 | | "commit_timestamp", |
350 | | "multixact_member", |
351 | | "multixact_offset", |
352 | | "notify", |
353 | | "serializable", |
354 | | "subtransaction", |
355 | | "transaction", |
356 | | "other" /* has to be last */ |
357 | | }; |
358 | | |
359 | 0 | #define SLRU_NUM_ELEMENTS lengthof(slru_names) |
360 | | |
361 | | |
362 | | /* ---------- |
363 | | * Types and definitions for different kinds of fixed-amount stats. |
364 | | * |
365 | | * Single-writer stats use the changecount mechanism to achieve low-overhead |
366 | | * writes - they're obviously more performance critical than reads. Check the |
367 | | * definition of struct PgBackendStatus for some explanation of the |
368 | | * changecount mechanism. |
369 | | * |
370 | | * Because the obvious implementation of resetting single-writer stats isn't |
371 | | * compatible with that (another backend needs to write), we don't scribble on |
372 | | * shared stats while resetting. Instead, just record the current counter |
373 | | * values in a copy of the stats data, which is protected by ->lock. See |
374 | | * pgstat_fetch_stat_(archiver|bgwriter|checkpointer) for the reader side. |
375 | | * |
376 | | * The only exception to that is the stat_reset_timestamp in these structs, |
377 | | * which is protected by ->lock, because it has to be written by another |
378 | | * backend while resetting. |
379 | | * ---------- |
380 | | */ |
381 | | |
382 | | typedef struct PgStatShared_Archiver |
383 | | { |
384 | | /* lock protects ->reset_offset as well as stats->stat_reset_timestamp */ |
385 | | LWLock lock; |
386 | | uint32 changecount; |
387 | | PgStat_ArchiverStats stats; |
388 | | PgStat_ArchiverStats reset_offset; |
389 | | } PgStatShared_Archiver; |
390 | | |
391 | | typedef struct PgStatShared_BgWriter |
392 | | { |
393 | | /* lock protects ->reset_offset as well as stats->stat_reset_timestamp */ |
394 | | LWLock lock; |
395 | | uint32 changecount; |
396 | | PgStat_BgWriterStats stats; |
397 | | PgStat_BgWriterStats reset_offset; |
398 | | } PgStatShared_BgWriter; |
399 | | |
400 | | typedef struct PgStatShared_Checkpointer |
401 | | { |
402 | | /* lock protects ->reset_offset as well as stats->stat_reset_timestamp */ |
403 | | LWLock lock; |
404 | | uint32 changecount; |
405 | | PgStat_CheckpointerStats stats; |
406 | | PgStat_CheckpointerStats reset_offset; |
407 | | } PgStatShared_Checkpointer; |
408 | | |
409 | | /* Shared-memory ready PgStat_IO */ |
410 | | typedef struct PgStatShared_IO |
411 | | { |
412 | | /* |
413 | | * locks[i] protects stats.stats[i]. locks[0] also protects |
414 | | * stats.stat_reset_timestamp. |
415 | | */ |
416 | | LWLock locks[BACKEND_NUM_TYPES]; |
417 | | PgStat_IO stats; |
418 | | } PgStatShared_IO; |
419 | | |
420 | | typedef struct PgStatShared_SLRU |
421 | | { |
422 | | /* lock protects ->stats */ |
423 | | LWLock lock; |
424 | | PgStat_SLRUStats stats[SLRU_NUM_ELEMENTS]; |
425 | | } PgStatShared_SLRU; |
426 | | |
427 | | typedef struct PgStatShared_Wal |
428 | | { |
429 | | /* lock protects ->stats */ |
430 | | LWLock lock; |
431 | | PgStat_WalStats stats; |
432 | | } PgStatShared_Wal; |
433 | | |
434 | | |
435 | | |
436 | | /* ---------- |
437 | | * Types and definitions for different kinds of variable-amount stats. |
438 | | * |
439 | | * Each struct has to start with PgStatShared_Common, containing information |
440 | | * common across the different types of stats. Kind-specific data follows. |
441 | | * ---------- |
442 | | */ |
443 | | |
444 | | typedef struct PgStatShared_Database |
445 | | { |
446 | | PgStatShared_Common header; |
447 | | PgStat_StatDBEntry stats; |
448 | | } PgStatShared_Database; |
449 | | |
450 | | typedef struct PgStatShared_Relation |
451 | | { |
452 | | PgStatShared_Common header; |
453 | | PgStat_StatTabEntry stats; |
454 | | } PgStatShared_Relation; |
455 | | |
456 | | typedef struct PgStatShared_Function |
457 | | { |
458 | | PgStatShared_Common header; |
459 | | PgStat_StatFuncEntry stats; |
460 | | } PgStatShared_Function; |
461 | | |
462 | | typedef struct PgStatShared_Subscription |
463 | | { |
464 | | PgStatShared_Common header; |
465 | | PgStat_StatSubEntry stats; |
466 | | } PgStatShared_Subscription; |
467 | | |
468 | | typedef struct PgStatShared_ReplSlot |
469 | | { |
470 | | PgStatShared_Common header; |
471 | | PgStat_StatReplSlotEntry stats; |
472 | | } PgStatShared_ReplSlot; |
473 | | |
474 | | typedef struct PgStatShared_Backend |
475 | | { |
476 | | PgStatShared_Common header; |
477 | | PgStat_Backend stats; |
478 | | } PgStatShared_Backend; |
479 | | |
480 | | /* |
481 | | * Central shared memory entry for the cumulative stats system. |
482 | | * |
483 | | * Fixed amount stats, the dynamic shared memory hash table for |
484 | | * non-fixed-amount stats, as well as remaining bits and pieces are all |
485 | | * reached from here. |
486 | | */ |
487 | | typedef struct PgStat_ShmemControl |
488 | | { |
489 | | void *raw_dsa_area; |
490 | | |
491 | | /* |
492 | | * Stats for variable-numbered objects are kept in this shared hash table. |
493 | | * See comment above PgStat_Kind for details. |
494 | | */ |
495 | | dshash_table_handle hash_handle; /* shared dbstat hash */ |
496 | | |
497 | | /* Has the stats system already been shut down? Just a debugging check. */ |
498 | | bool is_shutdown; |
499 | | |
500 | | /* |
501 | | * Whenever statistics for dropped objects could not be freed - because |
502 | | * backends still have references - the dropping backend calls |
503 | | * pgstat_request_entry_refs_gc() incrementing this counter. Eventually |
504 | | * that causes backends to run pgstat_gc_entry_refs(), allowing memory to |
505 | | * be reclaimed. |
506 | | */ |
507 | | pg_atomic_uint64 gc_request_count; |
508 | | |
509 | | /* |
510 | | * Counters for the number of entries associated to a single stats kind |
511 | | * that uses variable-numbered objects stored in the shared hash table. |
512 | | * These counters can be enabled on a per-kind basis, when |
513 | | * track_entry_count is set. This counter is incremented each time a new |
514 | | * entry is created (not reused) in the shared hash table, and is |
515 | | * decremented each time an entry is freed from the shared hash table. |
516 | | */ |
517 | | pg_atomic_uint64 entry_counts[PGSTAT_KIND_MAX]; |
518 | | |
519 | | /* |
520 | | * Stats data for fixed-numbered objects. |
521 | | */ |
522 | | PgStatShared_Archiver archiver; |
523 | | PgStatShared_BgWriter bgwriter; |
524 | | PgStatShared_Checkpointer checkpointer; |
525 | | PgStatShared_IO io; |
526 | | PgStatShared_SLRU slru; |
527 | | PgStatShared_Wal wal; |
528 | | |
529 | | /* |
530 | | * Custom stats data with fixed-numbered objects, indexed by (PgStat_Kind |
531 | | * - PGSTAT_KIND_CUSTOM_MIN). |
532 | | */ |
533 | | void *custom_data[PGSTAT_KIND_CUSTOM_SIZE]; |
534 | | |
535 | | } PgStat_ShmemControl; |
536 | | |
537 | | |
538 | | /* |
539 | | * Cached statistics snapshot |
540 | | */ |
541 | | typedef struct PgStat_Snapshot |
542 | | { |
543 | | PgStat_FetchConsistency mode; |
544 | | |
545 | | /* time at which snapshot was taken */ |
546 | | TimestampTz snapshot_timestamp; |
547 | | |
548 | | bool fixed_valid[PGSTAT_KIND_BUILTIN_SIZE]; |
549 | | |
550 | | PgStat_ArchiverStats archiver; |
551 | | |
552 | | PgStat_BgWriterStats bgwriter; |
553 | | |
554 | | PgStat_CheckpointerStats checkpointer; |
555 | | |
556 | | PgStat_IO io; |
557 | | |
558 | | PgStat_SLRUStats slru[SLRU_NUM_ELEMENTS]; |
559 | | |
560 | | PgStat_WalStats wal; |
561 | | |
562 | | /* |
563 | | * Data in snapshot for custom fixed-numbered statistics, indexed by |
564 | | * (PgStat_Kind - PGSTAT_KIND_CUSTOM_MIN). Each entry is allocated in |
565 | | * TopMemoryContext, for a size of PgStat_KindInfo->shared_data_len. |
566 | | */ |
567 | | bool custom_valid[PGSTAT_KIND_CUSTOM_SIZE]; |
568 | | void *custom_data[PGSTAT_KIND_CUSTOM_SIZE]; |
569 | | |
570 | | /* to free snapshot in bulk */ |
571 | | MemoryContext context; |
572 | | struct pgstat_snapshot_hash *stats; |
573 | | } PgStat_Snapshot; |
574 | | |
575 | | |
576 | | /* |
577 | | * Collection of backend-local stats state. |
578 | | */ |
579 | | typedef struct PgStat_LocalState |
580 | | { |
581 | | PgStat_ShmemControl *shmem; |
582 | | dsa_area *dsa; |
583 | | dshash_table *shared_hash; |
584 | | |
585 | | /* the current statistics snapshot */ |
586 | | PgStat_Snapshot snapshot; |
587 | | } PgStat_LocalState; |
588 | | |
589 | | |
590 | | /* |
591 | | * Inline functions defined further below. |
592 | | */ |
593 | | |
594 | | static inline void pgstat_begin_changecount_write(uint32 *cc); |
595 | | static inline void pgstat_end_changecount_write(uint32 *cc); |
596 | | static inline uint32 pgstat_begin_changecount_read(uint32 *cc); |
597 | | static inline bool pgstat_end_changecount_read(uint32 *cc, uint32 cc_before); |
598 | | |
599 | | static inline void pgstat_copy_changecounted_stats(void *dst, void *src, size_t len, |
600 | | uint32 *cc); |
601 | | |
602 | | static inline int pgstat_cmp_hash_key(const void *a, const void *b, size_t size, void *arg); |
603 | | static inline uint32 pgstat_hash_hash_key(const void *d, size_t size, void *arg); |
604 | | static inline size_t pgstat_get_entry_len(PgStat_Kind kind); |
605 | | static inline void *pgstat_get_entry_data(PgStat_Kind kind, PgStatShared_Common *entry); |
606 | | static inline void *pgstat_get_custom_shmem_data(PgStat_Kind kind); |
607 | | static inline void *pgstat_get_custom_snapshot_data(PgStat_Kind kind); |
608 | | |
609 | | |
610 | | /* |
611 | | * Functions in pgstat.c |
612 | | */ |
613 | | |
614 | | extern const PgStat_KindInfo *pgstat_get_kind_info(PgStat_Kind kind); |
615 | | extern void pgstat_register_kind(PgStat_Kind kind, |
616 | | const PgStat_KindInfo *kind_info); |
617 | | |
618 | | #ifdef USE_ASSERT_CHECKING |
619 | | extern void pgstat_assert_is_up(void); |
620 | | #else |
621 | 0 | #define pgstat_assert_is_up() ((void)true) |
622 | | #endif |
623 | | |
624 | | extern void pgstat_delete_pending_entry(PgStat_EntryRef *entry_ref); |
625 | | extern PgStat_EntryRef *pgstat_prep_pending_entry(PgStat_Kind kind, Oid dboid, |
626 | | uint64 objid, |
627 | | bool *created_entry); |
628 | | extern PgStat_EntryRef *pgstat_fetch_pending_entry(PgStat_Kind kind, |
629 | | Oid dboid, uint64 objid); |
630 | | |
631 | | extern void *pgstat_fetch_entry(PgStat_Kind kind, Oid dboid, uint64 objid); |
632 | | extern void pgstat_snapshot_fixed(PgStat_Kind kind); |
633 | | |
634 | | |
635 | | /* |
636 | | * Functions in pgstat_archiver.c |
637 | | */ |
638 | | |
639 | | extern void pgstat_archiver_init_shmem_cb(void *stats); |
640 | | extern void pgstat_archiver_reset_all_cb(TimestampTz ts); |
641 | | extern void pgstat_archiver_snapshot_cb(void); |
642 | | |
643 | | /* |
644 | | * Functions in pgstat_backend.c |
645 | | */ |
646 | | |
647 | | /* flags for pgstat_flush_backend() */ |
648 | 0 | #define PGSTAT_BACKEND_FLUSH_IO (1 << 0) /* Flush I/O statistics */ |
649 | 0 | #define PGSTAT_BACKEND_FLUSH_WAL (1 << 1) /* Flush WAL statistics */ |
650 | 0 | #define PGSTAT_BACKEND_FLUSH_ALL (PGSTAT_BACKEND_FLUSH_IO | PGSTAT_BACKEND_FLUSH_WAL) |
651 | | |
652 | | extern bool pgstat_flush_backend(bool nowait, bits32 flags); |
653 | | extern bool pgstat_backend_flush_cb(bool nowait); |
654 | | extern void pgstat_backend_reset_timestamp_cb(PgStatShared_Common *header, |
655 | | TimestampTz ts); |
656 | | |
657 | | /* |
658 | | * Functions in pgstat_bgwriter.c |
659 | | */ |
660 | | |
661 | | extern void pgstat_bgwriter_init_shmem_cb(void *stats); |
662 | | extern void pgstat_bgwriter_reset_all_cb(TimestampTz ts); |
663 | | extern void pgstat_bgwriter_snapshot_cb(void); |
664 | | |
665 | | |
666 | | /* |
667 | | * Functions in pgstat_checkpointer.c |
668 | | */ |
669 | | |
670 | | extern void pgstat_checkpointer_init_shmem_cb(void *stats); |
671 | | extern void pgstat_checkpointer_reset_all_cb(TimestampTz ts); |
672 | | extern void pgstat_checkpointer_snapshot_cb(void); |
673 | | |
674 | | |
675 | | /* |
676 | | * Functions in pgstat_database.c |
677 | | */ |
678 | | |
679 | | extern void pgstat_report_disconnect(Oid dboid); |
680 | | extern void pgstat_update_dbstats(TimestampTz ts); |
681 | | extern void AtEOXact_PgStat_Database(bool isCommit, bool parallel); |
682 | | |
683 | | extern PgStat_StatDBEntry *pgstat_prep_database_pending(Oid dboid); |
684 | | extern void pgstat_reset_database_timestamp(Oid dboid, TimestampTz ts); |
685 | | extern bool pgstat_database_flush_cb(PgStat_EntryRef *entry_ref, bool nowait); |
686 | | extern void pgstat_database_reset_timestamp_cb(PgStatShared_Common *header, TimestampTz ts); |
687 | | |
688 | | |
689 | | /* |
690 | | * Functions in pgstat_function.c |
691 | | */ |
692 | | |
693 | | extern bool pgstat_function_flush_cb(PgStat_EntryRef *entry_ref, bool nowait); |
694 | | extern void pgstat_function_reset_timestamp_cb(PgStatShared_Common *header, TimestampTz ts); |
695 | | |
696 | | |
697 | | /* |
698 | | * Functions in pgstat_io.c |
699 | | */ |
700 | | |
701 | | extern void pgstat_flush_io(bool nowait); |
702 | | |
703 | | extern bool pgstat_io_flush_cb(bool nowait); |
704 | | extern void pgstat_io_init_shmem_cb(void *stats); |
705 | | extern void pgstat_io_reset_all_cb(TimestampTz ts); |
706 | | extern void pgstat_io_snapshot_cb(void); |
707 | | |
708 | | |
709 | | /* |
710 | | * Functions in pgstat_relation.c |
711 | | */ |
712 | | |
713 | | extern void AtEOXact_PgStat_Relations(PgStat_SubXactStatus *xact_state, bool isCommit); |
714 | | extern void AtEOSubXact_PgStat_Relations(PgStat_SubXactStatus *xact_state, bool isCommit, int nestDepth); |
715 | | extern void AtPrepare_PgStat_Relations(PgStat_SubXactStatus *xact_state); |
716 | | extern void PostPrepare_PgStat_Relations(PgStat_SubXactStatus *xact_state); |
717 | | |
718 | | extern bool pgstat_relation_flush_cb(PgStat_EntryRef *entry_ref, bool nowait); |
719 | | extern void pgstat_relation_delete_pending_cb(PgStat_EntryRef *entry_ref); |
720 | | extern void pgstat_relation_reset_timestamp_cb(PgStatShared_Common *header, TimestampTz ts); |
721 | | |
722 | | |
723 | | /* |
724 | | * Functions in pgstat_replslot.c |
725 | | */ |
726 | | |
727 | | extern void pgstat_replslot_reset_timestamp_cb(PgStatShared_Common *header, TimestampTz ts); |
728 | | extern void pgstat_replslot_to_serialized_name_cb(const PgStat_HashKey *key, const PgStatShared_Common *header, NameData *name); |
729 | | extern bool pgstat_replslot_from_serialized_name_cb(const NameData *name, PgStat_HashKey *key); |
730 | | |
731 | | |
732 | | /* |
733 | | * Functions in pgstat_shmem.c |
734 | | */ |
735 | | |
736 | | extern void pgstat_attach_shmem(void); |
737 | | extern void pgstat_detach_shmem(void); |
738 | | |
739 | | extern PgStat_EntryRef *pgstat_get_entry_ref(PgStat_Kind kind, Oid dboid, uint64 objid, |
740 | | bool create, bool *created_entry); |
741 | | extern bool pgstat_lock_entry(PgStat_EntryRef *entry_ref, bool nowait); |
742 | | extern bool pgstat_lock_entry_shared(PgStat_EntryRef *entry_ref, bool nowait); |
743 | | extern void pgstat_unlock_entry(PgStat_EntryRef *entry_ref); |
744 | | extern bool pgstat_drop_entry(PgStat_Kind kind, Oid dboid, uint64 objid); |
745 | | extern void pgstat_drop_all_entries(void); |
746 | | extern void pgstat_drop_matching_entries(bool (*do_drop) (PgStatShared_HashEntry *, Datum), |
747 | | Datum match_data); |
748 | | extern PgStat_EntryRef *pgstat_get_entry_ref_locked(PgStat_Kind kind, Oid dboid, uint64 objid, |
749 | | bool nowait); |
750 | | extern void pgstat_reset_entry(PgStat_Kind kind, Oid dboid, uint64 objid, TimestampTz ts); |
751 | | extern void pgstat_reset_entries_of_kind(PgStat_Kind kind, TimestampTz ts); |
752 | | extern void pgstat_reset_matching_entries(bool (*do_reset) (PgStatShared_HashEntry *, Datum), |
753 | | Datum match_data, |
754 | | TimestampTz ts); |
755 | | |
756 | | extern void pgstat_request_entry_refs_gc(void); |
757 | | extern PgStatShared_Common *pgstat_init_entry(PgStat_Kind kind, |
758 | | PgStatShared_HashEntry *shhashent); |
759 | | |
760 | | |
761 | | /* |
762 | | * Functions in pgstat_slru.c |
763 | | */ |
764 | | |
765 | | extern bool pgstat_slru_flush_cb(bool nowait); |
766 | | extern void pgstat_slru_init_shmem_cb(void *stats); |
767 | | extern void pgstat_slru_reset_all_cb(TimestampTz ts); |
768 | | extern void pgstat_slru_snapshot_cb(void); |
769 | | |
770 | | |
771 | | /* |
772 | | * Functions in pgstat_wal.c |
773 | | */ |
774 | | |
775 | | extern void pgstat_wal_init_backend_cb(void); |
776 | | extern bool pgstat_wal_flush_cb(bool nowait); |
777 | | extern void pgstat_wal_init_shmem_cb(void *stats); |
778 | | extern void pgstat_wal_reset_all_cb(TimestampTz ts); |
779 | | extern void pgstat_wal_snapshot_cb(void); |
780 | | |
781 | | |
782 | | /* |
783 | | * Functions in pgstat_subscription.c |
784 | | */ |
785 | | |
786 | | extern bool pgstat_subscription_flush_cb(PgStat_EntryRef *entry_ref, bool nowait); |
787 | | extern void pgstat_subscription_reset_timestamp_cb(PgStatShared_Common *header, TimestampTz ts); |
788 | | |
789 | | |
790 | | /* |
791 | | * Functions in pgstat_xact.c |
792 | | */ |
793 | | |
794 | | extern PgStat_SubXactStatus *pgstat_get_xact_stack_level(int nest_level); |
795 | | extern void pgstat_drop_transactional(PgStat_Kind kind, Oid dboid, uint64 objid); |
796 | | extern void pgstat_create_transactional(PgStat_Kind kind, Oid dboid, uint64 objid); |
797 | | |
798 | | |
799 | | /* |
800 | | * Variables in pgstat.c |
801 | | */ |
802 | | |
803 | | /* |
804 | | * Track if *any* pending fixed-numbered statistics should be flushed to |
805 | | * shared memory. |
806 | | * |
807 | | * This flag can be switched to true by fixed-numbered statistics to let |
808 | | * pgstat_report_stat() know if it needs to go through one round of |
809 | | * reports, calling flush_static_cb for each fixed-numbered statistics |
810 | | * kind. When this flag is not set, pgstat_report_stat() is able to do |
811 | | * a fast exit, knowing that there are no pending fixed-numbered statistics. |
812 | | * |
813 | | * Statistics callbacks should never reset this flag; pgstat_report_stat() |
814 | | * is in charge of doing that. |
815 | | */ |
816 | | extern PGDLLIMPORT bool pgstat_report_fixed; |
817 | | |
818 | | /* Backend-local stats state */ |
819 | | extern PGDLLIMPORT PgStat_LocalState pgStatLocal; |
820 | | |
821 | | /* |
822 | | * Implementation of inline functions declared above. |
823 | | */ |
824 | | |
825 | | /* |
826 | | * Helpers for changecount manipulation. See comments around struct |
827 | | * PgBackendStatus for details. |
828 | | */ |
829 | | |
830 | | static inline void |
831 | | pgstat_begin_changecount_write(uint32 *cc) |
832 | 0 | { |
833 | 0 | Assert((*cc & 1) == 0); |
834 | |
|
835 | 0 | START_CRIT_SECTION(); |
836 | 0 | (*cc)++; |
837 | 0 | pg_write_barrier(); |
838 | 0 | } Unexecuted instantiation: xlog.c:pgstat_begin_changecount_write Unexecuted instantiation: xlogrecovery.c:pgstat_begin_changecount_write Unexecuted instantiation: walsender.c:pgstat_begin_changecount_write Unexecuted instantiation: pgstat.c:pgstat_begin_changecount_write Unexecuted instantiation: pgstat_archiver.c:pgstat_begin_changecount_write Unexecuted instantiation: pgstat_backend.c:pgstat_begin_changecount_write Unexecuted instantiation: pgstat_bgwriter.c:pgstat_begin_changecount_write Unexecuted instantiation: pgstat_checkpointer.c:pgstat_begin_changecount_write Unexecuted instantiation: pgstat_database.c:pgstat_begin_changecount_write Unexecuted instantiation: pgstat_function.c:pgstat_begin_changecount_write Unexecuted instantiation: pgstat_io.c:pgstat_begin_changecount_write Unexecuted instantiation: pgstat_relation.c:pgstat_begin_changecount_write Unexecuted instantiation: pgstat_replslot.c:pgstat_begin_changecount_write Unexecuted instantiation: pgstat_shmem.c:pgstat_begin_changecount_write Unexecuted instantiation: pgstat_slru.c:pgstat_begin_changecount_write Unexecuted instantiation: pgstat_subscription.c:pgstat_begin_changecount_write Unexecuted instantiation: pgstat_wal.c:pgstat_begin_changecount_write Unexecuted instantiation: pgstat_xact.c:pgstat_begin_changecount_write |
839 | | |
840 | | static inline void |
841 | | pgstat_end_changecount_write(uint32 *cc) |
842 | 0 | { |
843 | 0 | Assert((*cc & 1) == 1); |
844 | |
|
845 | 0 | pg_write_barrier(); |
846 | |
|
847 | 0 | (*cc)++; |
848 | |
|
849 | 0 | END_CRIT_SECTION(); |
850 | 0 | } Unexecuted instantiation: xlog.c:pgstat_end_changecount_write Unexecuted instantiation: xlogrecovery.c:pgstat_end_changecount_write Unexecuted instantiation: walsender.c:pgstat_end_changecount_write Unexecuted instantiation: pgstat.c:pgstat_end_changecount_write Unexecuted instantiation: pgstat_archiver.c:pgstat_end_changecount_write Unexecuted instantiation: pgstat_backend.c:pgstat_end_changecount_write Unexecuted instantiation: pgstat_bgwriter.c:pgstat_end_changecount_write Unexecuted instantiation: pgstat_checkpointer.c:pgstat_end_changecount_write Unexecuted instantiation: pgstat_database.c:pgstat_end_changecount_write Unexecuted instantiation: pgstat_function.c:pgstat_end_changecount_write Unexecuted instantiation: pgstat_io.c:pgstat_end_changecount_write Unexecuted instantiation: pgstat_relation.c:pgstat_end_changecount_write Unexecuted instantiation: pgstat_replslot.c:pgstat_end_changecount_write Unexecuted instantiation: pgstat_shmem.c:pgstat_end_changecount_write Unexecuted instantiation: pgstat_slru.c:pgstat_end_changecount_write Unexecuted instantiation: pgstat_subscription.c:pgstat_end_changecount_write Unexecuted instantiation: pgstat_wal.c:pgstat_end_changecount_write Unexecuted instantiation: pgstat_xact.c:pgstat_end_changecount_write |
851 | | |
852 | | static inline uint32 |
853 | | pgstat_begin_changecount_read(uint32 *cc) |
854 | 0 | { |
855 | 0 | uint32 before_cc = *cc; |
856 | |
|
857 | 0 | CHECK_FOR_INTERRUPTS(); |
858 | |
|
859 | 0 | pg_read_barrier(); |
860 | |
|
861 | 0 | return before_cc; |
862 | 0 | } Unexecuted instantiation: xlog.c:pgstat_begin_changecount_read Unexecuted instantiation: xlogrecovery.c:pgstat_begin_changecount_read Unexecuted instantiation: walsender.c:pgstat_begin_changecount_read Unexecuted instantiation: pgstat.c:pgstat_begin_changecount_read Unexecuted instantiation: pgstat_archiver.c:pgstat_begin_changecount_read Unexecuted instantiation: pgstat_backend.c:pgstat_begin_changecount_read Unexecuted instantiation: pgstat_bgwriter.c:pgstat_begin_changecount_read Unexecuted instantiation: pgstat_checkpointer.c:pgstat_begin_changecount_read Unexecuted instantiation: pgstat_database.c:pgstat_begin_changecount_read Unexecuted instantiation: pgstat_function.c:pgstat_begin_changecount_read Unexecuted instantiation: pgstat_io.c:pgstat_begin_changecount_read Unexecuted instantiation: pgstat_relation.c:pgstat_begin_changecount_read Unexecuted instantiation: pgstat_replslot.c:pgstat_begin_changecount_read Unexecuted instantiation: pgstat_shmem.c:pgstat_begin_changecount_read Unexecuted instantiation: pgstat_slru.c:pgstat_begin_changecount_read Unexecuted instantiation: pgstat_subscription.c:pgstat_begin_changecount_read Unexecuted instantiation: pgstat_wal.c:pgstat_begin_changecount_read Unexecuted instantiation: pgstat_xact.c:pgstat_begin_changecount_read |
863 | | |
864 | | /* |
865 | | * Returns true if the read succeeded, false if it needs to be repeated. |
866 | | */ |
867 | | static inline bool |
868 | | pgstat_end_changecount_read(uint32 *cc, uint32 before_cc) |
869 | 0 | { |
870 | 0 | uint32 after_cc; |
871 | |
|
872 | 0 | pg_read_barrier(); |
873 | |
|
874 | 0 | after_cc = *cc; |
875 | | |
876 | | /* was a write in progress when we started? */ |
877 | 0 | if (before_cc & 1) |
878 | 0 | return false; |
879 | | |
880 | | /* did writes start and complete while we read? */ |
881 | 0 | return before_cc == after_cc; |
882 | 0 | } Unexecuted instantiation: xlog.c:pgstat_end_changecount_read Unexecuted instantiation: xlogrecovery.c:pgstat_end_changecount_read Unexecuted instantiation: walsender.c:pgstat_end_changecount_read Unexecuted instantiation: pgstat.c:pgstat_end_changecount_read Unexecuted instantiation: pgstat_archiver.c:pgstat_end_changecount_read Unexecuted instantiation: pgstat_backend.c:pgstat_end_changecount_read Unexecuted instantiation: pgstat_bgwriter.c:pgstat_end_changecount_read Unexecuted instantiation: pgstat_checkpointer.c:pgstat_end_changecount_read Unexecuted instantiation: pgstat_database.c:pgstat_end_changecount_read Unexecuted instantiation: pgstat_function.c:pgstat_end_changecount_read Unexecuted instantiation: pgstat_io.c:pgstat_end_changecount_read Unexecuted instantiation: pgstat_relation.c:pgstat_end_changecount_read Unexecuted instantiation: pgstat_replslot.c:pgstat_end_changecount_read Unexecuted instantiation: pgstat_shmem.c:pgstat_end_changecount_read Unexecuted instantiation: pgstat_slru.c:pgstat_end_changecount_read Unexecuted instantiation: pgstat_subscription.c:pgstat_end_changecount_read Unexecuted instantiation: pgstat_wal.c:pgstat_end_changecount_read Unexecuted instantiation: pgstat_xact.c:pgstat_end_changecount_read |
883 | | |
884 | | |
885 | | /* |
886 | | * helper function for PgStat_KindInfo->snapshot_cb |
887 | | * PgStat_KindInfo->reset_all_cb callbacks. |
888 | | * |
889 | | * Copies out the specified memory area following change-count protocol. |
890 | | */ |
891 | | static inline void |
892 | | pgstat_copy_changecounted_stats(void *dst, void *src, size_t len, |
893 | | uint32 *cc) |
894 | 0 | { |
895 | 0 | uint32 cc_before; |
896 | |
|
897 | 0 | do |
898 | 0 | { |
899 | 0 | cc_before = pgstat_begin_changecount_read(cc); |
900 | |
|
901 | 0 | memcpy(dst, src, len); |
902 | 0 | } |
903 | 0 | while (!pgstat_end_changecount_read(cc, cc_before)); |
904 | 0 | } Unexecuted instantiation: xlog.c:pgstat_copy_changecounted_stats Unexecuted instantiation: xlogrecovery.c:pgstat_copy_changecounted_stats Unexecuted instantiation: walsender.c:pgstat_copy_changecounted_stats Unexecuted instantiation: pgstat.c:pgstat_copy_changecounted_stats Unexecuted instantiation: pgstat_archiver.c:pgstat_copy_changecounted_stats Unexecuted instantiation: pgstat_backend.c:pgstat_copy_changecounted_stats Unexecuted instantiation: pgstat_bgwriter.c:pgstat_copy_changecounted_stats Unexecuted instantiation: pgstat_checkpointer.c:pgstat_copy_changecounted_stats Unexecuted instantiation: pgstat_database.c:pgstat_copy_changecounted_stats Unexecuted instantiation: pgstat_function.c:pgstat_copy_changecounted_stats Unexecuted instantiation: pgstat_io.c:pgstat_copy_changecounted_stats Unexecuted instantiation: pgstat_relation.c:pgstat_copy_changecounted_stats Unexecuted instantiation: pgstat_replslot.c:pgstat_copy_changecounted_stats Unexecuted instantiation: pgstat_shmem.c:pgstat_copy_changecounted_stats Unexecuted instantiation: pgstat_slru.c:pgstat_copy_changecounted_stats Unexecuted instantiation: pgstat_subscription.c:pgstat_copy_changecounted_stats Unexecuted instantiation: pgstat_wal.c:pgstat_copy_changecounted_stats Unexecuted instantiation: pgstat_xact.c:pgstat_copy_changecounted_stats |
905 | | |
906 | | /* helpers for dshash / simplehash hashtables */ |
907 | | static inline int |
908 | | pgstat_cmp_hash_key(const void *a, const void *b, size_t size, void *arg) |
909 | 0 | { |
910 | 0 | Assert(size == sizeof(PgStat_HashKey) && arg == NULL); |
911 | 0 | return memcmp(a, b, sizeof(PgStat_HashKey)); |
912 | 0 | } Unexecuted instantiation: xlog.c:pgstat_cmp_hash_key Unexecuted instantiation: xlogrecovery.c:pgstat_cmp_hash_key Unexecuted instantiation: walsender.c:pgstat_cmp_hash_key Unexecuted instantiation: pgstat.c:pgstat_cmp_hash_key Unexecuted instantiation: pgstat_archiver.c:pgstat_cmp_hash_key Unexecuted instantiation: pgstat_backend.c:pgstat_cmp_hash_key Unexecuted instantiation: pgstat_bgwriter.c:pgstat_cmp_hash_key Unexecuted instantiation: pgstat_checkpointer.c:pgstat_cmp_hash_key Unexecuted instantiation: pgstat_database.c:pgstat_cmp_hash_key Unexecuted instantiation: pgstat_function.c:pgstat_cmp_hash_key Unexecuted instantiation: pgstat_io.c:pgstat_cmp_hash_key Unexecuted instantiation: pgstat_relation.c:pgstat_cmp_hash_key Unexecuted instantiation: pgstat_replslot.c:pgstat_cmp_hash_key Unexecuted instantiation: pgstat_shmem.c:pgstat_cmp_hash_key Unexecuted instantiation: pgstat_slru.c:pgstat_cmp_hash_key Unexecuted instantiation: pgstat_subscription.c:pgstat_cmp_hash_key Unexecuted instantiation: pgstat_wal.c:pgstat_cmp_hash_key Unexecuted instantiation: pgstat_xact.c:pgstat_cmp_hash_key |
913 | | |
914 | | static inline uint32 |
915 | | pgstat_hash_hash_key(const void *d, size_t size, void *arg) |
916 | 0 | { |
917 | 0 | const char *key = (const char *) d; |
918 | |
|
919 | 0 | Assert(size == sizeof(PgStat_HashKey) && arg == NULL); |
920 | 0 | return fasthash32(key, size, 0); |
921 | 0 | } Unexecuted instantiation: xlog.c:pgstat_hash_hash_key Unexecuted instantiation: xlogrecovery.c:pgstat_hash_hash_key Unexecuted instantiation: walsender.c:pgstat_hash_hash_key Unexecuted instantiation: pgstat.c:pgstat_hash_hash_key Unexecuted instantiation: pgstat_archiver.c:pgstat_hash_hash_key Unexecuted instantiation: pgstat_backend.c:pgstat_hash_hash_key Unexecuted instantiation: pgstat_bgwriter.c:pgstat_hash_hash_key Unexecuted instantiation: pgstat_checkpointer.c:pgstat_hash_hash_key Unexecuted instantiation: pgstat_database.c:pgstat_hash_hash_key Unexecuted instantiation: pgstat_function.c:pgstat_hash_hash_key Unexecuted instantiation: pgstat_io.c:pgstat_hash_hash_key Unexecuted instantiation: pgstat_relation.c:pgstat_hash_hash_key Unexecuted instantiation: pgstat_replslot.c:pgstat_hash_hash_key Unexecuted instantiation: pgstat_shmem.c:pgstat_hash_hash_key Unexecuted instantiation: pgstat_slru.c:pgstat_hash_hash_key Unexecuted instantiation: pgstat_subscription.c:pgstat_hash_hash_key Unexecuted instantiation: pgstat_wal.c:pgstat_hash_hash_key Unexecuted instantiation: pgstat_xact.c:pgstat_hash_hash_key |
922 | | |
923 | | /* |
924 | | * The length of the data portion of a shared memory stats entry (i.e. without |
925 | | * transient data such as refcounts, lwlocks, ...). |
926 | | */ |
927 | | static inline size_t |
928 | | pgstat_get_entry_len(PgStat_Kind kind) |
929 | 0 | { |
930 | 0 | return pgstat_get_kind_info(kind)->shared_data_len; |
931 | 0 | } Unexecuted instantiation: xlog.c:pgstat_get_entry_len Unexecuted instantiation: xlogrecovery.c:pgstat_get_entry_len Unexecuted instantiation: walsender.c:pgstat_get_entry_len Unexecuted instantiation: pgstat.c:pgstat_get_entry_len Unexecuted instantiation: pgstat_archiver.c:pgstat_get_entry_len Unexecuted instantiation: pgstat_backend.c:pgstat_get_entry_len Unexecuted instantiation: pgstat_bgwriter.c:pgstat_get_entry_len Unexecuted instantiation: pgstat_checkpointer.c:pgstat_get_entry_len Unexecuted instantiation: pgstat_database.c:pgstat_get_entry_len Unexecuted instantiation: pgstat_function.c:pgstat_get_entry_len Unexecuted instantiation: pgstat_io.c:pgstat_get_entry_len Unexecuted instantiation: pgstat_relation.c:pgstat_get_entry_len Unexecuted instantiation: pgstat_replslot.c:pgstat_get_entry_len Unexecuted instantiation: pgstat_shmem.c:pgstat_get_entry_len Unexecuted instantiation: pgstat_slru.c:pgstat_get_entry_len Unexecuted instantiation: pgstat_subscription.c:pgstat_get_entry_len Unexecuted instantiation: pgstat_wal.c:pgstat_get_entry_len Unexecuted instantiation: pgstat_xact.c:pgstat_get_entry_len |
932 | | |
933 | | /* |
934 | | * Returns a pointer to the data portion of a shared memory stats entry. |
935 | | */ |
936 | | static inline void * |
937 | | pgstat_get_entry_data(PgStat_Kind kind, PgStatShared_Common *entry) |
938 | 0 | { |
939 | 0 | size_t off = pgstat_get_kind_info(kind)->shared_data_off; |
940 | |
|
941 | 0 | Assert(off != 0 && off < PG_UINT32_MAX); |
942 | |
|
943 | 0 | return ((char *) (entry)) + off; |
944 | 0 | } Unexecuted instantiation: xlog.c:pgstat_get_entry_data Unexecuted instantiation: xlogrecovery.c:pgstat_get_entry_data Unexecuted instantiation: walsender.c:pgstat_get_entry_data Unexecuted instantiation: pgstat.c:pgstat_get_entry_data Unexecuted instantiation: pgstat_archiver.c:pgstat_get_entry_data Unexecuted instantiation: pgstat_backend.c:pgstat_get_entry_data Unexecuted instantiation: pgstat_bgwriter.c:pgstat_get_entry_data Unexecuted instantiation: pgstat_checkpointer.c:pgstat_get_entry_data Unexecuted instantiation: pgstat_database.c:pgstat_get_entry_data Unexecuted instantiation: pgstat_function.c:pgstat_get_entry_data Unexecuted instantiation: pgstat_io.c:pgstat_get_entry_data Unexecuted instantiation: pgstat_relation.c:pgstat_get_entry_data Unexecuted instantiation: pgstat_replslot.c:pgstat_get_entry_data Unexecuted instantiation: pgstat_shmem.c:pgstat_get_entry_data Unexecuted instantiation: pgstat_slru.c:pgstat_get_entry_data Unexecuted instantiation: pgstat_subscription.c:pgstat_get_entry_data Unexecuted instantiation: pgstat_wal.c:pgstat_get_entry_data Unexecuted instantiation: pgstat_xact.c:pgstat_get_entry_data |
945 | | |
946 | | /* |
947 | | * Returns the number of entries counted for a stats kind. |
948 | | */ |
949 | | static inline uint64 |
950 | | pgstat_get_entry_count(PgStat_Kind kind) |
951 | 0 | { |
952 | 0 | Assert(pgstat_get_kind_info(kind)->track_entry_count); |
953 | 0 |
|
954 | 0 | return pg_atomic_read_u64(&pgStatLocal.shmem->entry_counts[kind - 1]); |
955 | 0 | } Unexecuted instantiation: xlog.c:pgstat_get_entry_count Unexecuted instantiation: xlogrecovery.c:pgstat_get_entry_count Unexecuted instantiation: walsender.c:pgstat_get_entry_count Unexecuted instantiation: pgstat.c:pgstat_get_entry_count Unexecuted instantiation: pgstat_archiver.c:pgstat_get_entry_count Unexecuted instantiation: pgstat_backend.c:pgstat_get_entry_count Unexecuted instantiation: pgstat_bgwriter.c:pgstat_get_entry_count Unexecuted instantiation: pgstat_checkpointer.c:pgstat_get_entry_count Unexecuted instantiation: pgstat_database.c:pgstat_get_entry_count Unexecuted instantiation: pgstat_function.c:pgstat_get_entry_count Unexecuted instantiation: pgstat_io.c:pgstat_get_entry_count Unexecuted instantiation: pgstat_relation.c:pgstat_get_entry_count Unexecuted instantiation: pgstat_replslot.c:pgstat_get_entry_count Unexecuted instantiation: pgstat_shmem.c:pgstat_get_entry_count Unexecuted instantiation: pgstat_slru.c:pgstat_get_entry_count Unexecuted instantiation: pgstat_subscription.c:pgstat_get_entry_count Unexecuted instantiation: pgstat_wal.c:pgstat_get_entry_count Unexecuted instantiation: pgstat_xact.c:pgstat_get_entry_count |
956 | | |
957 | | /* |
958 | | * Returns a pointer to the shared memory area of custom stats for |
959 | | * fixed-numbered statistics. |
960 | | */ |
961 | | static inline void * |
962 | | pgstat_get_custom_shmem_data(PgStat_Kind kind) |
963 | 0 | { |
964 | 0 | int idx = kind - PGSTAT_KIND_CUSTOM_MIN; |
965 | 0 |
|
966 | 0 | Assert(pgstat_is_kind_custom(kind)); |
967 | 0 | Assert(pgstat_get_kind_info(kind)->fixed_amount); |
968 | 0 |
|
969 | 0 | return pgStatLocal.shmem->custom_data[idx]; |
970 | 0 | } Unexecuted instantiation: xlog.c:pgstat_get_custom_shmem_data Unexecuted instantiation: xlogrecovery.c:pgstat_get_custom_shmem_data Unexecuted instantiation: walsender.c:pgstat_get_custom_shmem_data Unexecuted instantiation: pgstat.c:pgstat_get_custom_shmem_data Unexecuted instantiation: pgstat_archiver.c:pgstat_get_custom_shmem_data Unexecuted instantiation: pgstat_backend.c:pgstat_get_custom_shmem_data Unexecuted instantiation: pgstat_bgwriter.c:pgstat_get_custom_shmem_data Unexecuted instantiation: pgstat_checkpointer.c:pgstat_get_custom_shmem_data Unexecuted instantiation: pgstat_database.c:pgstat_get_custom_shmem_data Unexecuted instantiation: pgstat_function.c:pgstat_get_custom_shmem_data Unexecuted instantiation: pgstat_io.c:pgstat_get_custom_shmem_data Unexecuted instantiation: pgstat_relation.c:pgstat_get_custom_shmem_data Unexecuted instantiation: pgstat_replslot.c:pgstat_get_custom_shmem_data Unexecuted instantiation: pgstat_shmem.c:pgstat_get_custom_shmem_data Unexecuted instantiation: pgstat_slru.c:pgstat_get_custom_shmem_data Unexecuted instantiation: pgstat_subscription.c:pgstat_get_custom_shmem_data Unexecuted instantiation: pgstat_wal.c:pgstat_get_custom_shmem_data Unexecuted instantiation: pgstat_xact.c:pgstat_get_custom_shmem_data |
971 | | |
972 | | /* |
973 | | * Returns a pointer to the portion of custom data for fixed-numbered |
974 | | * statistics in the current snapshot. |
975 | | */ |
976 | | static inline void * |
977 | | pgstat_get_custom_snapshot_data(PgStat_Kind kind) |
978 | 0 | { |
979 | 0 | int idx = kind - PGSTAT_KIND_CUSTOM_MIN; |
980 | 0 |
|
981 | 0 | Assert(pgstat_is_kind_custom(kind)); |
982 | 0 | Assert(pgstat_get_kind_info(kind)->fixed_amount); |
983 | 0 |
|
984 | 0 | return pgStatLocal.snapshot.custom_data[idx]; |
985 | 0 | } Unexecuted instantiation: xlog.c:pgstat_get_custom_snapshot_data Unexecuted instantiation: xlogrecovery.c:pgstat_get_custom_snapshot_data Unexecuted instantiation: walsender.c:pgstat_get_custom_snapshot_data Unexecuted instantiation: pgstat.c:pgstat_get_custom_snapshot_data Unexecuted instantiation: pgstat_archiver.c:pgstat_get_custom_snapshot_data Unexecuted instantiation: pgstat_backend.c:pgstat_get_custom_snapshot_data Unexecuted instantiation: pgstat_bgwriter.c:pgstat_get_custom_snapshot_data Unexecuted instantiation: pgstat_checkpointer.c:pgstat_get_custom_snapshot_data Unexecuted instantiation: pgstat_database.c:pgstat_get_custom_snapshot_data Unexecuted instantiation: pgstat_function.c:pgstat_get_custom_snapshot_data Unexecuted instantiation: pgstat_io.c:pgstat_get_custom_snapshot_data Unexecuted instantiation: pgstat_relation.c:pgstat_get_custom_snapshot_data Unexecuted instantiation: pgstat_replslot.c:pgstat_get_custom_snapshot_data Unexecuted instantiation: pgstat_shmem.c:pgstat_get_custom_snapshot_data Unexecuted instantiation: pgstat_slru.c:pgstat_get_custom_snapshot_data Unexecuted instantiation: pgstat_subscription.c:pgstat_get_custom_snapshot_data Unexecuted instantiation: pgstat_wal.c:pgstat_get_custom_snapshot_data Unexecuted instantiation: pgstat_xact.c:pgstat_get_custom_snapshot_data |
986 | | |
987 | | #endif /* PGSTAT_INTERNAL_H */ |