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 */
102
103/*
104 * Returns statistics of a backend by pid.
105 *
106 * This routine includes sanity checks to ensure that the backend exists and
107 * is running. "bktype" can be optionally defined to return the BackendType
108 * of the backend whose statistics are returned.
109 */
112{
113 PGPROC *proc;
115 ProcNumber procNumber;
117
118 proc = BackendPidGetProc(pid);
119 if (bktype)
120 *bktype = B_INVALID;
121
122 /* this could be an auxiliary process */
123 if (!proc)
124 proc = AuxiliaryPidGetProc(pid);
125
126 if (!proc)
127 return NULL;
128
129 procNumber = GetNumberFromPGProc(proc);
130
132 if (!beentry)
133 return NULL;
134
135 /* check if the backend type tracks statistics */
136 if (!pgstat_tracks_backend_bktype(beentry->st_backendType))
137 return NULL;
138
139 /* if PID does not match, leave */
140 if (beentry->st_procpid != pid)
141 return NULL;
142
143 if (bktype)
144 *bktype = beentry->st_backendType;
145
146 /*
147 * Retrieve the entry. Note that "beentry" may be freed depending on the
148 * value of stats_fetch_consistency, so do not access it from this point.
149 */
151 if (!backend_stats)
152 {
153 if (bktype)
154 *bktype = B_INVALID;
155 return NULL;
156 }
157
158 return backend_stats;
159}
160
161/*
162 * Flush out locally pending backend IO statistics. Locking is managed
163 * by the caller.
164 */
165static void
167{
170 PgStat_PendingIO pending_io;
171
172 /*
173 * This function can be called even if nothing at all has happened for IO
174 * statistics. In this case, avoid unnecessarily modifying the stats
175 * entry.
176 */
178 return;
179
181 bktype_shstats = &shbackendent->stats.io_stats;
182 pending_io = PendingBackendStats.pending_io;
183
185 {
187 {
188 for (int io_op = 0; io_op < IOOP_NUM_TYPES; io_op++)
189 {
190 instr_time time;
191
193 pending_io.counts[io_object][io_context][io_op];
195 pending_io.bytes[io_object][io_context][io_op];
196 time = pending_io.pending_times[io_object][io_context][io_op];
197
200 }
201 }
202 }
203
204 /*
205 * Clear out the statistics buffer, so it can be re-used.
206 */
208
209 backend_has_iostats = false;
210}
211
212/*
213 * To determine whether WAL usage happened.
214 */
215static inline bool
220
221/*
222 * Flush out locally pending backend WAL statistics. Locking is managed
223 * by the caller.
224 */
225static void
227{
231
232 /*
233 * This function can be called even if nothing at all has happened for WAL
234 * statistics. In this case, avoid unnecessarily modifying the stats
235 * entry.
236 */
238 return;
239
241 bktype_shstats = &shbackendent->stats.wal_counters;
242
243 /*
244 * Calculate how much WAL usage counters were increased by subtracting the
245 * previous counters from the current ones.
246 */
248
249#define WALSTAT_ACC(fld, var_to_add) \
250 (bktype_shstats->fld += var_to_add.fld)
251 WALSTAT_ACC(wal_buffers_full, wal_usage_diff);
252 WALSTAT_ACC(wal_records, wal_usage_diff);
253 WALSTAT_ACC(wal_fpi, wal_usage_diff);
254 WALSTAT_ACC(wal_bytes, wal_usage_diff);
255 WALSTAT_ACC(wal_fpi_bytes, wal_usage_diff);
256#undef WALSTAT_ACC
257
258 /*
259 * Save the current counters for the subsequent calculation of WAL usage.
260 */
262}
263
264/*
265 * Flush out locally pending backend statistics
266 *
267 * "flags" parameter controls which statistics to flush. Returns true
268 * if some statistics could not be flushed due to lock contention.
269 */
270bool
271pgstat_flush_backend(bool nowait, bits32 flags)
272{
273 PgStat_EntryRef *entry_ref;
274 bool has_pending_data = false;
275
277 return false;
278
279 /* Some IO data pending? */
281 has_pending_data = true;
282
283 /* Some WAL data pending? */
284 if ((flags & PGSTAT_BACKEND_FLUSH_WAL) &&
286 has_pending_data = true;
287
288 if (!has_pending_data)
289 return false;
290
292 MyProcNumber, nowait);
293 if (!entry_ref)
294 return true;
295
296 /* Flush requested statistics */
297 if (flags & PGSTAT_BACKEND_FLUSH_IO)
299
300 if (flags & PGSTAT_BACKEND_FLUSH_WAL)
302
303 pgstat_unlock_entry(entry_ref);
304
305 return false;
306}
307
308/*
309 * Callback to flush out locally pending backend statistics.
310 *
311 * If some stats could not be flushed due to lock contention, return true.
312 */
313bool
318
319/*
320 * Create backend statistics entry for proc number.
321 */
322void
324{
325 PgStat_EntryRef *entry_ref;
327
329 MyProcNumber, false);
331
332 /*
333 * NB: need to accept that there might be stats from an older backend,
334 * e.g. if we previously used this proc number.
335 */
336 memset(&shstatent->stats, 0, sizeof(shstatent->stats));
337 pgstat_unlock_entry(entry_ref);
338
340 backend_has_iostats = false;
341
342 /*
343 * Initialize prevBackendWalUsage with pgWalUsage so that
344 * pgstat_backend_flush_cb() can calculate how much pgWalUsage counters
345 * are increased by subtracting prevBackendWalUsage from pgWalUsage.
346 */
348}
349
350/*
351 * Backend statistics are not collected for all BackendTypes.
352 *
353 * The following BackendTypes do not participate in the backend stats
354 * subsystem:
355 * - The same and for the same reasons as in pgstat_tracks_io_bktype().
356 * - B_BG_WRITER, B_CHECKPOINTER, B_STARTUP and B_AUTOVAC_LAUNCHER because their
357 * I/O stats are already visible in pg_stat_io and there is only one of those.
358 *
359 * Function returns true if BackendType participates in the backend stats
360 * subsystem and false if it does not.
361 *
362 * When adding a new BackendType, also consider adding relevant restrictions to
363 * pgstat_tracks_io_object() and pgstat_tracks_io_op().
364 */
365bool
367{
368 /*
369 * List every type so that new backend types trigger a warning about
370 * needing to adjust this switch.
371 */
372 switch (bktype)
373 {
374 case B_INVALID:
377 case B_ARCHIVER:
378 case B_LOGGER:
379 case B_BG_WRITER:
380 case B_CHECKPOINTER:
381 case B_IO_WORKER:
382 case B_STARTUP:
383 return false;
384
385 case B_AUTOVAC_WORKER:
386 case B_BACKEND:
387 case B_BG_WORKER:
390 case B_WAL_RECEIVER:
391 case B_WAL_SENDER:
392 case B_WAL_SUMMARIZER:
393 case B_WAL_WRITER:
394 return true;
395 }
396
397 return false;
398}
399
400void
402{
403 ((PgStatShared_Backend *) header)->stats.stat_reset_timestamp = ts;
404}
PgBackendStatus * pgstat_get_beentry_by_proc_number(ProcNumber procNumber)
bool track_io_timing
Definition bufmgr.c:176
#define Assert(condition)
Definition c.h:883
uint32 bits32
Definition c.h:565
uint64_t uint64
Definition c.h:557
uint32_t uint32
Definition c.h:556
#define MemSet(start, val, len)
Definition c.h:1023
int64 TimestampTz
Definition timestamp.h:39
ProcNumber MyProcNumber
Definition globals.c:90
#define INSTR_TIME_ADD(x, y)
Definition instr_time.h:178
#define INSTR_TIME_GET_MICROSEC(t)
Definition instr_time.h:196
WalUsage pgWalUsage
Definition instrument.c:22
void WalUsageAccumDiff(WalUsage *dst, const WalUsage *add, const WalUsage *sub)
Definition instrument.c:285
BackendType
Definition miscadmin.h:338
@ B_WAL_SUMMARIZER
Definition miscadmin.h:367
@ B_WAL_WRITER
Definition miscadmin.h:368
@ B_WAL_RECEIVER
Definition miscadmin.h:366
@ B_CHECKPOINTER
Definition miscadmin.h:363
@ B_WAL_SENDER
Definition miscadmin.h:347
@ B_IO_WORKER
Definition miscadmin.h:364
@ B_LOGGER
Definition miscadmin.h:374
@ B_STARTUP
Definition miscadmin.h:365
@ B_BG_WORKER
Definition miscadmin.h:346
@ B_INVALID
Definition miscadmin.h:339
@ B_STANDALONE_BACKEND
Definition miscadmin.h:350
@ B_BG_WRITER
Definition miscadmin.h:362
@ B_BACKEND
Definition miscadmin.h:342
@ B_ARCHIVER
Definition miscadmin.h:361
@ B_AUTOVAC_LAUNCHER
Definition miscadmin.h:344
@ B_SLOTSYNC_WORKER
Definition miscadmin.h:348
@ B_DEAD_END_BACKEND
Definition miscadmin.h:343
@ B_AUTOVAC_WORKER
Definition miscadmin.h:345
BackendType MyBackendType
Definition miscinit.c:64
bool pgstat_report_fixed
Definition pgstat.c:218
void * pgstat_fetch_entry(PgStat_Kind kind, Oid dboid, uint64 objid)
Definition pgstat.c:944
IOObject
Definition pgstat.h:276
#define IOOP_NUM_TYPES
Definition pgstat.h:319
IOContext
Definition pgstat.h:285
#define IOCONTEXT_NUM_TYPES
Definition pgstat.h:293
IOOp
Definition pgstat.h:305
#define IOOBJECT_NUM_TYPES
Definition pgstat.h:282
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
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_flush_backend(bool nowait, bits32 flags)
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:477
#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:447
PGPROC * BackendPidGetProc(int pid)
Definition procarray.c:3159
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:515
PgStatShared_Common * shared_stats
PgStat_Counter counts[IOOBJECT_NUM_TYPES][IOCONTEXT_NUM_TYPES][IOOP_NUM_TYPES]
Definition pgstat.h:335
uint64 bytes[IOOBJECT_NUM_TYPES][IOCONTEXT_NUM_TYPES][IOOP_NUM_TYPES]
Definition pgstat.h:334
instr_time pending_times[IOOBJECT_NUM_TYPES][IOCONTEXT_NUM_TYPES][IOOP_NUM_TYPES]
Definition pgstat.h:336
int64 wal_records
Definition instrument.h:53
bool track_wal_io_timing
Definition xlog.c:140