diff options
Diffstat (limited to 'src/backend/utils/adt/pgstatfuncs.c')
-rw-r--r-- | src/backend/utils/adt/pgstatfuncs.c | 174 |
1 files changed, 97 insertions, 77 deletions
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c index cdf37403e9d..03dd8cd335a 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -1365,29 +1365,117 @@ pg_stat_us_to_ms(PgStat_Counter val_ms) return val_ms * (double) 0.001; } +/* + * pg_stat_io_build_tuples + * + * Helper routine for pg_stat_get_io() filling a result tuplestore with one + * tuple for each object and each context supported by the caller, based on the + * contents of bktype_stats. + */ +static void +pg_stat_io_build_tuples(ReturnSetInfo *rsinfo, + PgStat_BktypeIO *bktype_stats, + BackendType bktype, + TimestampTz stat_reset_timestamp) +{ + Datum bktype_desc = CStringGetTextDatum(GetBackendTypeDesc(bktype)); + + for (int io_obj = 0; io_obj < IOOBJECT_NUM_TYPES; io_obj++) + { + const char *obj_name = pgstat_get_io_object_name(io_obj); + + for (int io_context = 0; io_context < IOCONTEXT_NUM_TYPES; io_context++) + { + const char *context_name = pgstat_get_io_context_name(io_context); + + Datum values[IO_NUM_COLUMNS] = {0}; + bool nulls[IO_NUM_COLUMNS] = {0}; + + /* + * Some combinations of BackendType, IOObject, and IOContext are + * not valid for any type of IOOp. In such cases, omit the entire + * row from the view. + */ + if (!pgstat_tracks_io_object(bktype, io_obj, io_context)) + continue; + + values[IO_COL_BACKEND_TYPE] = bktype_desc; + values[IO_COL_CONTEXT] = CStringGetTextDatum(context_name); + values[IO_COL_OBJECT] = CStringGetTextDatum(obj_name); + if (stat_reset_timestamp != 0) + values[IO_COL_RESET_TIME] = TimestampTzGetDatum(stat_reset_timestamp); + else + nulls[IO_COL_RESET_TIME] = true; + + /* + * Hard-code this to the value of BLCKSZ for now. Future values + * could include XLOG_BLCKSZ, once WAL IO is tracked, and constant + * multipliers, once non-block-oriented IO (e.g. temporary file + * IO) is tracked. + */ + values[IO_COL_CONVERSION] = Int64GetDatum(BLCKSZ); + + for (int io_op = 0; io_op < IOOP_NUM_TYPES; io_op++) + { + int op_idx = pgstat_get_io_op_index(io_op); + int time_idx = pgstat_get_io_time_index(io_op); + + /* + * Some combinations of BackendType and IOOp, of IOContext and + * IOOp, and of IOObject and IOOp are not tracked. Set these + * cells in the view NULL. + */ + if (pgstat_tracks_io_op(bktype, io_obj, io_context, io_op)) + { + PgStat_Counter count = + bktype_stats->counts[io_obj][io_context][io_op]; + + values[op_idx] = Int64GetDatum(count); + } + else + nulls[op_idx] = true; + + /* not every operation is timed */ + if (time_idx == IO_COL_INVALID) + continue; + + if (!nulls[op_idx]) + { + PgStat_Counter time = + bktype_stats->times[io_obj][io_context][io_op]; + + values[time_idx] = Float8GetDatum(pg_stat_us_to_ms(time)); + } + else + nulls[time_idx] = true; + } + + tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, + values, nulls); + } + } +} + Datum pg_stat_get_io(PG_FUNCTION_ARGS) { ReturnSetInfo *rsinfo; PgStat_IO *backends_io_stats; - Datum reset_time; InitMaterializedSRF(fcinfo, 0); rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; backends_io_stats = pgstat_fetch_stat_io(); - reset_time = TimestampTzGetDatum(backends_io_stats->stat_reset_timestamp); - for (int bktype = 0; bktype < BACKEND_NUM_TYPES; bktype++) { - Datum bktype_desc = CStringGetTextDatum(GetBackendTypeDesc(bktype)); PgStat_BktypeIO *bktype_stats = &backends_io_stats->stats[bktype]; /* * In Assert builds, we can afford an extra loop through all of the - * counters checking that only expected stats are non-zero, since it - * keeps the non-Assert code cleaner. + * counters (in pg_stat_io_build_tuples()), checking that only + * expected stats are non-zero, since it keeps the non-Assert code + * cleaner. */ Assert(pgstat_bktype_io_stats_valid(bktype_stats, bktype)); @@ -1398,77 +1486,9 @@ pg_stat_get_io(PG_FUNCTION_ARGS) if (!pgstat_tracks_io_bktype(bktype)) continue; - for (int io_obj = 0; io_obj < IOOBJECT_NUM_TYPES; io_obj++) - { - const char *obj_name = pgstat_get_io_object_name(io_obj); - - for (int io_context = 0; io_context < IOCONTEXT_NUM_TYPES; io_context++) - { - const char *context_name = pgstat_get_io_context_name(io_context); - - Datum values[IO_NUM_COLUMNS] = {0}; - bool nulls[IO_NUM_COLUMNS] = {0}; - - /* - * Some combinations of BackendType, IOObject, and IOContext - * are not valid for any type of IOOp. In such cases, omit the - * entire row from the view. - */ - if (!pgstat_tracks_io_object(bktype, io_obj, io_context)) - continue; - - values[IO_COL_BACKEND_TYPE] = bktype_desc; - values[IO_COL_CONTEXT] = CStringGetTextDatum(context_name); - values[IO_COL_OBJECT] = CStringGetTextDatum(obj_name); - values[IO_COL_RESET_TIME] = reset_time; - - /* - * Hard-code this to the value of BLCKSZ for now. Future - * values could include XLOG_BLCKSZ, once WAL IO is tracked, - * and constant multipliers, once non-block-oriented IO (e.g. - * temporary file IO) is tracked. - */ - values[IO_COL_CONVERSION] = Int64GetDatum(BLCKSZ); - - for (int io_op = 0; io_op < IOOP_NUM_TYPES; io_op++) - { - int op_idx = pgstat_get_io_op_index(io_op); - int time_idx = pgstat_get_io_time_index(io_op); - - /* - * Some combinations of BackendType and IOOp, of IOContext - * and IOOp, and of IOObject and IOOp are not tracked. Set - * these cells in the view NULL. - */ - if (pgstat_tracks_io_op(bktype, io_obj, io_context, io_op)) - { - PgStat_Counter count = - bktype_stats->counts[io_obj][io_context][io_op]; - - values[op_idx] = Int64GetDatum(count); - } - else - nulls[op_idx] = true; - - /* not every operation is timed */ - if (time_idx == IO_COL_INVALID) - continue; - - if (!nulls[op_idx]) - { - PgStat_Counter time = - bktype_stats->times[io_obj][io_context][io_op]; - - values[time_idx] = Float8GetDatum(pg_stat_us_to_ms(time)); - } - else - nulls[time_idx] = true; - } - - tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, - values, nulls); - } - } + /* save tuples with data from this PgStat_BktypeIO */ + pg_stat_io_build_tuples(rsinfo, bktype_stats, bktype, + backends_io_stats->stat_reset_timestamp); } return (Datum) 0; |