Age Owner Branch data TLA Line data Source code
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-2026, 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"
21 : : #include "utils/pgstat_internal.h"
22 : :
23 : : static PgStat_PendingIO PendingIOStats;
24 : : static 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.
29 : : * Non-zero time with a zero operation count is allowed as there are cases
30 : : * where this may be appropriate -- like when a backend is waiting on IO
31 : : * initiated by another backend.
32 : : *
33 : : * The passed-in PgStat_BktypeIO must contain stats from the BackendType
34 : : * specified by the second parameter. Caller is responsible for locking the
35 : : * passed-in PgStat_BktypeIO, if needed.
36 : : */
37 : : bool
1296 andres@anarazel.de 38 :CBC 91925 : pgstat_bktype_io_stats_valid(PgStat_BktypeIO *backend_io,
39 : : BackendType bktype)
40 : : {
1277 tgl@sss.pgh.pa.us 41 [ + + ]: 367700 : for (int io_object = 0; io_object < IOOBJECT_NUM_TYPES; io_object++)
42 : : {
43 [ + + ]: 1654650 : for (int io_context = 0; io_context < IOCONTEXT_NUM_TYPES; io_context++)
44 : : {
45 [ + + ]: 12409875 : for (int io_op = 0; io_op < IOOP_NUM_TYPES; io_op++)
46 : : {
47 : : /* we don't track it, and it is not 0 */
27 melanieplageman@gmai 48 [ + + ]: 11031000 : if (!pgstat_tracks_io_op(bktype, io_object, io_context, io_op) &&
49 [ + - ]: 7829266 : (backend_io->counts[io_object][io_context][io_op] != 0 ||
50 [ - + ]: 7829266 : backend_io->times[io_object][io_context][io_op] != 0))
1296 andres@anarazel.de 51 :UBC 0 : return false;
52 : : }
53 : : }
54 : : }
55 : :
1296 andres@anarazel.de 56 :CBC 91925 : return true;
57 : : }
58 : :
59 : : void
590 michael@paquier.xyz 60 : 89508593 : pgstat_count_io_op(IOObject io_object, IOContext io_context, IOOp io_op,
61 : : uint32 cnt, uint64 bytes)
62 : : {
1276 tgl@sss.pgh.pa.us 63 [ - + ]: 89508593 : Assert((unsigned int) io_object < IOOBJECT_NUM_TYPES);
64 [ - + ]: 89508593 : Assert((unsigned int) io_context < IOCONTEXT_NUM_TYPES);
590 michael@paquier.xyz 65 [ + - + + : 89508593 : Assert(pgstat_is_ioop_tracked_in_bytes(io_op) || bytes == 0);
- + ]
1296 andres@anarazel.de 66 [ - + ]: 89508593 : Assert(pgstat_tracks_io_op(MyBackendType, io_object, io_context, io_op));
67 : :
1238 68 : 89508593 : PendingIOStats.counts[io_object][io_context][io_op] += cnt;
590 michael@paquier.xyz 69 : 89508593 : PendingIOStats.bytes[io_object][io_context][io_op] += bytes;
70 : :
71 : : /* Add the per-backend counts */
583 72 : 89508593 : pgstat_count_backend_io_op(io_object, io_context, io_op, cnt, bytes);
73 : :
1296 andres@anarazel.de 74 : 89508593 : have_iostats = true;
395 michael@paquier.xyz 75 : 89508593 : pgstat_report_fixed = true;
1296 andres@anarazel.de 76 : 89508593 : }
77 : :
78 : : /*
79 : : * Initialize the internal timing for an IO operation, depending on an
80 : : * IO timing GUC.
81 : : */
82 : : instr_time
547 michael@paquier.xyz 83 : 6746126 : pgstat_prepare_io_time(bool track_io_guc)
84 : : {
85 : : instr_time io_start;
86 : :
87 [ + + ]: 6746126 : if (track_io_guc)
1238 andres@anarazel.de 88 : 2 : INSTR_TIME_SET_CURRENT(io_start);
89 : : else
90 : : {
91 : : /*
92 : : * There is no need to set io_start when an IO timing GUC is disabled.
93 : : * Initialize it to zero to avoid compiler warnings and to let
94 : : * pgstat_count_io_op_time() know that timings should be ignored.
95 : : */
96 : 6746124 : INSTR_TIME_SET_ZERO(io_start);
97 : : }
98 : :
99 : 6746126 : return io_start;
100 : : }
101 : :
102 : : /*
103 : : * Like pgstat_count_io_op() except it also accumulates time.
104 : : *
105 : : * The calls related to pgstat_count_buffer_*() are for pgstat_database. As
106 : : * pg_stat_database only counts block read and write times, these are done for
107 : : * IOOP_READ, IOOP_WRITE and IOOP_EXTEND.
108 : : *
109 : : * pgBufferUsage is used for EXPLAIN. pgBufferUsage has write and read stats
110 : : * for shared, local and temporary blocks. pg_stat_io does not track the
111 : : * activity of temporary blocks, so these are ignored here.
112 : : */
113 : : void
1232 pg@bowt.ie 114 : 6746107 : pgstat_count_io_op_time(IOObject io_object, IOContext io_context, IOOp io_op,
115 : : instr_time start_time, uint32 cnt, uint64 bytes)
116 : : {
547 michael@paquier.xyz 117 [ + + ]: 6746107 : if (!INSTR_TIME_IS_ZERO(start_time))
118 : : {
119 : : instr_time io_time;
120 : :
1238 andres@anarazel.de 121 : 2 : INSTR_TIME_SET_CURRENT(io_time);
122 : 2 : INSTR_TIME_SUBTRACT(io_time, start_time);
123 : :
569 michael@paquier.xyz 124 [ + - ]: 2 : if (io_object != IOOBJECT_WAL)
125 : : {
126 [ + - - + ]: 2 : if (io_op == IOOP_WRITE || io_op == IOOP_EXTEND)
127 : : {
569 michael@paquier.xyz 128 :UBC 0 : pgstat_count_buffer_write_time(INSTR_TIME_GET_MICROSEC(io_time));
129 [ # # ]: 0 : if (io_object == IOOBJECT_RELATION)
130 : 0 : INSTR_TIME_ADD(pgBufferUsage.shared_blk_write_time, io_time);
131 [ # # ]: 0 : else if (io_object == IOOBJECT_TEMP_RELATION)
132 : 0 : INSTR_TIME_ADD(pgBufferUsage.local_blk_write_time, io_time);
133 : : }
569 michael@paquier.xyz 134 [ + - ]:CBC 2 : else if (io_op == IOOP_READ)
135 : : {
136 : 2 : pgstat_count_buffer_read_time(INSTR_TIME_GET_MICROSEC(io_time));
137 [ + - ]: 2 : if (io_object == IOOBJECT_RELATION)
138 : 2 : INSTR_TIME_ADD(pgBufferUsage.shared_blk_read_time, io_time);
569 michael@paquier.xyz 139 [ # # ]:UBC 0 : else if (io_object == IOOBJECT_TEMP_RELATION)
140 : 0 : INSTR_TIME_ADD(pgBufferUsage.local_blk_read_time, io_time);
141 : : }
142 : : }
143 : :
1232 pg@bowt.ie 144 :CBC 2 : INSTR_TIME_ADD(PendingIOStats.pending_times[io_object][io_context][io_op],
145 : : io_time);
146 : :
147 : : /* Add the per-backend count */
583 michael@paquier.xyz 148 : 2 : pgstat_count_backend_io_op_time(io_object, io_context, io_op,
149 : : io_time);
150 : : }
151 : :
590 152 : 6746107 : pgstat_count_io_op(io_object, io_context, io_op, cnt, bytes);
1238 andres@anarazel.de 153 : 6746107 : }
154 : :
155 : : PgStat_IO *
1296 156 : 94 : pgstat_fetch_stat_io(void)
157 : : {
158 : 94 : pgstat_snapshot_fixed(PGSTAT_KIND_IO);
159 : :
160 : 94 : return &pgStatLocal.snapshot.io;
161 : : }
162 : :
163 : : /*
164 : : * Simpler wrapper of pgstat_io_flush_cb()
165 : : */
166 : : void
717 michael@paquier.xyz 167 : 102919 : pgstat_flush_io(bool nowait)
168 : : {
169 : 102919 : (void) pgstat_io_flush_cb(nowait);
170 : 102919 : }
171 : :
172 : : /*
173 : : * Flush out locally pending IO statistics
174 : : *
175 : : * If no stats have been recorded, this function returns false.
176 : : *
177 : : * If nowait is true, this function returns true if the lock could not be
178 : : * acquired. Otherwise, return false.
179 : : */
180 : : bool
181 : 145271 : pgstat_io_flush_cb(bool nowait)
182 : : {
183 : : LWLock *bktype_lock;
184 : : PgStat_BktypeIO *bktype_shstats;
185 : :
1296 andres@anarazel.de 186 [ + + ]: 145271 : if (!have_iostats)
187 : 55236 : return false;
188 : :
189 : 90035 : bktype_lock = &pgStatLocal.shmem->io.locks[MyBackendType];
190 : 90035 : bktype_shstats =
191 : 90035 : &pgStatLocal.shmem->io.stats.stats[MyBackendType];
192 : :
193 [ + + ]: 90035 : if (!nowait)
194 : 62472 : LWLockAcquire(bktype_lock, LW_EXCLUSIVE);
195 [ + + ]: 27563 : else if (!LWLockConditionalAcquire(bktype_lock, LW_EXCLUSIVE))
196 : 18 : return true;
197 : :
1277 tgl@sss.pgh.pa.us 198 [ + + ]: 360068 : for (int io_object = 0; io_object < IOOBJECT_NUM_TYPES; io_object++)
199 : : {
200 [ + + ]: 1620306 : for (int io_context = 0; io_context < IOCONTEXT_NUM_TYPES; io_context++)
201 : : {
202 [ + + ]: 12152295 : for (int io_op = 0; io_op < IOOP_NUM_TYPES; io_op++)
203 : : {
204 : : instr_time time;
205 : :
1238 andres@anarazel.de 206 : 10802040 : bktype_shstats->counts[io_object][io_context][io_op] +=
207 : 10802040 : PendingIOStats.counts[io_object][io_context][io_op];
208 : :
590 michael@paquier.xyz 209 : 10802040 : bktype_shstats->bytes[io_object][io_context][io_op] +=
210 : 10802040 : PendingIOStats.bytes[io_object][io_context][io_op];
211 : :
1238 andres@anarazel.de 212 : 10802040 : time = PendingIOStats.pending_times[io_object][io_context][io_op];
213 : :
214 : 10802040 : bktype_shstats->times[io_object][io_context][io_op] +=
215 : 10802040 : INSTR_TIME_GET_MICROSEC(time);
216 : : }
217 : : }
218 : : }
219 : :
1296 220 [ - + ]: 90017 : Assert(pgstat_bktype_io_stats_valid(bktype_shstats, MyBackendType));
221 : :
222 : 90017 : LWLockRelease(bktype_lock);
223 : :
224 : 90017 : memset(&PendingIOStats, 0, sizeof(PendingIOStats));
225 : :
226 : 90017 : have_iostats = false;
227 : :
228 : 90017 : return false;
229 : : }
230 : :
231 : : const char *
232 : 22980 : pgstat_get_io_context_name(IOContext io_context)
233 : : {
234 [ + + + + : 22980 : switch (io_context)
+ - ]
235 : : {
236 : 4596 : case IOCONTEXT_BULKREAD:
237 : 4596 : return "bulkread";
238 : 4596 : case IOCONTEXT_BULKWRITE:
239 : 4596 : return "bulkwrite";
569 michael@paquier.xyz 240 : 4596 : case IOCONTEXT_INIT:
241 : 4596 : return "init";
1296 andres@anarazel.de 242 : 4596 : case IOCONTEXT_NORMAL:
243 : 4596 : return "normal";
244 : 4596 : case IOCONTEXT_VACUUM:
245 : 4596 : return "vacuum";
246 : : }
247 : :
1296 andres@anarazel.de 248 [ # # ]:UBC 0 : elog(ERROR, "unrecognized IOContext value: %d", io_context);
249 : : pg_unreachable();
250 : : }
251 : :
252 : : const char *
1296 andres@anarazel.de 253 :CBC 4596 : pgstat_get_io_object_name(IOObject io_object)
254 : : {
255 [ + + + - ]: 4596 : switch (io_object)
256 : : {
257 : 1532 : case IOOBJECT_RELATION:
258 : 1532 : return "relation";
259 : 1532 : case IOOBJECT_TEMP_RELATION:
260 : 1532 : return "temp relation";
569 michael@paquier.xyz 261 : 1532 : case IOOBJECT_WAL:
262 : 1532 : return "wal";
263 : : }
264 : :
1296 andres@anarazel.de 265 [ # # ]:UBC 0 : elog(ERROR, "unrecognized IOObject value: %d", io_object);
266 : : pg_unreachable();
267 : : }
268 : :
269 : : void
777 michael@paquier.xyz 270 :CBC 1236 : pgstat_io_init_shmem_cb(void *stats)
271 : : {
272 : 1236 : PgStatShared_IO *stat_shmem = (PgStatShared_IO *) stats;
273 : :
274 [ + + ]: 25956 : for (int i = 0; i < BACKEND_NUM_TYPES; i++)
275 : 24720 : LWLockInitialize(&stat_shmem->locks[i], LWTRANCHE_PGSTATS_DATA);
276 : 1236 : }
277 : :
278 : : void
1296 andres@anarazel.de 279 : 263 : pgstat_io_reset_all_cb(TimestampTz ts)
280 : : {
281 [ + + ]: 5523 : for (int i = 0; i < BACKEND_NUM_TYPES; i++)
282 : : {
283 : 5260 : LWLock *bktype_lock = &pgStatLocal.shmem->io.locks[i];
284 : 5260 : PgStat_BktypeIO *bktype_shstats = &pgStatLocal.shmem->io.stats.stats[i];
285 : :
286 : 5260 : LWLockAcquire(bktype_lock, LW_EXCLUSIVE);
287 : :
288 : : /*
289 : : * Use the lock in the first BackendType's PgStat_BktypeIO to protect
290 : : * the reset timestamp as well.
291 : : */
292 [ + + ]: 5260 : if (i == 0)
293 : 263 : pgStatLocal.shmem->io.stats.stat_reset_timestamp = ts;
294 : :
295 : 5260 : memset(bktype_shstats, 0, sizeof(*bktype_shstats));
296 : 5260 : LWLockRelease(bktype_lock);
297 : : }
298 : 263 : }
299 : :
300 : : void
301 : 874 : pgstat_io_snapshot_cb(void)
302 : : {
303 [ + + ]: 18354 : for (int i = 0; i < BACKEND_NUM_TYPES; i++)
304 : : {
305 : 17480 : LWLock *bktype_lock = &pgStatLocal.shmem->io.locks[i];
306 : 17480 : PgStat_BktypeIO *bktype_shstats = &pgStatLocal.shmem->io.stats.stats[i];
307 : 17480 : PgStat_BktypeIO *bktype_snap = &pgStatLocal.snapshot.io.stats[i];
308 : :
309 : 17480 : LWLockAcquire(bktype_lock, LW_SHARED);
310 : :
311 : : /*
312 : : * Use the lock in the first BackendType's PgStat_BktypeIO to protect
313 : : * the reset timestamp as well.
314 : : */
315 [ + + ]: 17480 : if (i == 0)
316 : 874 : pgStatLocal.snapshot.io.stat_reset_timestamp =
317 : 874 : pgStatLocal.shmem->io.stats.stat_reset_timestamp;
318 : :
319 : : /* using struct assignment due to better type safety */
320 : 17480 : *bktype_snap = *bktype_shstats;
321 : 17480 : LWLockRelease(bktype_lock);
322 : : }
323 : 874 : }
324 : :
325 : : /*
326 : : * IO statistics are not collected for all BackendTypes.
327 : : *
328 : : * The following BackendTypes do not participate in the cumulative stats
329 : : * subsystem or do not perform IO on which we currently track:
330 : : * - Dead-end backend because it is not connected to shared memory and
331 : : * doesn't do any IO
332 : : * - Syslogger because it is not connected to shared memory
333 : : * - Archiver because most relevant archiving IO is delegated to a
334 : : * specialized command or module
335 : : *
336 : : * Function returns true if BackendType participates in the cumulative stats
337 : : * subsystem for IO and false if it does not.
338 : : *
339 : : * When adding a new BackendType, also consider adding relevant restrictions to
340 : : * pgstat_tracks_io_object() and pgstat_tracks_io_op().
341 : : */
342 : : bool
343 : 182204822 : pgstat_tracks_io_bktype(BackendType bktype)
344 : : {
345 : : /*
346 : : * List every type so that new backend types trigger a warning about
347 : : * needing to adjust this switch.
348 : : */
349 [ + + - ]: 182204822 : switch (bktype)
350 : : {
351 : 45496 : case B_INVALID:
352 : : case B_DEAD_END_BACKEND:
353 : : case B_ARCHIVER:
354 : : case B_LOGGER:
355 : 45496 : return false;
356 : :
146 dgustafsson@postgres 357 : 182159326 : case B_DATACHECKSUMSWORKER_LAUNCHER:
358 : : case B_DATACHECKSUMSWORKER_WORKER:
359 : : case B_AUTOVAC_LAUNCHER:
360 : : case B_AUTOVAC_WORKER:
361 : : case B_BACKEND:
362 : : case B_BG_WORKER:
363 : : case B_BG_WRITER:
364 : : case B_CHECKPOINTER:
365 : : case B_IO_WORKER:
366 : : case B_SLOTSYNC_WORKER:
367 : : case B_STANDALONE_BACKEND:
368 : : case B_STARTUP:
369 : : case B_WAL_RECEIVER:
370 : : case B_WAL_SENDER:
371 : : case B_WAL_SUMMARIZER:
372 : : case B_WAL_WRITER:
1296 andres@anarazel.de 373 : 182159326 : return true;
374 : : }
375 : :
1296 andres@anarazel.de 376 :UBC 0 : return false;
377 : : }
378 : :
379 : : /*
380 : : * Some BackendTypes do not perform IO on certain IOObjects or in certain
381 : : * IOContexts. Some IOObjects are never operated on in some IOContexts. Check
382 : : * that the given BackendType is expected to do IO in the given IOContext and
383 : : * on the given IOObject and that the given IOObject is expected to be operated
384 : : * on in the given IOContext.
385 : : */
386 : : bool
1296 andres@anarazel.de 387 :CBC 182202942 : pgstat_tracks_io_object(BackendType bktype, IOObject io_object,
388 : : IOContext io_context)
389 : : {
390 : : bool no_temp_rel;
391 : :
392 : : /*
393 : : * Some BackendTypes should never track IO statistics.
394 : : */
395 [ + + ]: 182202942 : if (!pgstat_tracks_io_bktype(bktype))
396 : 45120 : return false;
397 : :
398 : : /*
399 : : * Currently, IO on IOOBJECT_WAL objects can only occur in the
400 : : * IOCONTEXT_NORMAL and IOCONTEXT_INIT IOContexts.
401 : : */
569 michael@paquier.xyz 402 [ + + + + ]: 182157822 : if (io_object == IOOBJECT_WAL &&
403 [ + + ]: 2953262 : (io_context != IOCONTEXT_NORMAL &&
404 : : io_context != IOCONTEXT_INIT))
405 : 2201772 : return false;
406 : :
407 : : /*
408 : : * Currently, IO on temporary relations can only occur in the
409 : : * IOCONTEXT_NORMAL IOContext.
410 : : */
1296 andres@anarazel.de 411 [ + + + + ]: 179956050 : if (io_context != IOCONTEXT_NORMAL &&
412 : : io_object == IOOBJECT_TEMP_RELATION)
413 : 2935696 : return false;
414 : :
415 : : /*
416 : : * In core Postgres, only regular backends and WAL Sender processes
417 : : * executing queries will use local buffers and operate on temporary
418 : : * relations. Parallel workers will not use local buffers (see
419 : : * InitLocalBuffers()); however, extensions leveraging background workers
420 : : * have no such limitation, so track IO on IOOBJECT_TEMP_RELATION for
421 : : * BackendType B_BG_WORKER.
422 : : */
423 [ + + + + ]: 176979480 : no_temp_rel = bktype == B_AUTOVAC_LAUNCHER || bktype == B_BG_WRITER ||
424 [ + + + + ]: 175829350 : bktype == B_CHECKPOINTER || bktype == B_AUTOVAC_WORKER ||
540 michael@paquier.xyz 425 [ + + + + ]: 162937218 : bktype == B_STANDALONE_BACKEND || bktype == B_STARTUP ||
426 [ + + + + : 353999834 : bktype == B_WAL_SUMMARIZER || bktype == B_WAL_WRITER ||
+ + ]
427 : : bktype == B_WAL_RECEIVER;
428 : :
1296 andres@anarazel.de 429 [ + + + + : 177020354 : if (no_temp_rel && io_context == IOCONTEXT_NORMAL &&
+ + ]
430 : : io_object == IOOBJECT_TEMP_RELATION)
431 : 275830 : return false;
432 : :
433 : : /*
434 : : * Some BackendTypes only perform IO under IOOBJECT_WAL, hence exclude all
435 : : * rows for all the other objects for these.
436 : : */
540 michael@paquier.xyz 437 [ + + + + : 176744524 : if ((bktype == B_WAL_SUMMARIZER || bktype == B_WAL_RECEIVER ||
+ + ]
438 [ + + ]: 690948 : bktype == B_WAL_WRITER) && io_object != IOOBJECT_WAL)
439 : 315330 : return false;
440 : :
441 : : /*
442 : : * Some BackendTypes do not currently perform any IO in certain
443 : : * IOContexts, and, while it may not be inherently incorrect for them to
444 : : * do so, excluding those rows from the view makes the view easier to use.
445 : : */
1296 andres@anarazel.de 446 [ + + + + : 176429194 : if ((bktype == B_CHECKPOINTER || bktype == B_BG_WRITER) &&
+ + ]
447 [ + + ]: 950058 : (io_context == IOCONTEXT_BULKREAD ||
448 [ + + ]: 850022 : io_context == IOCONTEXT_BULKWRITE ||
449 : : io_context == IOCONTEXT_VACUUM))
450 : 300108 : return false;
451 : :
452 [ + + + + ]: 176129086 : if (bktype == B_AUTOVAC_LAUNCHER && io_context == IOCONTEXT_VACUUM)
453 : 4502 : return false;
454 : :
455 [ + + + + : 176124584 : if ((bktype == B_AUTOVAC_WORKER || bktype == B_AUTOVAC_LAUNCHER) &&
+ + ]
456 : : io_context == IOCONTEXT_BULKWRITE)
457 : 16444 : return false;
458 : :
459 : : /*
460 : : * The data checksums launcher scans catalogs and emits WAL records for
461 : : * checksum state changes. Catalog scans can use a bulkread strategy.
462 : : */
41 fujii@postgresql.org 463 [ + + ]: 176108140 : if (bktype == B_DATACHECKSUMSWORKER_LAUNCHER)
464 : : {
465 [ + + + + ]: 11324 : if (io_object == IOOBJECT_WAL ||
466 [ + + ]: 6680 : (io_object == IOOBJECT_RELATION &&
467 [ + + ]: 4898 : (io_context == IOCONTEXT_BULKREAD ||
468 : : io_context == IOCONTEXT_NORMAL)))
469 : 7204 : return true;
470 : :
471 : 4120 : return false;
472 : : }
473 : :
474 : : /*
475 : : * The worker also scans catalogs, then processes relations using a vacuum
476 : : * access strategy. Catalog scans can use a bulkread strategy.
477 : : */
478 [ + + ]: 176096816 : if (bktype == B_DATACHECKSUMSWORKER_WORKER)
479 : : {
480 [ + + + + ]: 262836 : if (io_object == IOOBJECT_WAL ||
481 [ + + ]: 237084 : (io_object == IOOBJECT_RELATION &&
482 [ + + ]: 233528 : (io_context == IOCONTEXT_BULKREAD ||
483 [ + + ]: 130655 : io_context == IOCONTEXT_NORMAL ||
484 : : io_context == IOCONTEXT_VACUUM)))
485 : 259338 : return true;
486 : :
487 : 3498 : return false;
488 : : }
489 : :
1296 andres@anarazel.de 490 : 175833980 : return true;
491 : : }
492 : :
493 : : /*
494 : : * Some BackendTypes will never do certain IOOps and some IOOps should not
495 : : * occur in certain IOContexts or on certain IOObjects. Check that the given
496 : : * IOOp is valid for the given BackendType in the given IOContext and on the
497 : : * given IOObject. Note that there are currently no cases of an IOOp being
498 : : * invalid for a particular BackendType only within a certain IOContext and/or
499 : : * only on a certain IOObject.
500 : : */
501 : : bool
502 : 182179962 : pgstat_tracks_io_op(BackendType bktype, IOObject io_object,
503 : : IOContext io_context, IOOp io_op)
504 : : {
505 : : bool strategy_io_context;
506 : :
507 : : /* if (io_context, io_object) will never collect stats, we're done */
508 [ + + ]: 182179962 : if (!pgstat_tracks_io_object(bktype, io_object, io_context))
509 : 6087936 : return false;
510 : :
511 : : /*
512 : : * Some BackendTypes will not do certain IOOps.
513 : : */
569 michael@paquier.xyz 514 [ + + + + ]: 176092026 : if (bktype == B_BG_WRITER &&
1246 andres@anarazel.de 515 [ + + + + ]: 185526 : (io_op == IOOP_READ || io_op == IOOP_EVICT || io_op == IOOP_HIT))
1296 516 : 56028 : return false;
517 : :
569 michael@paquier.xyz 518 [ + + + + ]: 176035998 : if (bktype == B_CHECKPOINTER &&
519 [ + + + + ]: 545032 : ((io_object != IOOBJECT_WAL && io_op == IOOP_READ) ||
520 [ + + ]: 497032 : (io_op == IOOP_EVICT || io_op == IOOP_HIT)))
521 : 80000 : return false;
522 : :
64 melanieplageman@gmai 523 [ + + + + : 175955998 : if ((bktype == B_BG_WRITER || bktype == B_CHECKPOINTER) &&
+ + ]
524 : : io_op == IOOP_EXTEND)
1296 andres@anarazel.de 525 : 50676 : return false;
526 : :
527 : : /*
528 : : * Some BackendTypes do not perform reads with IOOBJECT_WAL.
529 : : */
569 michael@paquier.xyz 530 [ + + + + : 175905322 : if (io_object == IOOBJECT_WAL && io_op == IOOP_READ &&
+ + ]
531 [ + - + + ]: 1966007 : (bktype == B_WAL_RECEIVER || bktype == B_BG_WRITER ||
526 532 [ + + + + ]: 1964717 : bktype == B_AUTOVAC_LAUNCHER || bktype == B_AUTOVAC_WORKER ||
41 fujii@postgresql.org 533 [ + + ]: 1961145 : bktype == B_DATACHECKSUMSWORKER_LAUNCHER ||
534 [ + + ]: 1960689 : bktype == B_DATACHECKSUMSWORKER_WORKER ||
535 : : bktype == B_WAL_WRITER))
569 michael@paquier.xyz 536 : 21154 : return false;
537 : :
538 : : /*
539 : : * Temporary tables are not logged and thus do not require fsync'ing.
540 : : * Writeback is not requested for temporary tables.
541 : : */
1198 andres@anarazel.de 542 [ + + + + ]: 175884168 : if (io_object == IOOBJECT_TEMP_RELATION &&
543 [ + + ]: 4023895 : (io_op == IOOP_FSYNC || io_op == IOOP_WRITEBACK))
544 : 114846 : return false;
545 : :
546 : : /*
547 : : * Some IOOps are not valid in certain IOContexts and some IOOps are only
548 : : * valid in certain contexts.
549 : : */
1296 550 [ + + + + ]: 175769322 : if (io_context == IOCONTEXT_BULKREAD && io_op == IOOP_EXTEND)
551 : 72282 : return false;
552 : :
553 [ + + ]: 172693370 : strategy_io_context = io_context == IOCONTEXT_BULKREAD ||
554 [ + + + + ]: 348390410 : io_context == IOCONTEXT_BULKWRITE || io_context == IOCONTEXT_VACUUM;
555 : :
556 : : /*
557 : : * IOOP_REUSE is only relevant when a BufferAccessStrategy is in use.
558 : : */
559 [ + + + + ]: 175697040 : if (!strategy_io_context && io_op == IOOP_REUSE)
560 : 413048 : return false;
561 : :
562 : : /*
563 : : * IOOBJECT_WAL IOObject will not do certain IOOps depending on IOContext.
564 : : */
569 michael@paquier.xyz 565 [ + + + + : 175283992 : if (io_object == IOOBJECT_WAL && io_context == IOCONTEXT_INIT &&
+ + ]
566 [ + + ]: 507888 : !(io_op == IOOP_WRITE || io_op == IOOP_FSYNC))
567 : 412152 : return false;
568 : :
569 [ + + + + : 174871840 : if (io_object == IOOBJECT_WAL && io_context == IOCONTEXT_NORMAL &&
+ + ]
570 [ + + + + ]: 2295096 : !(io_op == IOOP_WRITE || io_op == IOOP_READ || io_op == IOOP_FSYNC))
571 : 334317 : return false;
572 : :
573 : : /*
574 : : * IOOP_FSYNC IOOps done by a backend using a BufferAccessStrategy are
575 : : * counted in the IOCONTEXT_NORMAL IOContext. See comment in
576 : : * register_dirty_segment() for more details.
577 : : */
1296 andres@anarazel.de 578 [ + + + + ]: 174537523 : if (strategy_io_context && io_op == IOOP_FSYNC)
579 : 213331 : return false;
580 : :
581 : :
582 : 174324192 : return true;
583 : : }
|