PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
pgstat_io.c
Go to the documentation of this file.
1/* -------------------------------------------------------------------------
2 *
3 * pgstat_io.c
4 * Implementation of IO statistics.
5 *
6 * This file contains the implementation of IO statistics. It is kept separate
7 * from pgstat.c to enforce the line between the statistics access / storage
8 * implementation and the details about individual types of statistics.
9 *
10 * Copyright (c) 2021-2025, PostgreSQL Global Development Group
11 *
12 * IDENTIFICATION
13 * src/backend/utils/activity/pgstat_io.c
14 * -------------------------------------------------------------------------
15 */
16
17#include "postgres.h"
18
19#include "executor/instrument.h"
20#include "storage/bufmgr.h"
22
24static bool have_iostats = false;
25
26/*
27 * Check that stats have not been counted for any combination of IOObject,
28 * IOContext, and IOOp which are not tracked for the passed-in BackendType. If
29 * stats are tracked for this combination and IO times are non-zero, counts
30 * should be non-zero.
31 *
32 * The passed-in PgStat_BktypeIO must contain stats from the BackendType
33 * specified by the second parameter. Caller is responsible for locking the
34 * passed-in PgStat_BktypeIO, if needed.
35 */
36bool
38 BackendType bktype)
39{
40 for (int io_object = 0; io_object < IOOBJECT_NUM_TYPES; io_object++)
41 {
42 for (int io_context = 0; io_context < IOCONTEXT_NUM_TYPES; io_context++)
43 {
44 for (int io_op = 0; io_op < IOOP_NUM_TYPES; io_op++)
45 {
46 /* we do track it */
47 if (pgstat_tracks_io_op(bktype, io_object, io_context, io_op))
48 {
49 /* ensure that if IO times are non-zero, counts are > 0 */
50 if (backend_io->times[io_object][io_context][io_op] != 0 &&
51 backend_io->counts[io_object][io_context][io_op] <= 0)
52 return false;
53
54 continue;
55 }
56
57 /* we don't track it, and it is not 0 */
58 if (backend_io->counts[io_object][io_context][io_op] != 0)
59 return false;
60 }
61 }
62 }
63
64 return true;
65}
66
67void
68pgstat_count_io_op(IOObject io_object, IOContext io_context, IOOp io_op,
69 uint32 cnt, uint64 bytes)
70{
71 Assert((unsigned int) io_object < IOOBJECT_NUM_TYPES);
72 Assert((unsigned int) io_context < IOCONTEXT_NUM_TYPES);
73 Assert(pgstat_is_ioop_tracked_in_bytes(io_op) || bytes == 0);
74 Assert(pgstat_tracks_io_op(MyBackendType, io_object, io_context, io_op));
75
76 PendingIOStats.counts[io_object][io_context][io_op] += cnt;
77 PendingIOStats.bytes[io_object][io_context][io_op] += bytes;
78
79 /* Add the per-backend counts */
80 pgstat_count_backend_io_op(io_object, io_context, io_op, cnt, bytes);
81
82 have_iostats = true;
83}
84
85/*
86 * Initialize the internal timing for an IO operation, depending on an
87 * IO timing GUC.
88 */
90pgstat_prepare_io_time(bool track_io_guc)
91{
92 instr_time io_start;
93
94 if (track_io_guc)
95 INSTR_TIME_SET_CURRENT(io_start);
96 else
97 {
98 /*
99 * There is no need to set io_start when an IO timing GUC is disabled.
100 * Initialize it to zero to avoid compiler warnings and to let
101 * pgstat_count_io_op_time() know that timings should be ignored.
102 */
103 INSTR_TIME_SET_ZERO(io_start);
104 }
105
106 return io_start;
107}
108
109/*
110 * Like pgstat_count_io_op() except it also accumulates time.
111 *
112 * The calls related to pgstat_count_buffer_*() are for pgstat_database. As
113 * pg_stat_database only counts block read and write times, these are done for
114 * IOOP_READ, IOOP_WRITE and IOOP_EXTEND.
115 *
116 * pgBufferUsage is used for EXPLAIN. pgBufferUsage has write and read stats
117 * for shared, local and temporary blocks. pg_stat_io does not track the
118 * activity of temporary blocks, so these are ignored here.
119 */
120void
121pgstat_count_io_op_time(IOObject io_object, IOContext io_context, IOOp io_op,
123{
125 {
126 instr_time io_time;
127
128 INSTR_TIME_SET_CURRENT(io_time);
130
131 if (io_object != IOOBJECT_WAL)
132 {
133 if (io_op == IOOP_WRITE || io_op == IOOP_EXTEND)
134 {
136 if (io_object == IOOBJECT_RELATION)
138 else if (io_object == IOOBJECT_TEMP_RELATION)
140 }
141 else if (io_op == IOOP_READ)
142 {
144 if (io_object == IOOBJECT_RELATION)
146 else if (io_object == IOOBJECT_TEMP_RELATION)
148 }
149 }
150
151 INSTR_TIME_ADD(PendingIOStats.pending_times[io_object][io_context][io_op],
152 io_time);
153
154 /* Add the per-backend count */
155 pgstat_count_backend_io_op_time(io_object, io_context, io_op,
156 io_time);
157 }
158
159 pgstat_count_io_op(io_object, io_context, io_op, cnt, bytes);
160}
161
162PgStat_IO *
164{
166
167 return &pgStatLocal.snapshot.io;
168}
169
170/*
171 * Check if there any IO stats waiting for flush.
172 */
173bool
175{
176 return have_iostats;
177}
178
179/*
180 * Simpler wrapper of pgstat_io_flush_cb()
181 */
182void
183pgstat_flush_io(bool nowait)
184{
185 (void) pgstat_io_flush_cb(nowait);
186}
187
188/*
189 * Flush out locally pending IO statistics
190 *
191 * If no stats have been recorded, this function returns false.
192 *
193 * If nowait is true, this function returns true if the lock could not be
194 * acquired. Otherwise, return false.
195 */
196bool
198{
199 LWLock *bktype_lock;
200 PgStat_BktypeIO *bktype_shstats;
201
202 if (!have_iostats)
203 return false;
204
205 bktype_lock = &pgStatLocal.shmem->io.locks[MyBackendType];
206 bktype_shstats =
208
209 if (!nowait)
210 LWLockAcquire(bktype_lock, LW_EXCLUSIVE);
211 else if (!LWLockConditionalAcquire(bktype_lock, LW_EXCLUSIVE))
212 return true;
213
214 for (int io_object = 0; io_object < IOOBJECT_NUM_TYPES; io_object++)
215 {
216 for (int io_context = 0; io_context < IOCONTEXT_NUM_TYPES; io_context++)
217 {
218 for (int io_op = 0; io_op < IOOP_NUM_TYPES; io_op++)
219 {
220 instr_time time;
221
222 bktype_shstats->counts[io_object][io_context][io_op] +=
223 PendingIOStats.counts[io_object][io_context][io_op];
224
225 bktype_shstats->bytes[io_object][io_context][io_op] +=
226 PendingIOStats.bytes[io_object][io_context][io_op];
227
228 time = PendingIOStats.pending_times[io_object][io_context][io_op];
229
230 bktype_shstats->times[io_object][io_context][io_op] +=
232 }
233 }
234 }
235
237
238 LWLockRelease(bktype_lock);
239
240 memset(&PendingIOStats, 0, sizeof(PendingIOStats));
241
242 have_iostats = false;
243
244 return false;
245}
246
247const char *
249{
250 switch (io_context)
251 {
253 return "bulkread";
255 return "bulkwrite";
256 case IOCONTEXT_INIT:
257 return "init";
258 case IOCONTEXT_NORMAL:
259 return "normal";
260 case IOCONTEXT_VACUUM:
261 return "vacuum";
262 }
263
264 elog(ERROR, "unrecognized IOContext value: %d", io_context);
266}
267
268const char *
270{
271 switch (io_object)
272 {
274 return "relation";
276 return "temp relation";
277 case IOOBJECT_WAL:
278 return "wal";
279 }
280
281 elog(ERROR, "unrecognized IOObject value: %d", io_object);
283}
284
285void
287{
288 PgStatShared_IO *stat_shmem = (PgStatShared_IO *) stats;
289
290 for (int i = 0; i < BACKEND_NUM_TYPES; i++)
292}
293
294void
296{
297 for (int i = 0; i < BACKEND_NUM_TYPES; i++)
298 {
299 LWLock *bktype_lock = &pgStatLocal.shmem->io.locks[i];
300 PgStat_BktypeIO *bktype_shstats = &pgStatLocal.shmem->io.stats.stats[i];
301
302 LWLockAcquire(bktype_lock, LW_EXCLUSIVE);
303
304 /*
305 * Use the lock in the first BackendType's PgStat_BktypeIO to protect
306 * the reset timestamp as well.
307 */
308 if (i == 0)
310
311 memset(bktype_shstats, 0, sizeof(*bktype_shstats));
312 LWLockRelease(bktype_lock);
313 }
314}
315
316void
318{
319 for (int i = 0; i < BACKEND_NUM_TYPES; i++)
320 {
321 LWLock *bktype_lock = &pgStatLocal.shmem->io.locks[i];
322 PgStat_BktypeIO *bktype_shstats = &pgStatLocal.shmem->io.stats.stats[i];
323 PgStat_BktypeIO *bktype_snap = &pgStatLocal.snapshot.io.stats[i];
324
325 LWLockAcquire(bktype_lock, LW_SHARED);
326
327 /*
328 * Use the lock in the first BackendType's PgStat_BktypeIO to protect
329 * the reset timestamp as well.
330 */
331 if (i == 0)
334
335 /* using struct assignment due to better type safety */
336 *bktype_snap = *bktype_shstats;
337 LWLockRelease(bktype_lock);
338 }
339}
340
341/*
342* IO statistics are not collected for all BackendTypes.
343*
344* The following BackendTypes do not participate in the cumulative stats
345* subsystem or do not perform IO on which we currently track:
346* - Dead-end backend because it is not connected to shared memory and
347* doesn't do any IO
348* - Syslogger because it is not connected to shared memory
349* - Archiver because most relevant archiving IO is delegated to a
350* specialized command or module
351*
352* Function returns true if BackendType participates in the cumulative stats
353* subsystem for IO and false if it does not.
354*
355* When adding a new BackendType, also consider adding relevant restrictions to
356* pgstat_tracks_io_object() and pgstat_tracks_io_op().
357*/
358bool
360{
361 /*
362 * List every type so that new backend types trigger a warning about
363 * needing to adjust this switch.
364 */
365 switch (bktype)
366 {
367 case B_INVALID:
369 case B_ARCHIVER:
370 case B_LOGGER:
371 return false;
372
374 case B_AUTOVAC_WORKER:
375 case B_BACKEND:
376 case B_BG_WORKER:
377 case B_BG_WRITER:
378 case B_CHECKPOINTER:
379 case B_IO_WORKER:
382 case B_STARTUP:
383 case B_WAL_RECEIVER:
384 case B_WAL_SENDER:
385 case B_WAL_SUMMARIZER:
386 case B_WAL_WRITER:
387 return true;
388 }
389
390 return false;
391}
392
393/*
394 * Some BackendTypes do not perform IO on certain IOObjects or in certain
395 * IOContexts. Some IOObjects are never operated on in some IOContexts. Check
396 * that the given BackendType is expected to do IO in the given IOContext and
397 * on the given IOObject and that the given IOObject is expected to be operated
398 * on in the given IOContext.
399 */
400bool
402 IOContext io_context)
403{
404 bool no_temp_rel;
405
406 /*
407 * Some BackendTypes should never track IO statistics.
408 */
409 if (!pgstat_tracks_io_bktype(bktype))
410 return false;
411
412 /*
413 * Currently, IO on IOOBJECT_WAL objects can only occur in the
414 * IOCONTEXT_NORMAL and IOCONTEXT_INIT IOContexts.
415 */
416 if (io_object == IOOBJECT_WAL &&
417 (io_context != IOCONTEXT_NORMAL &&
418 io_context != IOCONTEXT_INIT))
419 return false;
420
421 /*
422 * Currently, IO on temporary relations can only occur in the
423 * IOCONTEXT_NORMAL IOContext.
424 */
425 if (io_context != IOCONTEXT_NORMAL &&
426 io_object == IOOBJECT_TEMP_RELATION)
427 return false;
428
429 /*
430 * In core Postgres, only regular backends and WAL Sender processes
431 * executing queries will use local buffers and operate on temporary
432 * relations. Parallel workers will not use local buffers (see
433 * InitLocalBuffers()); however, extensions leveraging background workers
434 * have no such limitation, so track IO on IOOBJECT_TEMP_RELATION for
435 * BackendType B_BG_WORKER.
436 */
437 no_temp_rel = bktype == B_AUTOVAC_LAUNCHER || bktype == B_BG_WRITER ||
438 bktype == B_CHECKPOINTER || bktype == B_AUTOVAC_WORKER ||
439 bktype == B_STANDALONE_BACKEND || bktype == B_STARTUP ||
440 bktype == B_WAL_SUMMARIZER || bktype == B_WAL_WRITER ||
441 bktype == B_WAL_RECEIVER;
442
443 if (no_temp_rel && io_context == IOCONTEXT_NORMAL &&
444 io_object == IOOBJECT_TEMP_RELATION)
445 return false;
446
447 /*
448 * Some BackendTypes only perform IO under IOOBJECT_WAL, hence exclude all
449 * rows for all the other objects for these.
450 */
451 if ((bktype == B_WAL_SUMMARIZER || bktype == B_WAL_RECEIVER ||
452 bktype == B_WAL_WRITER) && io_object != IOOBJECT_WAL)
453 return false;
454
455 /*
456 * Some BackendTypes do not currently perform any IO in certain
457 * IOContexts, and, while it may not be inherently incorrect for them to
458 * do so, excluding those rows from the view makes the view easier to use.
459 */
460 if ((bktype == B_CHECKPOINTER || bktype == B_BG_WRITER) &&
461 (io_context == IOCONTEXT_BULKREAD ||
462 io_context == IOCONTEXT_BULKWRITE ||
463 io_context == IOCONTEXT_VACUUM))
464 return false;
465
466 if (bktype == B_AUTOVAC_LAUNCHER && io_context == IOCONTEXT_VACUUM)
467 return false;
468
469 if ((bktype == B_AUTOVAC_WORKER || bktype == B_AUTOVAC_LAUNCHER) &&
470 io_context == IOCONTEXT_BULKWRITE)
471 return false;
472
473 return true;
474}
475
476/*
477 * Some BackendTypes will never do certain IOOps and some IOOps should not
478 * occur in certain IOContexts or on certain IOObjects. Check that the given
479 * IOOp is valid for the given BackendType in the given IOContext and on the
480 * given IOObject. Note that there are currently no cases of an IOOp being
481 * invalid for a particular BackendType only within a certain IOContext and/or
482 * only on a certain IOObject.
483 */
484bool
486 IOContext io_context, IOOp io_op)
487{
488 bool strategy_io_context;
489
490 /* if (io_context, io_object) will never collect stats, we're done */
491 if (!pgstat_tracks_io_object(bktype, io_object, io_context))
492 return false;
493
494 /*
495 * Some BackendTypes will not do certain IOOps.
496 */
497 if (bktype == B_BG_WRITER &&
498 (io_op == IOOP_READ || io_op == IOOP_EVICT || io_op == IOOP_HIT))
499 return false;
500
501 if (bktype == B_CHECKPOINTER &&
502 ((io_object != IOOBJECT_WAL && io_op == IOOP_READ) ||
503 (io_op == IOOP_EVICT || io_op == IOOP_HIT)))
504 return false;
505
506 if ((bktype == B_AUTOVAC_LAUNCHER || bktype == B_BG_WRITER ||
507 bktype == B_CHECKPOINTER) && io_op == IOOP_EXTEND)
508 return false;
509
510 /*
511 * Some BackendTypes do not perform reads with IOOBJECT_WAL.
512 */
513 if (io_object == IOOBJECT_WAL && io_op == IOOP_READ &&
514 (bktype == B_WAL_RECEIVER || bktype == B_BG_WRITER ||
515 bktype == B_AUTOVAC_LAUNCHER || bktype == B_AUTOVAC_WORKER ||
516 bktype == B_WAL_WRITER))
517 return false;
518
519 /*
520 * Temporary tables are not logged and thus do not require fsync'ing.
521 * Writeback is not requested for temporary tables.
522 */
523 if (io_object == IOOBJECT_TEMP_RELATION &&
524 (io_op == IOOP_FSYNC || io_op == IOOP_WRITEBACK))
525 return false;
526
527 /*
528 * Some IOOps are not valid in certain IOContexts and some IOOps are only
529 * valid in certain contexts.
530 */
531 if (io_context == IOCONTEXT_BULKREAD && io_op == IOOP_EXTEND)
532 return false;
533
534 strategy_io_context = io_context == IOCONTEXT_BULKREAD ||
535 io_context == IOCONTEXT_BULKWRITE || io_context == IOCONTEXT_VACUUM;
536
537 /*
538 * IOOP_REUSE is only relevant when a BufferAccessStrategy is in use.
539 */
540 if (!strategy_io_context && io_op == IOOP_REUSE)
541 return false;
542
543 /*
544 * IOOBJECT_WAL IOObject will not do certain IOOps depending on IOContext.
545 */
546 if (io_object == IOOBJECT_WAL && io_context == IOCONTEXT_INIT &&
547 !(io_op == IOOP_WRITE || io_op == IOOP_FSYNC))
548 return false;
549
550 if (io_object == IOOBJECT_WAL && io_context == IOCONTEXT_NORMAL &&
551 !(io_op == IOOP_WRITE || io_op == IOOP_READ || io_op == IOOP_FSYNC))
552 return false;
553
554 /*
555 * IOOP_FSYNC IOOps done by a backend using a BufferAccessStrategy are
556 * counted in the IOCONTEXT_NORMAL IOContext. See comment in
557 * register_dirty_segment() for more details.
558 */
559 if (strategy_io_context && io_op == IOOP_FSYNC)
560 return false;
561
562
563 return true;
564}
uint64_t uint64
Definition: c.h:503
#define pg_unreachable()
Definition: c.h:332
uint32_t uint32
Definition: c.h:502
int64 TimestampTz
Definition: timestamp.h:39
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:226
Assert(PointerIsAligned(start, uint64))
#define INSTR_TIME_SET_CURRENT(t)
Definition: instr_time.h:122
#define INSTR_TIME_ADD(x, y)
Definition: instr_time.h:178
#define INSTR_TIME_IS_ZERO(t)
Definition: instr_time.h:169
#define INSTR_TIME_SUBTRACT(x, y)
Definition: instr_time.h:181
#define INSTR_TIME_GET_MICROSEC(t)
Definition: instr_time.h:194
#define INSTR_TIME_SET_ZERO(t)
Definition: instr_time.h:172
BufferUsage pgBufferUsage
Definition: instrument.c:20
int i
Definition: isn.c:77
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1182
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1902
void LWLockInitialize(LWLock *lock, int tranche_id)
Definition: lwlock.c:721
bool LWLockConditionalAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1353
@ LWTRANCHE_PGSTATS_DATA
Definition: lwlock.h:210
@ LW_SHARED
Definition: lwlock.h:115
@ LW_EXCLUSIVE
Definition: lwlock.h:114
#define BACKEND_NUM_TYPES
Definition: miscadmin.h:377
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
static time_t start_time
Definition: pg_ctl.c:95
void pgstat_snapshot_fixed(PgStat_Kind kind)
Definition: pgstat.c:1078
PgStat_LocalState pgStatLocal
Definition: pgstat.c:212
#define pgstat_count_buffer_read_time(n)
Definition: pgstat.h:620
IOObject
Definition: pgstat.h:273
@ IOOBJECT_RELATION
Definition: pgstat.h:274
@ IOOBJECT_WAL
Definition: pgstat.h:276
@ IOOBJECT_TEMP_RELATION
Definition: pgstat.h:275
#define pgstat_is_ioop_tracked_in_bytes(io_op)
Definition: pgstat.h:318
#define pgstat_count_buffer_write_time(n)
Definition: pgstat.h:622
#define IOOP_NUM_TYPES
Definition: pgstat.h:316
IOContext
Definition: pgstat.h:282
@ IOCONTEXT_INIT
Definition: pgstat.h:285
@ IOCONTEXT_NORMAL
Definition: pgstat.h:286
@ IOCONTEXT_VACUUM
Definition: pgstat.h:287
@ IOCONTEXT_BULKREAD
Definition: pgstat.h:283
@ IOCONTEXT_BULKWRITE
Definition: pgstat.h:284
#define IOCONTEXT_NUM_TYPES
Definition: pgstat.h:290
IOOp
Definition: pgstat.h:302
@ IOOP_EXTEND
Definition: pgstat.h:311
@ IOOP_FSYNC
Definition: pgstat.h:305
@ IOOP_READ
Definition: pgstat.h:312
@ IOOP_WRITEBACK
Definition: pgstat.h:308
@ IOOP_HIT
Definition: pgstat.h:306
@ IOOP_EVICT
Definition: pgstat.h:304
@ IOOP_REUSE
Definition: pgstat.h:307
@ IOOP_WRITE
Definition: pgstat.h:313
#define IOOBJECT_NUM_TYPES
Definition: pgstat.h:279
void pgstat_count_backend_io_op(IOObject io_object, IOContext io_context, IOOp io_op, uint32 cnt, uint64 bytes)
void pgstat_count_backend_io_op_time(IOObject io_object, IOContext io_context, IOOp io_op, instr_time io_time)
instr_time pgstat_prepare_io_time(bool track_io_guc)
Definition: pgstat_io.c:90
void pgstat_count_io_op(IOObject io_object, IOContext io_context, IOOp io_op, uint32 cnt, uint64 bytes)
Definition: pgstat_io.c:68
void pgstat_flush_io(bool nowait)
Definition: pgstat_io.c:183
void pgstat_count_io_op_time(IOObject io_object, IOContext io_context, IOOp io_op, instr_time start_time, uint32 cnt, uint64 bytes)
Definition: pgstat_io.c:121
PgStat_IO * pgstat_fetch_stat_io(void)
Definition: pgstat_io.c:163
const char * pgstat_get_io_context_name(IOContext io_context)
Definition: pgstat_io.c:248
bool pgstat_tracks_io_bktype(BackendType bktype)
Definition: pgstat_io.c:359
const char * pgstat_get_io_object_name(IOObject io_object)
Definition: pgstat_io.c:269
bool pgstat_io_have_pending_cb(void)
Definition: pgstat_io.c:174
bool pgstat_io_flush_cb(bool nowait)
Definition: pgstat_io.c:197
void pgstat_io_reset_all_cb(TimestampTz ts)
Definition: pgstat_io.c:295
bool pgstat_bktype_io_stats_valid(PgStat_BktypeIO *backend_io, BackendType bktype)
Definition: pgstat_io.c:37
static PgStat_PendingIO PendingIOStats
Definition: pgstat_io.c:23
bool pgstat_tracks_io_op(BackendType bktype, IOObject io_object, IOContext io_context, IOOp io_op)
Definition: pgstat_io.c:485
static bool have_iostats
Definition: pgstat_io.c:24
void pgstat_io_snapshot_cb(void)
Definition: pgstat_io.c:317
void pgstat_io_init_shmem_cb(void *stats)
Definition: pgstat_io.c:286
bool pgstat_tracks_io_object(BackendType bktype, IOObject io_object, IOContext io_context)
Definition: pgstat_io.c:401
#define PGSTAT_KIND_IO
Definition: pgstat_kind.h:38
instr_time local_blk_read_time
Definition: instrument.h:38
instr_time shared_blk_read_time
Definition: instrument.h:36
instr_time shared_blk_write_time
Definition: instrument.h:37
instr_time local_blk_write_time
Definition: instrument.h:39
Definition: lwlock.h:42
LWLock locks[BACKEND_NUM_TYPES]
PgStat_Counter times[IOOBJECT_NUM_TYPES][IOCONTEXT_NUM_TYPES][IOOP_NUM_TYPES]
Definition: pgstat.h:326
uint64 bytes[IOOBJECT_NUM_TYPES][IOCONTEXT_NUM_TYPES][IOOP_NUM_TYPES]
Definition: pgstat.h:324
PgStat_Counter counts[IOOBJECT_NUM_TYPES][IOCONTEXT_NUM_TYPES][IOOP_NUM_TYPES]
Definition: pgstat.h:325
PgStat_BktypeIO stats[BACKEND_NUM_TYPES]
Definition: pgstat.h:339
TimestampTz stat_reset_timestamp
Definition: pgstat.h:338
PgStat_Snapshot snapshot
PgStat_ShmemControl * shmem
PgStat_Counter counts[IOOBJECT_NUM_TYPES][IOCONTEXT_NUM_TYPES][IOOP_NUM_TYPES]
Definition: pgstat.h:332
uint64 bytes[IOOBJECT_NUM_TYPES][IOCONTEXT_NUM_TYPES][IOOP_NUM_TYPES]
Definition: pgstat.h:331
instr_time pending_times[IOOBJECT_NUM_TYPES][IOCONTEXT_NUM_TYPES][IOOP_NUM_TYPES]
Definition: pgstat.h:333
PgStatShared_IO io