@@ -1365,29 +1365,117 @@ pg_stat_us_to_ms(PgStat_Counter val_ms)
1365
1365
return val_ms * (double ) 0.001 ;
1366
1366
}
1367
1367
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
+
1368
1459
Datum
1369
1460
pg_stat_get_io (PG_FUNCTION_ARGS )
1370
1461
{
1371
1462
ReturnSetInfo * rsinfo ;
1372
1463
PgStat_IO * backends_io_stats ;
1373
- Datum reset_time ;
1374
1464
1375
1465
InitMaterializedSRF (fcinfo , 0 );
1376
1466
rsinfo = (ReturnSetInfo * ) fcinfo -> resultinfo ;
1377
1467
1378
1468
backends_io_stats = pgstat_fetch_stat_io ();
1379
1469
1380
- reset_time = TimestampTzGetDatum (backends_io_stats -> stat_reset_timestamp );
1381
-
1382
1470
for (int bktype = 0 ; bktype < BACKEND_NUM_TYPES ; bktype ++ )
1383
1471
{
1384
- Datum bktype_desc = CStringGetTextDatum (GetBackendTypeDesc (bktype ));
1385
1472
PgStat_BktypeIO * bktype_stats = & backends_io_stats -> stats [bktype ];
1386
1473
1387
1474
/*
1388
1475
* 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.
1391
1479
*/
1392
1480
Assert (pgstat_bktype_io_stats_valid (bktype_stats , bktype ));
1393
1481
@@ -1398,77 +1486,9 @@ pg_stat_get_io(PG_FUNCTION_ARGS)
1398
1486
if (!pgstat_tracks_io_bktype (bktype ))
1399
1487
continue ;
1400
1488
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 );
1472
1492
}
1473
1493
1474
1494
return (Datum ) 0 ;
0 commit comments