From c74028f943d51cea79968d1519af68b9242094c3 Mon Sep 17 00:00:00 2001 From: Alena Rybakina Date: Mon, 20 Jul 2026 17:22:26 +0300 Subject: [PATCH v42 8/9] ext_vacuum_statistics: shared-buffer access counters and I/O timing. Add the buffer category: total shared-buffer traffic of a vacuum (total_blks_read, total_blks_hit, total_blks_dirtied, total_blks_written), the relation-level breakdown (rel_blks_read, rel_blks_hit) and the I/O times (blk_read_time, blk_write_time), for tables, indexes, and the per-database aggregate, sampled by the core machinery from pgBufferUsage and the relation's pgstat counts around the heap run and each index pass. The resource usage of index passes is subtracted from the heap report to avoid double-counting in aggregates. Buffer traffic is the other primary answer to "which relations or databases were the most expensive to vacuum": it shows both how much data a vacuum had to touch, how much of it missed shared buffers, and how long the resulting I/O took. --- contrib/ext_vacuum_statistics/README.md | 6 +- .../ext_vacuum_statistics--1.0.sql | 48 +++++- .../t/052_vacuum_extending_basic_test.pl | 23 ++- .../ext_vacuum_statistics/vacuum_statistics.c | 24 ++- doc/src/sgml/extvacuumstatistics.sgml | 143 +++++++++++++++++- src/backend/access/heap/vacuumlazy.c | 75 +++++++-- src/backend/commands/vacuumparallel.c | 7 +- src/include/commands/vacuum.h | 13 ++ src/include/pgstat.h | 8 + 9 files changed, 319 insertions(+), 28 deletions(-) diff --git a/contrib/ext_vacuum_statistics/README.md b/contrib/ext_vacuum_statistics/README.md index 2a8477535c3..14a62384d68 100644 --- a/contrib/ext_vacuum_statistics/README.md +++ b/contrib/ext_vacuum_statistics/README.md @@ -45,9 +45,9 @@ SELECT * FROM ext_vacuum_statistics.pg_stats_vacuum_database; Example output: ``` - relname | wal_records | tuples_deleted | pages_removed ------------+-------------+----------------+--------------- - mytable | 15 | 500 | 10 + relname | total_blks_read | total_blks_hit | wal_records | tuples_deleted | pages_removed +-----------+-----------------+----------------+-------------+----------------+--------------- + mytable | 120 | 340 | 15 | 500 | 10 ``` Reset statistics when needed: diff --git a/contrib/ext_vacuum_statistics/ext_vacuum_statistics--1.0.sql b/contrib/ext_vacuum_statistics/ext_vacuum_statistics--1.0.sql index 279f673f6be..50f0cd81d05 100644 --- a/contrib/ext_vacuum_statistics/ext_vacuum_statistics--1.0.sql +++ b/contrib/ext_vacuum_statistics/ext_vacuum_statistics--1.0.sql @@ -49,9 +49,17 @@ CREATE OR REPLACE FUNCTION ext_vacuum_statistics.pg_stats_get_vacuum_tables( IN dboid oid, IN reloid oid, OUT relid oid, + OUT total_blks_read bigint, + OUT total_blks_hit bigint, + OUT total_blks_dirtied bigint, + OUT total_blks_written bigint, OUT wal_records bigint, OUT wal_fpi bigint, OUT wal_bytes numeric, + OUT blk_read_time double precision, + OUT blk_write_time double precision, + OUT rel_blks_read bigint, + OUT rel_blks_hit bigint, OUT tuples_deleted bigint, OUT pages_scanned bigint, OUT pages_removed bigint, @@ -69,9 +77,17 @@ CREATE OR REPLACE FUNCTION ext_vacuum_statistics.pg_stats_get_vacuum_indexes( IN dboid oid, IN reloid oid, OUT relid oid, + OUT total_blks_read bigint, + OUT total_blks_hit bigint, + OUT total_blks_dirtied bigint, + OUT total_blks_written bigint, OUT wal_records bigint, OUT wal_fpi bigint, OUT wal_bytes numeric, + OUT blk_read_time double precision, + OUT blk_write_time double precision, + OUT rel_blks_read bigint, + OUT rel_blks_hit bigint, OUT tuples_deleted bigint, OUT pages_deleted bigint ) @@ -83,9 +99,15 @@ LANGUAGE C STRICT STABLE; CREATE OR REPLACE FUNCTION ext_vacuum_statistics.pg_stats_get_vacuum_database( IN dboid oid, OUT dbid oid, + OUT total_blks_read bigint, + OUT total_blks_hit bigint, + OUT total_blks_dirtied bigint, + OUT total_blks_written bigint, OUT wal_records bigint, OUT wal_fpi bigint, - OUT wal_bytes numeric + OUT wal_bytes numeric, + OUT blk_read_time double precision, + OUT blk_write_time double precision ) RETURNS SETOF record AS 'MODULE_PATHNAME', 'pg_stats_get_vacuum_database' @@ -98,9 +120,17 @@ SELECT ns.nspname AS schema, rel.relname AS relname, db.datname AS dbname, + stats.total_blks_read, + stats.total_blks_hit, + stats.total_blks_dirtied, + stats.total_blks_written, stats.wal_records, stats.wal_fpi, stats.wal_bytes, + stats.blk_read_time, + stats.blk_write_time, + stats.rel_blks_read, + stats.rel_blks_hit, stats.tuples_deleted, stats.pages_scanned, stats.pages_removed, @@ -127,9 +157,17 @@ SELECT ns.nspname AS schema, rel.relname AS indexrelname, db.datname AS dbname, + stats.total_blks_read, + stats.total_blks_hit, + stats.total_blks_dirtied, + stats.total_blks_written, stats.wal_records, stats.wal_fpi, stats.wal_bytes, + stats.blk_read_time, + stats.blk_write_time, + stats.rel_blks_read, + stats.rel_blks_hit, stats.tuples_deleted, stats.pages_deleted FROM pg_database db, @@ -149,9 +187,15 @@ CREATE VIEW ext_vacuum_statistics.pg_stats_vacuum_database AS SELECT db.oid AS dboid, db.datname AS dbname, + stats.total_blks_read AS db_blks_read, + stats.total_blks_hit AS db_blks_hit, + stats.total_blks_dirtied AS db_blks_dirtied, + stats.total_blks_written AS db_blks_written, stats.wal_records AS db_wal_records, stats.wal_fpi AS db_wal_fpi, - stats.wal_bytes AS db_wal_bytes + stats.wal_bytes AS db_wal_bytes, + stats.blk_read_time AS db_blk_read_time, + stats.blk_write_time AS db_blk_write_time FROM pg_database db LEFT JOIN LATERAL ext_vacuum_statistics.pg_stats_get_vacuum_database(db.oid) stats ON db.oid = stats.dbid; diff --git a/contrib/ext_vacuum_statistics/t/052_vacuum_extending_basic_test.pl b/contrib/ext_vacuum_statistics/t/052_vacuum_extending_basic_test.pl index 494c6cc8259..ba649bc25ee 100644 --- a/contrib/ext_vacuum_statistics/t/052_vacuum_extending_basic_test.pl +++ b/contrib/ext_vacuum_statistics/t/052_vacuum_extending_basic_test.pl @@ -263,16 +263,22 @@ sub fetch_error_base_db_vacuum_statistics { # fetch actual base database vacuum statistics my $base_statistics = $node->safe_psql( $database_name, - "SELECT db_wal_records, db_wal_fpi, db_wal_bytes + "SELECT db_blks_hit, db_blks_dirtied, + db_blks_written, db_wal_records, + db_wal_fpi, db_wal_bytes FROM ext_vacuum_statistics.pg_stats_vacuum_database, pg_database WHERE pg_database.datname = '$dbname' AND pg_database.oid = ext_vacuum_statistics.pg_stats_vacuum_database.dboid;" ); $base_statistics =~ s/\s*\|\s*/ /g; # transform " | " in space - my ($wal_records, $wal_fpi, $wal_bytes) = split /\s+/, $base_statistics; + my ($db_blks_hit, $total_blks_dirtied, $total_blks_written, + $wal_records, $wal_fpi, $wal_bytes) = split /\s+/, $base_statistics; diag( "BASE STATS MISMATCH FOR DATABASE $dbname:\n" . + " db_blks_hit = $db_blks_hit\n" . + " total_blks_dirtied = $total_blks_dirtied\n" . + " total_blks_written = $total_blks_written\n" . " wal_records = $wal_records\n" . " wal_fpi = $wal_fpi\n" . " wal_bytes = $wal_bytes\n" @@ -617,19 +623,28 @@ is($base_stats, 0, 'vacuum stats per all index objects from another database are #-------------------------------------------------------------------------------------- subtest 'Test 9: Check database-level vacuum statistics from the current and another database' => sub { +my $db_blk_hit = 0; +my $total_blks_dirtied = 0; +my $total_blks_written = 0; my $wal_records = 0; my $wal_fpi = 0; my $wal_bytes = 0; $base_stats = $node->safe_psql( $dbname, - "SELECT db_wal_records, db_wal_fpi, db_wal_bytes + "SELECT db_blks_hit, db_blks_dirtied, + db_blks_written, db_wal_records, + db_wal_fpi, db_wal_bytes FROM ext_vacuum_statistics.pg_stats_vacuum_database, pg_database WHERE pg_database.datname = '$dbname' AND pg_database.oid = ext_vacuum_statistics.pg_stats_vacuum_database.dboid;" ); $base_stats =~ s/\s*\|\s*/ /g; # transform " | " into space - ($wal_records, $wal_fpi, $wal_bytes) = split /\s+/, $base_stats; + ($db_blk_hit, $total_blks_dirtied, $total_blks_written, $wal_records, $wal_fpi, $wal_bytes) + = split /\s+/, $base_stats; +ok($db_blk_hit > 0, 'db_blks_hit is more than 0'); +ok($total_blks_dirtied > 0, 'total_blks_dirtied is more than 0'); +ok($total_blks_written > 0, 'total_blks_written is more than 0'); ok($wal_records > 0, 'wal_records is more than 0'); ok($wal_fpi > 0, 'wal_fpi is more than 0'); ok($wal_bytes > 0, 'wal_bytes is more than 0'); diff --git a/contrib/ext_vacuum_statistics/vacuum_statistics.c b/contrib/ext_vacuum_statistics/vacuum_statistics.c index da8f5f56c26..85941df0112 100644 --- a/contrib/ext_vacuum_statistics/vacuum_statistics.c +++ b/contrib/ext_vacuum_statistics/vacuum_statistics.c @@ -82,6 +82,14 @@ static const PgStat_KindInfo extvac_db_kind_info = { static inline void pgstat_accumulate_common(PgStat_CommonCounts * dst, const PgStat_CommonCounts * src) { + dst->total_blks_read += src->total_blks_read; + dst->total_blks_hit += src->total_blks_hit; + dst->total_blks_dirtied += src->total_blks_dirtied; + dst->total_blks_written += src->total_blks_written; + dst->blks_fetched += src->blks_fetched; + dst->blks_hit += src->blks_hit; + dst->blk_read_time += src->blk_read_time; + dst->blk_write_time += src->blk_write_time; dst->wal_records += src->wal_records; dst->wal_fpi += src->wal_fpi; dst->wal_bytes += src->wal_bytes; @@ -305,7 +313,7 @@ extvac_shared_memory_size(PG_FUNCTION_ARGS) /* * Output vacuum statistics (tables, indexes, or per-database aggregates). */ -#define EXTVAC_COMMON_STAT_COLS 3 +#define EXTVAC_COMMON_STAT_COLS 9 static void tuplestore_put_common(PgStat_CommonCounts * vacuum_ext, @@ -314,6 +322,10 @@ tuplestore_put_common(PgStat_CommonCounts * vacuum_ext, char buf[256]; const int base PG_USED_FOR_ASSERTS_ONLY = *i; + values[(*i)++] = Int64GetDatum(vacuum_ext->total_blks_read); + values[(*i)++] = Int64GetDatum(vacuum_ext->total_blks_hit); + values[(*i)++] = Int64GetDatum(vacuum_ext->total_blks_dirtied); + values[(*i)++] = Int64GetDatum(vacuum_ext->total_blks_written); values[(*i)++] = Int64GetDatum(vacuum_ext->wal_records); values[(*i)++] = Int64GetDatum(vacuum_ext->wal_fpi); snprintf(buf, sizeof buf, UINT64_FORMAT, vacuum_ext->wal_bytes); @@ -321,11 +333,13 @@ tuplestore_put_common(PgStat_CommonCounts * vacuum_ext, CStringGetDatum(buf), ObjectIdGetDatum(0), Int32GetDatum(-1)); + values[(*i)++] = Float8GetDatum(vacuum_ext->blk_read_time); + values[(*i)++] = Float8GetDatum(vacuum_ext->blk_write_time); Assert((*i - base) == EXTVAC_COMMON_STAT_COLS); } -#define EXTVAC_HEAP_STAT_COLS 11 -#define EXTVAC_IDX_STAT_COLS 6 +#define EXTVAC_HEAP_STAT_COLS 19 +#define EXTVAC_IDX_STAT_COLS 14 #define EXTVAC_MAX_STAT_COLS Max(EXTVAC_HEAP_STAT_COLS, EXTVAC_IDX_STAT_COLS) static void @@ -340,6 +354,8 @@ tuplestore_put_for_relation(Oid relid, Tuplestorestate *tupstore, values[i++] = ObjectIdGetDatum(relid); tuplestore_put_common(&vacuum_ext->common, values, nulls, &i); + values[i++] = Int64GetDatum(vacuum_ext->common.blks_fetched - vacuum_ext->common.blks_hit); + values[i++] = Int64GetDatum(vacuum_ext->common.blks_hit); if (vacuum_ext->type == PGSTAT_EXTVAC_TABLE) { @@ -417,7 +433,7 @@ pg_stats_vacuum(FunctionCallInfo fcinfo, int type) { if (OidIsValid(dbid)) { -#define EXTVAC_DB_STAT_COLS 4 +#define EXTVAC_DB_STAT_COLS 10 Datum values[EXTVAC_DB_STAT_COLS]; bool nulls[EXTVAC_DB_STAT_COLS]; int i = 0; diff --git a/doc/src/sgml/extvacuumstatistics.sgml b/doc/src/sgml/extvacuumstatistics.sgml index 9e601f0951d..475eb5ebab7 100644 --- a/doc/src/sgml/extvacuumstatistics.sgml +++ b/doc/src/sgml/extvacuumstatistics.sgml @@ -99,6 +99,38 @@ Name of the database containing this table + + + total_blks_read int8 + + + Number of database blocks read by vacuum operations performed on this table + + + + + total_blks_hit int8 + + + Number of times database blocks were found in the buffer cache by vacuum operations + + + + + total_blks_dirtied int8 + + + Number of database blocks dirtied by vacuum operations + + + + + total_blks_written int8 + + + Number of database blocks written by vacuum operations + + wal_records int8 @@ -123,6 +155,38 @@ Total amount of WAL bytes generated by vacuum operations + + + blk_read_time float8 + + + Time spent reading blocks by vacuum operations, in milliseconds + + + + + blk_write_time float8 + + + Time spent writing blocks by vacuum operations, in milliseconds + + + + + rel_blks_read int8 + + + Number of blocks vacuum operations read from this table + + + + + rel_blks_hit int8 + + + Number of times blocks of this table were found in the buffer cache by vacuum + + tuples_deleted int8 @@ -244,6 +308,42 @@ Name of the database containing this index + + + total_blks_read int8 + + + Number of database blocks read by vacuum operations while processing + this index + + + + + total_blks_hit int8 + + + Number of times database blocks were found in the buffer cache by + vacuum operations while processing this index + + + + + total_blks_dirtied int8 + + + Number of database blocks dirtied by vacuum operations while + processing this index + + + + + total_blks_written int8 + + + Number of database blocks written by vacuum operations while + processing this index + + wal_records int8 @@ -271,6 +371,41 @@ processing this index + + + blk_read_time float8 + + + Time spent reading blocks by vacuum operations while processing this + index, in milliseconds + + + + + blk_write_time float8 + + + Time spent writing blocks by vacuum operations while processing this + index, in milliseconds + + + + + rel_blks_read int8 + + + Number of blocks of this index read by vacuum operations + + + + + rel_blks_hit int8 + + + Number of blocks of this index found in the buffer cache by vacuum + operations + + tuples_deleted int8 @@ -305,8 +440,12 @@ contains one row for each database in the cluster, showing aggregate vacuum statistics for that database. Columns include dboid, dbname, - and WAL stats (db_wal_records, - db_wal_fpi, db_wal_bytes). + db_blks_read, db_blks_hit, + db_blks_dirtied, db_blks_written, + WAL stats (db_wal_records, + db_wal_fpi, db_wal_bytes), + and I/O timing (db_blk_read_time, + db_blk_write_time). diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c index 6adbcd31224..803152fe46a 100644 --- a/src/backend/access/heap/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -511,6 +511,13 @@ extvac_stats_start(Relation rel, LVExtStatCounters * counters) { memset(counters, 0, sizeof(LVExtStatCounters)); counters->walusage = pgWalUsage; + counters->bufusage = pgBufferUsage; + + if (rel->pgstat_info && pgstat_track_counts) + { + counters->blocks_fetched = rel->pgstat_info->counts.blocks_fetched; + counters->blocks_hit = rel->pgstat_info->counts.blocks_hit; + } } /* @@ -521,13 +528,53 @@ extvac_stats_end(Relation rel, LVExtStatCounters * counters, PgStat_CommonCounts * report) { WalUsage walusage; + BufferUsage bufusage; memset(&walusage, 0, sizeof(WalUsage)); WalUsageAccumDiff(&walusage, &pgWalUsage, &counters->walusage); - + memset(&bufusage, 0, sizeof(BufferUsage)); + BufferUsageAccumDiff(&bufusage, &pgBufferUsage, &counters->bufusage); + + report->total_blks_read = bufusage.local_blks_read + bufusage.shared_blks_read; + report->total_blks_hit = bufusage.local_blks_hit + bufusage.shared_blks_hit; + report->total_blks_dirtied = bufusage.local_blks_dirtied + bufusage.shared_blks_dirtied; + report->total_blks_written = bufusage.shared_blks_written; + report->blk_read_time = INSTR_TIME_GET_MILLISEC(bufusage.local_blk_read_time) + + INSTR_TIME_GET_MILLISEC(bufusage.shared_blk_read_time); + report->blk_write_time = INSTR_TIME_GET_MILLISEC(bufusage.local_blk_write_time) + + INSTR_TIME_GET_MILLISEC(bufusage.shared_blk_write_time); report->wal_records = walusage.wal_records; report->wal_fpi = walusage.wal_fpi; report->wal_bytes = walusage.wal_bytes; + + if (rel->pgstat_info && pgstat_track_counts) + { + report->blks_fetched = rel->pgstat_info->counts.blocks_fetched - counters->blocks_fetched; + report->blks_hit = rel->pgstat_info->counts.blocks_hit - counters->blocks_hit; + } +} + +/* + * extvac_stats_start_idx - Snapshot resource usage before an index pass. + */ +void +extvac_stats_start_idx(Relation rel, LVExtStatCountersIdx * counters) +{ + extvac_stats_start(rel, &counters->common); +} + +/* + * extvac_stats_end_idx - Diff resource usage of an index pass into report. + * + * The bulkdelete result deltas (tuples/pages) are computed by the caller, + * which tracks the running totals across passes. + */ +void +extvac_stats_end_idx(Relation rel, LVExtStatCountersIdx * counters, + PgStat_VacuumRelationCounts * report) +{ + extvac_stats_end(rel, &counters->common, &report->common); + report->type = PGSTAT_EXTVAC_INDEX; } /* @@ -552,6 +599,12 @@ accumulate_heap_vacuum_statistics(LVRelState *vacrel, PgStat_VacuumRelationCount * them twice otherwise. Parallel workers report their own usage with * their index passes, so it never enters the leader's counters. */ + extVacStats->common.total_blks_read -= vacrel->extVacReportIdx.common.total_blks_read; + extVacStats->common.total_blks_hit -= vacrel->extVacReportIdx.common.total_blks_hit; + extVacStats->common.total_blks_dirtied -= vacrel->extVacReportIdx.common.total_blks_dirtied; + extVacStats->common.total_blks_written -= vacrel->extVacReportIdx.common.total_blks_written; + extVacStats->common.blk_read_time -= vacrel->extVacReportIdx.common.blk_read_time; + extVacStats->common.blk_write_time -= vacrel->extVacReportIdx.common.blk_write_time; extVacStats->common.wal_records -= vacrel->extVacReportIdx.common.wal_records; extVacStats->common.wal_fpi -= vacrel->extVacReportIdx.common.wal_fpi; extVacStats->common.wal_bytes -= vacrel->extVacReportIdx.common.wal_bytes; @@ -565,6 +618,12 @@ static void accumulate_idxs_vacuum_statistics(LVRelState *vacrel, PgStat_VacuumRelationCounts * extVacIdxStats) { + vacrel->extVacReportIdx.common.total_blks_read += extVacIdxStats->common.total_blks_read; + vacrel->extVacReportIdx.common.total_blks_hit += extVacIdxStats->common.total_blks_hit; + vacrel->extVacReportIdx.common.total_blks_dirtied += extVacIdxStats->common.total_blks_dirtied; + vacrel->extVacReportIdx.common.total_blks_written += extVacIdxStats->common.total_blks_written; + vacrel->extVacReportIdx.common.blk_read_time += extVacIdxStats->common.blk_read_time; + vacrel->extVacReportIdx.common.blk_write_time += extVacIdxStats->common.blk_write_time; vacrel->extVacReportIdx.common.wal_records += extVacIdxStats->common.wal_records; vacrel->extVacReportIdx.common.wal_fpi += extVacIdxStats->common.wal_fpi; vacrel->extVacReportIdx.common.wal_bytes += extVacIdxStats->common.wal_bytes; @@ -3139,7 +3198,7 @@ lazy_vacuum_one_index(Relation indrel, IndexBulkDeleteResult *istat, double startdelaytime = VacuumDelayTime; double prev_tuples_removed = 0; BlockNumber prev_pages_deleted = 0; - LVExtStatCounters extVacCounters; + LVExtStatCountersIdx extVacCounters; PgStat_VacuumRelationCounts extVacReport; /* @@ -3152,7 +3211,7 @@ lazy_vacuum_one_index(Relation indrel, IndexBulkDeleteResult *istat, prev_pages_deleted = istat->pages_deleted; } if (set_report_vacuum_hook) - extvac_stats_start(indrel, &extVacCounters); + extvac_stats_start_idx(indrel, &extVacCounters); ivinfo.index = indrel; ivinfo.heaprel = vacrel->rel; ivinfo.analyze_only = false; @@ -3190,8 +3249,7 @@ lazy_vacuum_one_index(Relation indrel, IndexBulkDeleteResult *istat, if (set_report_vacuum_hook) { memset(&extVacReport, 0, sizeof(extVacReport)); - extvac_stats_end(indrel, &extVacCounters, &extVacReport.common); - extVacReport.type = PGSTAT_EXTVAC_INDEX; + extvac_stats_end_idx(indrel, &extVacCounters, &extVacReport); if (istat != NULL) { extVacReport.common.tuples_deleted = @@ -3231,7 +3289,7 @@ lazy_cleanup_one_index(Relation indrel, IndexBulkDeleteResult *istat, double startdelaytime = VacuumDelayTime; double prev_tuples_removed = 0; BlockNumber prev_pages_deleted = 0; - LVExtStatCounters extVacCounters; + LVExtStatCountersIdx extVacCounters; PgStat_VacuumRelationCounts extVacReport; /* @@ -3244,7 +3302,7 @@ lazy_cleanup_one_index(Relation indrel, IndexBulkDeleteResult *istat, prev_pages_deleted = istat->pages_deleted; } if (set_report_vacuum_hook) - extvac_stats_start(indrel, &extVacCounters); + extvac_stats_start_idx(indrel, &extVacCounters); ivinfo.index = indrel; ivinfo.heaprel = vacrel->rel; ivinfo.analyze_only = false; @@ -3281,8 +3339,7 @@ lazy_cleanup_one_index(Relation indrel, IndexBulkDeleteResult *istat, if (set_report_vacuum_hook) { memset(&extVacReport, 0, sizeof(extVacReport)); - extvac_stats_end(indrel, &extVacCounters, &extVacReport.common); - extVacReport.type = PGSTAT_EXTVAC_INDEX; + extvac_stats_end_idx(indrel, &extVacCounters, &extVacReport); if (istat != NULL) { extVacReport.common.tuples_deleted = diff --git a/src/backend/commands/vacuumparallel.c b/src/backend/commands/vacuumparallel.c index c48ef437389..40e52065f65 100644 --- a/src/backend/commands/vacuumparallel.c +++ b/src/backend/commands/vacuumparallel.c @@ -1082,7 +1082,7 @@ parallel_vacuum_process_one_index(ParallelVacuumState *pvs, Relation indrel, double startdelaytime = VacuumDelayTime; double prev_tuples_removed = 0; BlockNumber prev_pages_deleted = 0; - LVExtStatCounters extVacCounters; + LVExtStatCountersIdx extVacCounters; PgStat_VacuumRelationCounts extVacReport; /* @@ -1102,7 +1102,7 @@ parallel_vacuum_process_one_index(ParallelVacuumState *pvs, Relation indrel, prev_pages_deleted = istat->pages_deleted; } if (set_report_vacuum_hook) - extvac_stats_start(indrel, &extVacCounters); + extvac_stats_start_idx(indrel, &extVacCounters); ivinfo.index = indrel; ivinfo.heaprel = pvs->heaprel; ivinfo.analyze_only = false; @@ -1134,8 +1134,7 @@ parallel_vacuum_process_one_index(ParallelVacuumState *pvs, Relation indrel, if (set_report_vacuum_hook) { memset(&extVacReport, 0, sizeof(extVacReport)); - extvac_stats_end(indrel, &extVacCounters, &extVacReport.common); - extVacReport.type = PGSTAT_EXTVAC_INDEX; + extvac_stats_end_idx(indrel, &extVacCounters, &extVacReport); if (istat_res != NULL) { extVacReport.common.tuples_deleted = diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 856c6fefd17..3307f7aac4a 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -360,12 +360,25 @@ extern PGDLLIMPORT int VacuumCostBalanceLocal; typedef struct LVExtStatCounters { WalUsage walusage; + BufferUsage bufusage; + PgStat_Counter blocks_fetched; + PgStat_Counter blocks_hit; } LVExtStatCounters; extern void extvac_stats_start(Relation rel, LVExtStatCounters *counters); extern void extvac_stats_end(Relation rel, LVExtStatCounters *counters, PgStat_CommonCounts *report); +/* Per-index-pass sampling state; deltas of istat are computed by callers */ +typedef struct LVExtStatCountersIdx +{ + LVExtStatCounters common; +} LVExtStatCountersIdx; + +extern void extvac_stats_start_idx(Relation rel, LVExtStatCountersIdx *counters); +extern void extvac_stats_end_idx(Relation rel, LVExtStatCountersIdx *counters, + PgStat_VacuumRelationCounts *report); + extern PGDLLIMPORT bool VacuumFailsafeActive; extern PGDLLIMPORT double vacuum_cost_delay; extern PGDLLIMPORT int vacuum_cost_limit; diff --git a/src/include/pgstat.h b/src/include/pgstat.h index a984c1bc347..41f0305223e 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -107,6 +107,14 @@ typedef enum ExtVacReportType typedef struct PgStat_CommonCounts { + int64 total_blks_read; + int64 total_blks_hit; + int64 total_blks_dirtied; + int64 total_blks_written; + int64 blks_fetched; + int64 blks_hit; + double blk_read_time; + double blk_write_time; int64 wal_records; int64 wal_fpi; uint64 wal_bytes; -- 2.39.5 (Apple Git-154)