mirror of
https://github.com/postgres/postgres.git
synced 2025-05-29 16:21:20 +03:00
Extract logic filling pg_stat_get_io()'s tuplestore into its own routine
This commit adds pg_stat_io_build_tuples(), a helper routine for pg_stat_get_io(), that fills its result tuplestore based on the contents of PgStat_BktypeIO. This will be used in a follow-up commit that uses the same structures as pg_stat_io for reporting, including the same object types and contexts, but for a different statistics kind. Author: Bertrand Drouvot, Michael Paquier Discussion: https://postgr.es/m/ZtXR+CtkEVVE/LHF@ip-10-97-1-34.eu-west-3.compute.internal
This commit is contained in:
parent
08cdb079d4
commit
ff7c40d7fd
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user