PostgreSQL Source Code git master
Loading...
Searching...
No Matches
pgstat_backend.c
Go to the documentation of this file.
1/* -------------------------------------------------------------------------
2 *
3 * pgstat_backend.c
4 * Implementation of backend statistics.
5 *
6 * This file contains the implementation of backend statistics. It is kept
7 * separate from pgstat.c to enforce the line between the statistics access /
8 * storage implementation and the details about individual types of
9 * statistics.
10 *
11 * This statistics kind uses a proc number as object ID for the hash table
12 * of pgstats. Entries are created each time a process is spawned, and are
13 * dropped when the process exits. These are not written to the pgstats file
14 * on disk. Pending statistics are managed without direct interactions with
15 * PgStat_EntryRef->pending, relying on PendingBackendStats instead so as it
16 * is possible to report data within critical sections.
17 *
18 * Copyright (c) 2001-2026, PostgreSQL Global Development Group
19 *
20 * IDENTIFICATION
21 * src/backend/utils/activity/pgstat_backend.c
22 * -------------------------------------------------------------------------
23 */
24
25#include "postgres.h"
26
27#include "access/xlog.h"
28#include "executor/instrument.h"
29#include "storage/bufmgr.h"
30#include "storage/proc.h"
31#include "storage/procarray.h"
32#include "utils/memutils.h"
34
35/*
36 * Backend statistics counts waiting to be flushed out. These counters may be
37 * reported within critical sections so we use static memory in order to avoid
38 * memory allocation.
39 */
41static bool backend_has_iostats = false;
42
43/*
44 * WAL usage counters saved from pgWalUsage at the previous call to
45 * pgstat_flush_backend(). This is used to calculate how much WAL usage
46 * happens between pgstat_flush_backend() calls, by subtracting the
47 * previous counters from the current ones.
48 */
50
51/*
52 * Utility routines to report I/O stats for backends, kept here to avoid
53 * exposing PendingBackendStats to the outside world.
54 */
55void
72
73void
88
89/*
90 * Returns statistics of a backend by proc number.
91 */
103
104/*
105 * Returns statistics of a backend by pid.
106 *
107 * This routine includes sanity checks to ensure that the backend exists and
108 * is running. "bktype" can be optionally defined to return the BackendType
109 * of the backend whose statistics are returned.
110 */
113{
114 PGPROC *proc;
116 ProcNumber procNumber;
118
119 proc = BackendPidGetProc(pid);
120 if (bktype)
121 *bktype = B_INVALID;
122
123 /* this could be an auxiliary process */
124 if (!proc)
125 proc = AuxiliaryPidGetProc(pid);
126
127 if (!proc)
128 return NULL;
129
130 procNumber = GetNumberFromPGProc(proc);
131
133 if (!beentry)
134 return NULL;
135
136 /* check if the backend type tracks statistics */
137 if (!pgstat_tracks_backend_bktype(beentry->st_backendType))
138 return NULL;
139
140 /* if PID does not match, leave */
141 if (beentry->st_procpid != pid)
142 return NULL;
143
144 if (bktype)
145 *bktype = beentry->st_backendType;
146
147 /*
148 * Retrieve the entry. Note that "beentry" may be freed depending on the
149 * value of stats_fetch_consistency, so do not access it from this point.
150 */
152 if (!backend_stats)
153 {
154 if (bktype)
155 *bktype = B_INVALID;
156 return NULL;
157 }
158
159 return backend_stats;
160}
161
162/*
163 * Flush out locally pending backend IO statistics. Locking is managed
164 * by the caller.
165 */
166static void
168{
171 PgStat_PendingIO pending_io;
172
173 /*
174 * This function can be called even if nothing at all has happened for IO
175 * statistics. In this case, avoid unnecessarily modifying the stats
176 * entry.
177 */
179 return;
180
182 bktype_shstats = &shbackendent->stats.io_stats;
183 pending_io = PendingBackendStats.pending_io;
184
186 {
188 {
189 for (int io_op = 0; io_op < IOOP_NUM_TYPES; io_op++)
190 {
191 instr_time time;
192
194 pending_io.counts[io_object][io_context][io_op];
196 pending_io.bytes[io_object][io_context][io_op];
197 time = pending_io.pending_times[io_object][io_context][io_op];
198
201 }
202 }
203 }
204
205 /*
206 * Clear out the statistics buffer, so it can be re-used.
207 */
209
210 backend_has_iostats = false;
211}
212
213/*
214 * To determine whether WAL usage happened.
215 */
216static inline bool
221
222/*
223 * Flush out locally pending backend WAL statistics. Locking is managed
224 * by the caller.
225 */
226static void
228{
232
233 /*
234 * This function can be called even if nothing at all has happened for WAL
235 * statistics. In this case, avoid unnecessarily modifying the stats
236 * entry.
237 */
239 return;
240
242 bktype_shstats = &shbackendent->stats.wal_counters;
243
244 /*
245 * Calculate how much WAL usage counters were increased by subtracting the
246 * previous counters from the current ones.
247 */
249
250#define WALSTAT_ACC(fld, var_to_add) \
251 (bktype_shstats->fld += var_to_add.fld)
252 WALSTAT_ACC(wal_buffers_full, wal_usage_diff);
253 WALSTAT_ACC(wal_records, wal_usage_diff);
254 WALSTAT_ACC(wal_fpi, wal_usage_diff);
255 WALSTAT_ACC(wal_bytes, wal_usage_diff);
256 WALSTAT_ACC(wal_fpi_bytes, wal_usage_diff);
257#undef WALSTAT_ACC
258
259 /*
260 * Save the current counters for the subsequent calculation of WAL usage.
261 */
263}
264
265/*
266 * Flush out locally pending backend statistics
267 *
268 * "flags" parameter controls which statistics to flush. Returns true
269 * if some statistics could not be flushed due to lock contention.
270 */
271bool
272pgstat_flush_backend(bool nowait, uint32 flags)
273{
274 PgStat_EntryRef *entry_ref;
275 bool has_pending_data = false;
276
278 return false;
279
280 /* Some IO data pending? */
282 has_pending_data = true;
283
284 /* Some WAL data pending? */
285 if ((flags & PGSTAT_BACKEND_FLUSH_WAL) &&
287 has_pending_data = true;
288
289 if (!has_pending_data)
290 return false;
291
293 MyProcNumber, nowait);
294 if (!entry_ref)
295 return true;
296
297 /* Flush requested statistics */
298 if (flags & PGSTAT_BACKEND_FLUSH_IO)
300
301 if (flags & PGSTAT_BACKEND_FLUSH_WAL)
303
304 pgstat_unlock_entry(entry_ref);
305
306 return false;
307}
308
309/*
310 * Callback to flush out locally pending backend statistics.
311 *
312 * If some stats could not be flushed due to lock contention, return true.
313 */
314bool
319
320/*
321 * Create backend statistics entry for proc number.
322 */
323void
325{
326 PgStat_EntryRef *entry_ref;
328
330 procnum, false);
332
333 /*
334 * NB: need to accept that there might be stats from an older backend,
335 * e.g. if we previously used this proc number.
336 */
337 memset(&shstatent->stats, 0, sizeof(shstatent->stats));
338 pgstat_unlock_entry(entry_ref);
339
341 backend_has_iostats = false;
342
343 /*
344 * Initialize prevBackendWalUsage with pgWalUsage so that
345 * pgstat_backend_flush_cb() can calculate how much pgWalUsage counters
346 * are increased by subtracting prevBackendWalUsage from pgWalUsage.
347 */
349}
350
351/*
352 * Backend statistics are not collected for all BackendTypes.
353 *
354 * The following BackendTypes do not participate in the backend stats
355 * subsystem:
356 * - The same and for the same reasons as in pgstat_tracks_io_bktype().
357 * - B_BG_WRITER, B_CHECKPOINTER, B_STARTUP and B_AUTOVAC_LAUNCHER because their
358 * I/O stats are already visible in pg_stat_io and there is only one of those.
359 *
360 * Function returns true if BackendType participates in the backend stats
361 * subsystem and false if it does not.
362 *
363 * When adding a new BackendType, also consider adding relevant restrictions to
364 * pgstat_tracks_io_object() and pgstat_tracks_io_op().
365 */
366bool
368{
369 /*
370 * List every type so that new backend types trigger a warning about
371 * needing to adjust this switch.
372 */
373 switch (bktype)
374 {
375 case B_INVALID:
378 case B_ARCHIVER:
379 case B_LOGGER:
380 case B_BG_WRITER:
381 case B_CHECKPOINTER:
382 case B_IO_WORKER:
383 case B_STARTUP:
386 return false;
387
388 case B_AUTOVAC_WORKER:
389 case B_BACKEND:
390 case B_BG_WORKER:
393 case B_WAL_RECEIVER:
394 case B_WAL_SENDER:
395 case B_WAL_SUMMARIZER:
396 case B_WAL_WRITER:
397 return true;
398 }
399
400 return false;
401}
402
403void
405{
406 ((PgStatShared_Backend *) header)->stats.stat_reset_timestamp = ts;
407}
PgBackendStatus * pgstat_get_beentry_by_proc_number(ProcNumber procNumber)
bool track_io_timing
Definition bufmgr.c:192
#define Assert(condition)
Definition c.h:943
uint64_t uint64
Definition c.h:625
uint32_t uint32
Definition c.h:624
#define MemSet(start, val, len)
Definition c.h:1107
int64 TimestampTz
Definition timestamp.h:39
ProcNumber MyProcNumber
Definition globals.c:92
#define INSTR_TIME_ADD(x, y)
Definition instr_time.h:430
#define INSTR_TIME_GET_MICROSEC(t)
Definition instr_time.h:454
WalUsage pgWalUsage
Definition instrument.c:27
void WalUsageAccumDiff(WalUsage *dst, const WalUsage *add, const WalUsage *sub)
Definition instrument.c:367
BackendType
Definition miscadmin.h:350
@ B_WAL_SUMMARIZER
Definition miscadmin.h:379
@ B_WAL_WRITER
Definition miscadmin.h:380
@ B_WAL_RECEIVER
Definition miscadmin.h:378
@ B_CHECKPOINTER
Definition miscadmin.h:375
@ B_DATACHECKSUMSWORKER_WORKER
Definition miscadmin.h:383
@ B_WAL_SENDER
Definition miscadmin.h:359
@ B_IO_WORKER
Definition miscadmin.h:376
@ B_LOGGER
Definition miscadmin.h:389
@ B_STARTUP
Definition miscadmin.h:377
@ B_DATACHECKSUMSWORKER_LAUNCHER
Definition miscadmin.h:382
@ B_BG_WORKER
Definition miscadmin.h:358
@ B_INVALID
Definition miscadmin.h:351
@ B_STANDALONE_BACKEND
Definition miscadmin.h:362
@ B_BG_WRITER
Definition miscadmin.h:374
@ B_BACKEND
Definition miscadmin.h:354
@ B_ARCHIVER
Definition miscadmin.h:373
@ B_AUTOVAC_LAUNCHER
Definition miscadmin.h:356
@ B_SLOTSYNC_WORKER
Definition miscadmin.h:360
@ B_DEAD_END_BACKEND
Definition miscadmin.h:355
@ B_AUTOVAC_WORKER
Definition miscadmin.h:357
BackendType MyBackendType
Definition miscinit.c:65
void * pgstat_fetch_entry(PgStat_Kind kind, Oid dboid, uint64 objid, bool *may_free)
Definition pgstat.c:962
bool pgstat_report_fixed
Definition pgstat.c:219
IOObject
Definition pgstat.h:280
#define IOOP_NUM_TYPES
Definition pgstat.h:323
IOContext
Definition pgstat.h:289
#define IOCONTEXT_NUM_TYPES
Definition pgstat.h:297
IOOp
Definition pgstat.h:309
#define IOOBJECT_NUM_TYPES
Definition pgstat.h:286
void pgstat_create_backend(ProcNumber procnum)
static void pgstat_flush_backend_entry_wal(PgStat_EntryRef *entry_ref)
static PgStat_BackendPending PendingBackendStats
bool pgstat_tracks_backend_bktype(BackendType bktype)
#define WALSTAT_ACC(fld, var_to_add)
static void pgstat_flush_backend_entry_io(PgStat_EntryRef *entry_ref)
void pgstat_count_backend_io_op(IOObject io_object, IOContext io_context, IOOp io_op, uint32 cnt, uint64 bytes)
static bool pgstat_backend_wal_have_pending(void)
static bool backend_has_iostats
bool pgstat_flush_backend(bool nowait, uint32 flags)
void pgstat_backend_reset_timestamp_cb(PgStatShared_Common *header, TimestampTz ts)
static WalUsage prevBackendWalUsage
PgStat_Backend * pgstat_fetch_stat_backend_by_pid(int pid, BackendType *bktype)
void pgstat_count_backend_io_op_time(IOObject io_object, IOContext io_context, IOOp io_op, instr_time io_time)
bool pgstat_backend_flush_cb(bool nowait)
PgStat_Backend * pgstat_fetch_stat_backend(ProcNumber procNumber)
#define PGSTAT_BACKEND_FLUSH_ALL
#define PGSTAT_BACKEND_FLUSH_IO
#define PGSTAT_BACKEND_FLUSH_WAL
bool pgstat_tracks_io_op(BackendType bktype, IOObject io_object, IOContext io_context, IOOp io_op)
Definition pgstat_io.c:479
#define PGSTAT_KIND_BACKEND
Definition pgstat_kind.h:32
void pgstat_unlock_entry(PgStat_EntryRef *entry_ref)
PgStat_EntryRef * pgstat_get_entry_ref_locked(PgStat_Kind kind, Oid dboid, uint64 objid, bool nowait)
#define InvalidOid
static int fb(int x)
#define GetNumberFromPGProc(proc)
Definition proc.h:505
PGPROC * BackendPidGetProc(int pid)
Definition procarray.c:3169
int ProcNumber
Definition procnumber.h:24
PGPROC * AuxiliaryPidGetProc(int pid)
Definition proc.c:1097
Definition proc.h:179
PgStat_PendingIO pending_io
Definition pgstat.h:537
PgStatShared_Common * shared_stats
PgStat_Counter counts[IOOBJECT_NUM_TYPES][IOCONTEXT_NUM_TYPES][IOOP_NUM_TYPES]
Definition pgstat.h:339
uint64 bytes[IOOBJECT_NUM_TYPES][IOCONTEXT_NUM_TYPES][IOOP_NUM_TYPES]
Definition pgstat.h:338
instr_time pending_times[IOOBJECT_NUM_TYPES][IOCONTEXT_NUM_TYPES][IOOP_NUM_TYPES]
Definition pgstat.h:340
int64 wal_records
Definition instrument.h:53
bool track_wal_io_timing
Definition xlog.c:144