diff --git a/src/backend/utils/activity/pgstat_io.c b/src/backend/utils/activity/pgstat_io.c index 148a2a9c7d5..da1f3103ee7 100644 --- a/src/backend/utils/activity/pgstat_io.c +++ b/src/backend/utils/activity/pgstat_io.c @@ -222,13 +222,14 @@ pgstat_io_flush_cb(bool nowait) { LWLock *bktype_lock; PgStat_BktypeIO *bktype_shstats; + BackendType condensedBkType = pgstat_remap_condensed_bktype(MyBackendType); if (!have_iostats) return false; bktype_lock = &pgStatLocal.shmem->io.locks[MyBackendType]; bktype_shstats = - &pgStatLocal.shmem->io.stats.stats[MyBackendType]; + &pgStatLocal.shmem->io.stats.stats[condensedBkType]; if (!nowait) LWLockAcquire(bktype_lock, LW_EXCLUSIVE); @@ -352,7 +353,10 @@ pgstat_io_reset_all_cb(TimestampTz ts) for (int i = 0; i < BACKEND_NUM_TYPES; i++) { LWLock *bktype_lock = &pgStatLocal.shmem->io.locks[i]; - PgStat_BktypeIO *bktype_shstats = &pgStatLocal.shmem->io.stats.stats[i]; + BackendType bktype = pgstat_remap_condensed_bktype(i); + PgStat_BktypeIO *bktype_shstats = &pgStatLocal.shmem->io.stats.stats[bktype]; + if(bktype == -1) + continue; LWLockAcquire(bktype_lock, LW_EXCLUSIVE); @@ -374,8 +378,11 @@ pgstat_io_snapshot_cb(void) for (int i = 0; i < BACKEND_NUM_TYPES; i++) { LWLock *bktype_lock = &pgStatLocal.shmem->io.locks[i]; - PgStat_BktypeIO *bktype_shstats = &pgStatLocal.shmem->io.stats.stats[i]; - PgStat_BktypeIO *bktype_snap = &pgStatLocal.snapshot.io.stats[i]; + BackendType bktype = pgstat_remap_condensed_bktype(i); + PgStat_BktypeIO *bktype_shstats = &pgStatLocal.shmem->io.stats.stats[bktype]; + PgStat_BktypeIO *bktype_snap = &pgStatLocal.snapshot.io.stats[bktype]; + if(bktype == -1) + continue; LWLockAcquire(bktype_lock, LW_SHARED); @@ -445,6 +452,42 @@ pgstat_tracks_io_bktype(BackendType bktype) return false; } + +/* + * Remap sparse backend type IDs to contiguous ones. Keep in sync with enum + * BackendType. + * + * Returns -1 if the input ID is invalid or unused. + */ +int +pgstat_remap_condensed_bktype(BackendType bktype) { + /* -1 here means it should not be used */ + static const int mapping_table[BACKEND_NUM_TYPES] = { + -1, /* B_INVALID */ + 0, + -1, /* B_DEAD_END_BACKEND */ + 1, + 2, + 3, + 4, + 5, + 6, + -1, /* B_ARCHIVER */ + 7, + 8, + 9, + 10, + 11, + 12, + 13, + -1 /* B_LOGGER */ + }; + + if (bktype < 0 || bktype > BACKEND_NUM_TYPES) + return -1; + return mapping_table[bktype]; +} + /* * Some BackendTypes do not perform IO on certain IOObjects or in certain * IOContexts. Some IOObjects are never operated on in some IOContexts. Check diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c index ac08ab14195..72296720286 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -1578,9 +1578,12 @@ pg_stat_get_io(PG_FUNCTION_ARGS) backends_io_stats = pgstat_fetch_stat_io(); - for (int bktype = 0; bktype < BACKEND_NUM_TYPES; bktype++) + for (int i = 0; i < BACKEND_NUM_TYPES; i++) { + BackendType bktype = pgstat_remap_condensed_bktype(i); PgStat_BktypeIO *bktype_stats = &backends_io_stats->stats[bktype]; + if(bktype == -1) + continue; /* * In Assert builds, we can afford an extra loop through all of the @@ -1757,9 +1760,12 @@ pg_stat_get_io_histogram(PG_FUNCTION_ARGS) backends_io_stats = pgstat_fetch_stat_io(); - for (int bktype = 0; bktype < BACKEND_NUM_TYPES; bktype++) + for (int i = 0; i < BACKEND_NUM_TYPES; i++) { + BackendType bktype = pgstat_remap_condensed_bktype(i); PgStat_BktypeIO *bktype_stats = &backends_io_stats->stats[bktype]; + if(bktype == -1) + continue; /* * In Assert builds, we can afford an extra loop through all of the diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h index f16f35659b9..d0c62d3248e 100644 --- a/src/include/miscadmin.h +++ b/src/include/miscadmin.h @@ -332,7 +332,7 @@ extern void SwitchBackToLocalLatch(void); * MyBackendType indicates what kind of a backend this is. * * If you add entries, please also update the child_process_kinds array in - * launch_backend.c. + * launch_backend.c and PGSTAT_USED_BACKEND_NUM_TYPES in pgstat.h */ typedef enum BackendType { diff --git a/src/include/pgstat.h b/src/include/pgstat.h index 816d261e80d..a8e1f88e4c6 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -348,10 +348,12 @@ typedef struct PgStat_PendingIO uint64 pending_hist_time_buckets[IOOBJECT_NUM_TYPES][IOCONTEXT_NUM_TYPES][IOOP_NUM_TYPES][PGSTAT_IO_HIST_BUCKETS]; } PgStat_PendingIO; +/* This needs to stay in sync with pgstat_tracks_io_bktype() */ +#define PGSTAT_USED_BACKEND_NUM_TYPES BACKEND_NUM_TYPES - 4 typedef struct PgStat_IO { TimestampTz stat_reset_timestamp; - PgStat_BktypeIO stats[BACKEND_NUM_TYPES]; + PgStat_BktypeIO stats[PGSTAT_USED_BACKEND_NUM_TYPES]; } PgStat_IO; typedef struct PgStat_StatDBEntry @@ -620,6 +622,7 @@ extern const char *pgstat_get_io_context_name(IOContext io_context); extern const char *pgstat_get_io_object_name(IOObject io_object); extern const char *pgstat_get_io_op_name(IOOp io_op); +extern int pgstat_remap_condensed_bktype(BackendType bktype); extern bool pgstat_tracks_io_bktype(BackendType bktype); extern bool pgstat_tracks_io_object(BackendType bktype, IOObject io_object, IOContext io_context);