Skip to content

Commit ff7c40d

Browse files
committed
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
1 parent 08cdb07 commit ff7c40d

File tree

1 file changed

+97
-77
lines changed

1 file changed

+97
-77
lines changed

src/backend/utils/adt/pgstatfuncs.c

Lines changed: 97 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1365,29 +1365,117 @@ pg_stat_us_to_ms(PgStat_Counter val_ms)
13651365
return val_ms * (double) 0.001;
13661366
}
13671367

1368+
/*
1369+
* pg_stat_io_build_tuples
1370+
*
1371+
* Helper routine for pg_stat_get_io() filling a result tuplestore with one
1372+
* tuple for each object and each context supported by the caller, based on the
1373+
* contents of bktype_stats.
1374+
*/
1375+
static void
1376+
pg_stat_io_build_tuples(ReturnSetInfo *rsinfo,
1377+
PgStat_BktypeIO *bktype_stats,
1378+
BackendType bktype,
1379+
TimestampTz stat_reset_timestamp)
1380+
{
1381+
Datum bktype_desc = CStringGetTextDatum(GetBackendTypeDesc(bktype));
1382+
1383+
for (int io_obj = 0; io_obj < IOOBJECT_NUM_TYPES; io_obj++)
1384+
{
1385+
const char *obj_name = pgstat_get_io_object_name(io_obj);
1386+
1387+
for (int io_context = 0; io_context < IOCONTEXT_NUM_TYPES; io_context++)
1388+
{
1389+
const char *context_name = pgstat_get_io_context_name(io_context);
1390+
1391+
Datum values[IO_NUM_COLUMNS] = {0};
1392+
bool nulls[IO_NUM_COLUMNS] = {0};
1393+
1394+
/*
1395+
* Some combinations of BackendType, IOObject, and IOContext are
1396+
* not valid for any type of IOOp. In such cases, omit the entire
1397+
* row from the view.
1398+
*/
1399+
if (!pgstat_tracks_io_object(bktype, io_obj, io_context))
1400+
continue;
1401+
1402+
values[IO_COL_BACKEND_TYPE] = bktype_desc;
1403+
values[IO_COL_CONTEXT] = CStringGetTextDatum(context_name);
1404+
values[IO_COL_OBJECT] = CStringGetTextDatum(obj_name);
1405+
if (stat_reset_timestamp != 0)
1406+
values[IO_COL_RESET_TIME] = TimestampTzGetDatum(stat_reset_timestamp);
1407+
else
1408+
nulls[IO_COL_RESET_TIME] = true;
1409+
1410+
/*
1411+
* Hard-code this to the value of BLCKSZ for now. Future values
1412+
* could include XLOG_BLCKSZ, once WAL IO is tracked, and constant
1413+
* multipliers, once non-block-oriented IO (e.g. temporary file
1414+
* IO) is tracked.
1415+
*/
1416+
values[IO_COL_CONVERSION] = Int64GetDatum(BLCKSZ);
1417+
1418+
for (int io_op = 0; io_op < IOOP_NUM_TYPES; io_op++)
1419+
{
1420+
int op_idx = pgstat_get_io_op_index(io_op);
1421+
int time_idx = pgstat_get_io_time_index(io_op);
1422+
1423+
/*
1424+
* Some combinations of BackendType and IOOp, of IOContext and
1425+
* IOOp, and of IOObject and IOOp are not tracked. Set these
1426+
* cells in the view NULL.
1427+
*/
1428+
if (pgstat_tracks_io_op(bktype, io_obj, io_context, io_op))
1429+
{
1430+
PgStat_Counter count =
1431+
bktype_stats->counts[io_obj][io_context][io_op];
1432+
1433+
values[op_idx] = Int64GetDatum(count);
1434+
}
1435+
else
1436+
nulls[op_idx] = true;
1437+
1438+
/* not every operation is timed */
1439+
if (time_idx == IO_COL_INVALID)
1440+
continue;
1441+
1442+
if (!nulls[op_idx])
1443+
{
1444+
PgStat_Counter time =
1445+
bktype_stats->times[io_obj][io_context][io_op];
1446+
1447+
values[time_idx] = Float8GetDatum(pg_stat_us_to_ms(time));
1448+
}
1449+
else
1450+
nulls[time_idx] = true;
1451+
}
1452+
1453+
tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc,
1454+
values, nulls);
1455+
}
1456+
}
1457+
}
1458+
13681459
Datum
13691460
pg_stat_get_io(PG_FUNCTION_ARGS)
13701461
{
13711462
ReturnSetInfo *rsinfo;
13721463
PgStat_IO *backends_io_stats;
1373-
Datum reset_time;
13741464

13751465
InitMaterializedSRF(fcinfo, 0);
13761466
rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
13771467

13781468
backends_io_stats = pgstat_fetch_stat_io();
13791469

1380-
reset_time = TimestampTzGetDatum(backends_io_stats->stat_reset_timestamp);
1381-
13821470
for (int bktype = 0; bktype < BACKEND_NUM_TYPES; bktype++)
13831471
{
1384-
Datum bktype_desc = CStringGetTextDatum(GetBackendTypeDesc(bktype));
13851472
PgStat_BktypeIO *bktype_stats = &backends_io_stats->stats[bktype];
13861473

13871474
/*
13881475
* In Assert builds, we can afford an extra loop through all of the
1389-
* counters checking that only expected stats are non-zero, since it
1390-
* keeps the non-Assert code cleaner.
1476+
* counters (in pg_stat_io_build_tuples()), checking that only
1477+
* expected stats are non-zero, since it keeps the non-Assert code
1478+
* cleaner.
13911479
*/
13921480
Assert(pgstat_bktype_io_stats_valid(bktype_stats, bktype));
13931481

@@ -1398,77 +1486,9 @@ pg_stat_get_io(PG_FUNCTION_ARGS)
13981486
if (!pgstat_tracks_io_bktype(bktype))
13991487
continue;
14001488

1401-
for (int io_obj = 0; io_obj < IOOBJECT_NUM_TYPES; io_obj++)
1402-
{
1403-
const char *obj_name = pgstat_get_io_object_name(io_obj);
1404-
1405-
for (int io_context = 0; io_context < IOCONTEXT_NUM_TYPES; io_context++)
1406-
{
1407-
const char *context_name = pgstat_get_io_context_name(io_context);
1408-
1409-
Datum values[IO_NUM_COLUMNS] = {0};
1410-
bool nulls[IO_NUM_COLUMNS] = {0};
1411-
1412-
/*
1413-
* Some combinations of BackendType, IOObject, and IOContext
1414-
* are not valid for any type of IOOp. In such cases, omit the
1415-
* entire row from the view.
1416-
*/
1417-
if (!pgstat_tracks_io_object(bktype, io_obj, io_context))
1418-
continue;
1419-
1420-
values[IO_COL_BACKEND_TYPE] = bktype_desc;
1421-
values[IO_COL_CONTEXT] = CStringGetTextDatum(context_name);
1422-
values[IO_COL_OBJECT] = CStringGetTextDatum(obj_name);
1423-
values[IO_COL_RESET_TIME] = reset_time;
1424-
1425-
/*
1426-
* Hard-code this to the value of BLCKSZ for now. Future
1427-
* values could include XLOG_BLCKSZ, once WAL IO is tracked,
1428-
* and constant multipliers, once non-block-oriented IO (e.g.
1429-
* temporary file IO) is tracked.
1430-
*/
1431-
values[IO_COL_CONVERSION] = Int64GetDatum(BLCKSZ);
1432-
1433-
for (int io_op = 0; io_op < IOOP_NUM_TYPES; io_op++)
1434-
{
1435-
int op_idx = pgstat_get_io_op_index(io_op);
1436-
int time_idx = pgstat_get_io_time_index(io_op);
1437-
1438-
/*
1439-
* Some combinations of BackendType and IOOp, of IOContext
1440-
* and IOOp, and of IOObject and IOOp are not tracked. Set
1441-
* these cells in the view NULL.
1442-
*/
1443-
if (pgstat_tracks_io_op(bktype, io_obj, io_context, io_op))
1444-
{
1445-
PgStat_Counter count =
1446-
bktype_stats->counts[io_obj][io_context][io_op];
1447-
1448-
values[op_idx] = Int64GetDatum(count);
1449-
}
1450-
else
1451-
nulls[op_idx] = true;
1452-
1453-
/* not every operation is timed */
1454-
if (time_idx == IO_COL_INVALID)
1455-
continue;
1456-
1457-
if (!nulls[op_idx])
1458-
{
1459-
PgStat_Counter time =
1460-
bktype_stats->times[io_obj][io_context][io_op];
1461-
1462-
values[time_idx] = Float8GetDatum(pg_stat_us_to_ms(time));
1463-
}
1464-
else
1465-
nulls[time_idx] = true;
1466-
}
1467-
1468-
tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc,
1469-
values, nulls);
1470-
}
1471-
}
1489+
/* save tuples with data from this PgStat_BktypeIO */
1490+
pg_stat_io_build_tuples(rsinfo, bktype_stats, bktype,
1491+
backends_io_stats->stat_reset_timestamp);
14721492
}
14731493

14741494
return (Datum) 0;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy