From 66aafd7ac70686a164c35bf6bb3b8b757c16cf43 Mon Sep 17 00:00:00 2001 From: Alena Rybakina Date: Wed, 17 Jun 2026 21:46:14 +0300 Subject: [PATCH 7/9] Extended vacuum statistics: total shared-buffer access counters Expose the shared-buffer access counters in pg_stat_vacuum_tables, pg_stat_vacuum_indexes and the pg_stat_vacuum_database aggregate, with documentation and regression coverage: total_blks_read shared buffer blocks missed (read from disk) total_blks_hit shared buffer blocks found in the buffer cache (hits) total_blks_dirtied shared buffer blocks dirtied by this vacuum total_blks_written shared buffer blocks written out These counters are common to tables, indexes and the database aggregate (where the first two are named db_blks_read/db_blks_hit); total_blks_dirtied counts only the pages dirtied by this vacuum. --- doc/src/sgml/system-views.sgml | 96 ++++++++++++++++++++++ src/backend/access/heap/vacuumlazy.c | 23 +++++- src/backend/catalog/system_views.sql | 12 +++ src/backend/utils/activity/pgstat_vacuum.c | 5 ++ src/backend/utils/adt/pgstatfuncs.c | 20 ++++- src/include/catalog/pg_proc.dat | 18 ++-- src/include/pgstat.h | 6 ++ src/test/regress/expected/rules.out | 18 +++- src/test/regress/expected/vacuum_stats.out | 42 ++++++++-- src/test/regress/sql/vacuum_stats.sql | 26 +++++- 10 files changed, 240 insertions(+), 26 deletions(-) diff --git a/doc/src/sgml/system-views.sgml b/doc/src/sgml/system-views.sgml index 1be54673bf..f37a3b64c1 100644 --- a/doc/src/sgml/system-views.sgml +++ b/doc/src/sgml/system-views.sgml @@ -5916,6 +5916,38 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx Number of heap pages newly marked both all-visible and all-frozen in the visibility map by the vacuum. + + + total_blks_read bigint + + + Number of shared buffer blocks missed (read from disk) by the vacuum. + + + + + total_blks_hit bigint + + + Number of shared buffer blocks found in the buffer cache (hits) by the vacuum. + + + + + total_blks_dirtied bigint + + + Number of shared buffer blocks dirtied by the vacuum. + + + + + total_blks_written bigint + + + Number of shared buffer blocks written out by the vacuum. + + wraparound_failsafe integer @@ -6039,6 +6071,38 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx Number of index entries removed by the vacuum. + + + total_blks_read bigint + + + Number of shared buffer blocks read while vacuuming the index. + + + + + total_blks_hit bigint + + + Number of shared buffer block hits while vacuuming the index. + + + + + total_blks_dirtied bigint + + + Number of shared buffer blocks dirtied while vacuuming the index. + + + + + total_blks_written bigint + + + Number of shared buffer blocks written out while vacuuming the index. + + wal_records bigint @@ -6121,6 +6185,38 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx Number of vacuum operations in this database that failed with an error. + + + db_blks_read bigint + + + Number of shared buffer blocks read by vacuum operations in this database. + + + + + db_blks_hit bigint + + + Number of shared buffer block hits by vacuum operations in this database. + + + + + total_blks_dirtied bigint + + + Number of shared buffer blocks dirtied by vacuum operations in this database. + + + + + total_blks_written bigint + + + Number of shared buffer blocks written out by vacuum operations in this database. + + wraparound_failsafe integer diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c index 46b7418136..1d6db2a91d 100644 --- a/src/backend/access/heap/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -518,6 +518,7 @@ extvac_stats_start(Relation rel, LVExtStatCounters * counters) memset(counters, 0, sizeof(LVExtStatCounters)); counters->walusage = pgWalUsage; + counters->bufusage = pgBufferUsage; } /* ---------- @@ -531,19 +532,27 @@ extvac_stats_end(Relation rel, LVExtStatCounters * counters, PgStat_CommonCounts * report) { WalUsage walusage; + BufferUsage bufusage; if (!pgstat_track_vacuum_statistics) return; memset(report, 0, sizeof(PgStat_CommonCounts)); - /* Calculate diffs of global stat parameters on WAL usage. */ + /* Calculate diffs of global stat parameters on WAL and buffer usage. */ memset(&walusage, 0, sizeof(WalUsage)); WalUsageAccumDiff(&walusage, &pgWalUsage, &counters->walusage); + memset(&bufusage, 0, sizeof(BufferUsage)); + BufferUsageAccumDiff(&bufusage, &pgBufferUsage, &counters->bufusage); + /* * Fill additional statistics on a vacuum processing operation. */ + 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->wal_records += walusage.wal_records; report->wal_fpi += walusage.wal_fpi; report->wal_bytes += walusage.wal_bytes; @@ -634,6 +643,10 @@ accumulate_heap_vacuum_statistics(LVRelState *vacrel, PgStat_VacuumRelationCount extVacStats->table.missed_dead_pages = vacrel->missed_dead_pages; extVacStats->common.wraparound_failsafe_count = vacrel->wraparound_failsafe; + extVacStats->common.total_blks_dirtied -= vacrel->extVacReportIdx.common.total_blks_dirtied; + extVacStats->common.total_blks_hit -= vacrel->extVacReportIdx.common.total_blks_hit; + extVacStats->common.total_blks_read -= vacrel->extVacReportIdx.common.total_blks_read; + extVacStats->common.total_blks_written -= vacrel->extVacReportIdx.common.total_blks_written; extVacStats->common.wal_bytes -= vacrel->extVacReportIdx.common.wal_bytes; extVacStats->common.wal_fpi -= vacrel->extVacReportIdx.common.wal_fpi; extVacStats->common.wal_records -= vacrel->extVacReportIdx.common.wal_records; @@ -643,6 +656,10 @@ static void accumulate_idxs_vacuum_statistics(LVRelState *vacrel, PgStat_VacuumRelationCounts * extVacIdxStats) { /* Fill heap-specific extended stats fields */ + vacrel->extVacReportIdx.common.total_blks_dirtied += extVacIdxStats->common.total_blks_dirtied; + vacrel->extVacReportIdx.common.total_blks_hit += extVacIdxStats->common.total_blks_hit; + vacrel->extVacReportIdx.common.total_blks_read += extVacIdxStats->common.total_blks_read; + vacrel->extVacReportIdx.common.total_blks_written += extVacIdxStats->common.total_blks_written; vacrel->extVacReportIdx.common.wal_bytes += extVacIdxStats->common.wal_bytes; vacrel->extVacReportIdx.common.wal_fpi += extVacIdxStats->common.wal_fpi; vacrel->extVacReportIdx.common.wal_records += extVacIdxStats->common.wal_records; @@ -664,6 +681,10 @@ extvac_accumulate_idx_report(PgStat_VacuumRelationCounts * dst, { dst->type = PGSTAT_EXTVAC_INDEX; + dst->common.total_blks_read += src->common.total_blks_read; + dst->common.total_blks_hit += src->common.total_blks_hit; + dst->common.total_blks_dirtied += src->common.total_blks_dirtied; + dst->common.total_blks_written += src->common.total_blks_written; dst->common.wal_records += src->common.wal_records; dst->common.wal_fpi += src->common.wal_fpi; dst->common.wal_bytes += src->common.wal_bytes; diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index a7ac037bc3..1ee74f9273 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -1576,6 +1576,10 @@ CREATE VIEW pg_stat_vacuum_tables AS S.vm_new_frozen_pages AS vm_new_frozen_pages, S.vm_new_visible_pages AS vm_new_visible_pages, S.vm_new_visible_frozen_pages AS vm_new_visible_frozen_pages, + S.total_blks_read AS total_blks_read, + S.total_blks_hit AS total_blks_hit, + S.total_blks_dirtied AS total_blks_dirtied, + S.total_blks_written AS total_blks_written, S.wraparound_failsafe AS wraparound_failsafe, S.wal_records AS wal_records, S.wal_fpi AS wal_fpi, @@ -1597,6 +1601,10 @@ CREATE VIEW pg_stat_vacuum_indexes AS S.pages_deleted AS pages_deleted, S.tuples_deleted AS tuples_deleted, + S.total_blks_read AS total_blks_read, + S.total_blks_hit AS total_blks_hit, + S.total_blks_dirtied AS total_blks_dirtied, + S.total_blks_written AS total_blks_written, S.wal_records AS wal_records, S.wal_fpi AS wal_fpi, S.wal_bytes AS wal_bytes @@ -1615,6 +1623,10 @@ CREATE VIEW pg_stat_vacuum_database AS S.errors AS errors, + S.db_blks_read AS db_blks_read, + S.db_blks_hit AS db_blks_hit, + S.total_blks_dirtied AS total_blks_dirtied, + S.total_blks_written AS total_blks_written, S.wraparound_failsafe AS wraparound_failsafe, S.wal_records AS wal_records, S.wal_fpi AS wal_fpi, diff --git a/src/backend/utils/activity/pgstat_vacuum.c b/src/backend/utils/activity/pgstat_vacuum.c index ec3d50c59c..2bb44da510 100644 --- a/src/backend/utils/activity/pgstat_vacuum.c +++ b/src/backend/utils/activity/pgstat_vacuum.c @@ -38,6 +38,11 @@ bool pgstat_track_vacuum_statistics_for_relations = false; static void pgstat_accumulate_common(PgStat_CommonCounts *dst, const PgStat_CommonCounts *src) { + ACCUMULATE_FIELD(total_blks_read); + ACCUMULATE_FIELD(total_blks_hit); + ACCUMULATE_FIELD(total_blks_dirtied); + ACCUMULATE_FIELD(total_blks_written); + ACCUMULATE_FIELD(wal_records); ACCUMULATE_FIELD(wal_fpi); ACCUMULATE_FIELD(wal_bytes); diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c index 694fd220b0..eeca140354 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -2374,7 +2374,7 @@ pg_stat_have_stats(PG_FUNCTION_ARGS) Datum pg_stat_get_vacuum_tables(PG_FUNCTION_ARGS) { -#define PG_STAT_GET_VACUUM_TABLES_STATS_COLS 15 +#define PG_STAT_GET_VACUUM_TABLES_STATS_COLS 19 Oid relid = PG_GETARG_OID(0); PgStat_VacuumRelationCounts *extvacuum; @@ -2411,6 +2411,10 @@ pg_stat_get_vacuum_tables(PG_FUNCTION_ARGS) values[i++] = Int64GetDatum(extvacuum->table.vm_new_frozen_pages); values[i++] = Int64GetDatum(extvacuum->table.vm_new_visible_pages); values[i++] = Int64GetDatum(extvacuum->table.vm_new_visible_frozen_pages); + values[i++] = Int64GetDatum(extvacuum->common.total_blks_read); + values[i++] = Int64GetDatum(extvacuum->common.total_blks_hit); + values[i++] = Int64GetDatum(extvacuum->common.total_blks_dirtied); + values[i++] = Int64GetDatum(extvacuum->common.total_blks_written); values[i++] = Int32GetDatum(extvacuum->common.wraparound_failsafe_count); values[i++] = Int64GetDatum(extvacuum->common.wal_records); values[i++] = Int64GetDatum(extvacuum->common.wal_fpi); @@ -2432,7 +2436,7 @@ pg_stat_get_vacuum_tables(PG_FUNCTION_ARGS) Datum pg_stat_get_vacuum_indexes(PG_FUNCTION_ARGS) { -#define PG_STAT_GET_VACUUM_INDEX_STATS_COLS 6 +#define PG_STAT_GET_VACUUM_INDEX_STATS_COLS 10 Oid relid = PG_GETARG_OID(0); PgStat_VacuumRelationCounts *extvacuum; @@ -2461,6 +2465,11 @@ pg_stat_get_vacuum_indexes(PG_FUNCTION_ARGS) values[i++] = Int64GetDatum(extvacuum->index.pages_deleted); values[i++] = Int64GetDatum(extvacuum->common.tuples_deleted); + values[i++] = Int64GetDatum(extvacuum->common.total_blks_read); + values[i++] = Int64GetDatum(extvacuum->common.total_blks_hit); + values[i++] = Int64GetDatum(extvacuum->common.total_blks_dirtied); + values[i++] = Int64GetDatum(extvacuum->common.total_blks_written); + values[i++] = Int64GetDatum(extvacuum->common.wal_records); values[i++] = Int64GetDatum(extvacuum->common.wal_fpi); snprintf(buf, sizeof buf, UINT64_FORMAT, extvacuum->common.wal_bytes); @@ -2480,7 +2489,7 @@ pg_stat_get_vacuum_indexes(PG_FUNCTION_ARGS) Datum pg_stat_get_vacuum_database(PG_FUNCTION_ARGS) { -#define PG_STAT_GET_VACUUM_DATABASE_STATS_COLS 7 +#define PG_STAT_GET_VACUUM_DATABASE_STATS_COLS 11 Oid dbid = PG_GETARG_OID(0); PgStat_VacuumDBCounts *extvacuum; @@ -2504,6 +2513,11 @@ pg_stat_get_vacuum_database(PG_FUNCTION_ARGS) values[i++] = Int32GetDatum(extvacuum->errors); + values[i++] = Int64GetDatum(extvacuum->common.total_blks_read); + values[i++] = Int64GetDatum(extvacuum->common.total_blks_hit); + values[i++] = Int64GetDatum(extvacuum->common.total_blks_dirtied); + values[i++] = Int64GetDatum(extvacuum->common.total_blks_written); + values[i++] = Int32GetDatum(extvacuum->common.wraparound_failsafe_count); values[i++] = Int64GetDatum(extvacuum->common.wal_records); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index d2fb1b4ec0..718ba80a3a 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -12643,9 +12643,9 @@ proname => 'pg_stat_get_vacuum_tables', prorows => 1000, provolatile => 's', prorettype => 'record', proisstrict => 'f', proretset => 't', proargtypes => 'oid', - proallargtypes => '{oid,oid,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int4,int8,int8,numeric}', - proargmodes => '{i,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}', - proargnames => '{reloid,relid,pages_scanned,pages_removed,tuples_deleted,tuples_frozen,recently_dead_tuples,missed_dead_pages,missed_dead_tuples,vm_new_frozen_pages,vm_new_visible_pages,vm_new_visible_frozen_pages,wraparound_failsafe,wal_records,wal_fpi,wal_bytes}', + proallargtypes => '{oid,oid,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int4,int8,int8,numeric}', + proargmodes => '{i,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}', + proargnames => '{reloid,relid,pages_scanned,pages_removed,tuples_deleted,tuples_frozen,recently_dead_tuples,missed_dead_pages,missed_dead_tuples,vm_new_frozen_pages,vm_new_visible_pages,vm_new_visible_frozen_pages,total_blks_read,total_blks_hit,total_blks_dirtied,total_blks_written,wraparound_failsafe,wal_records,wal_fpi,wal_bytes}', prosrc => 'pg_stat_get_vacuum_tables' } # oid8 related functions @@ -12718,17 +12718,17 @@ proname => 'pg_stat_get_vacuum_indexes', prorows => 1000, provolatile => 's', prorettype => 'record', proisstrict => 'f', proretset => 't', proargtypes => 'oid', - proallargtypes => '{oid,oid,int8,int8,int8,int8,numeric}', - proargmodes => '{i,o,o,o,o,o,o}', - proargnames => '{reloid,relid,pages_deleted,tuples_deleted,wal_records,wal_fpi,wal_bytes}', + proallargtypes => '{oid,oid,int8,int8,int8,int8,int8,int8,int8,int8,numeric}', + proargmodes => '{i,o,o,o,o,o,o,o,o,o,o}', + proargnames => '{reloid,relid,pages_deleted,tuples_deleted,total_blks_read,total_blks_hit,total_blks_dirtied,total_blks_written,wal_records,wal_fpi,wal_bytes}', prosrc => 'pg_stat_get_vacuum_indexes' }, { oid => '8005', descr => 'pg_stat_get_vacuum_database returns vacuum stats values for database', proname => 'pg_stat_get_vacuum_database', prorows => 1000, provolatile => 's', prorettype => 'record', proisstrict => 'f', proretset => 't', proargtypes => 'oid', - proallargtypes => '{oid,oid,int4,int4,int8,int8,numeric,int4}', - proargmodes => '{i,o,o,o,o,o,o,o}', - proargnames => '{dbid,dboid,errors,wraparound_failsafe,wal_records,wal_fpi,wal_bytes,interrupts_count}', + proallargtypes => '{oid,oid,int4,int8,int8,int8,int8,int4,int8,int8,numeric,int4}', + proargmodes => '{i,o,o,o,o,o,o,o,o,o,o,o}', + proargnames => '{dbid,dboid,errors,db_blks_read,db_blks_hit,total_blks_dirtied,total_blks_written,wraparound_failsafe,wal_records,wal_fpi,wal_bytes,interrupts_count}', prosrc => 'pg_stat_get_vacuum_database' }, ] diff --git a/src/include/pgstat.h b/src/include/pgstat.h index bcc84dbd41..92f8b9b8ec 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -175,6 +175,12 @@ typedef struct PgStat_TableCounts typedef struct PgStat_CommonCounts { + /* blocks */ + int64 total_blks_read; + int64 total_blks_hit; + int64 total_blks_dirtied; + int64 total_blks_written; + /* WAL */ int64 wal_records; int64 wal_fpi; diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index 27a17ee0c2..2b879192aa 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -2424,13 +2424,17 @@ pg_stat_user_tables| SELECT relid, pg_stat_vacuum_database| SELECT d.oid AS dboid, d.datname AS dbname, s.errors, + s.db_blks_read, + s.db_blks_hit, + s.total_blks_dirtied, + s.total_blks_written, s.wraparound_failsafe, s.wal_records, s.wal_fpi, s.wal_bytes, s.interrupts_count FROM pg_database d, - LATERAL pg_stat_get_vacuum_database(d.oid) s(dboid, errors, wraparound_failsafe, wal_records, wal_fpi, wal_bytes, interrupts_count); + LATERAL pg_stat_get_vacuum_database(d.oid) s(dboid, errors, db_blks_read, db_blks_hit, total_blks_dirtied, total_blks_written, wraparound_failsafe, wal_records, wal_fpi, wal_bytes, interrupts_count); pg_stat_vacuum_indexes| SELECT c.oid AS relid, i.oid AS indexrelid, n.nspname AS schemaname, @@ -2438,6 +2442,10 @@ pg_stat_vacuum_indexes| SELECT c.oid AS relid, i.relname AS indexrelname, s.pages_deleted, s.tuples_deleted, + s.total_blks_read, + s.total_blks_hit, + s.total_blks_dirtied, + s.total_blks_written, s.wal_records, s.wal_fpi, s.wal_bytes @@ -2445,7 +2453,7 @@ pg_stat_vacuum_indexes| SELECT c.oid AS relid, JOIN pg_index x ON ((c.oid = x.indrelid))) JOIN pg_class i ON ((i.oid = x.indexrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))), - LATERAL pg_stat_get_vacuum_indexes(i.oid) s(relid, pages_deleted, tuples_deleted, wal_records, wal_fpi, wal_bytes) + LATERAL pg_stat_get_vacuum_indexes(i.oid) s(relid, pages_deleted, tuples_deleted, total_blks_read, total_blks_hit, total_blks_dirtied, total_blks_written, wal_records, wal_fpi, wal_bytes) WHERE (c.relkind = ANY (ARRAY['r'::"char", 't'::"char", 'm'::"char"])); pg_stat_vacuum_tables| SELECT n.nspname AS schemaname, c.relname, @@ -2460,13 +2468,17 @@ pg_stat_vacuum_tables| SELECT n.nspname AS schemaname, s.vm_new_frozen_pages, s.vm_new_visible_pages, s.vm_new_visible_frozen_pages, + s.total_blks_read, + s.total_blks_hit, + s.total_blks_dirtied, + s.total_blks_written, s.wraparound_failsafe, s.wal_records, s.wal_fpi, s.wal_bytes FROM (pg_class c JOIN pg_namespace n ON ((n.oid = c.relnamespace))), - LATERAL pg_stat_get_vacuum_tables(c.oid) s(relid, pages_scanned, pages_removed, tuples_deleted, tuples_frozen, recently_dead_tuples, missed_dead_pages, missed_dead_tuples, vm_new_frozen_pages, vm_new_visible_pages, vm_new_visible_frozen_pages, wraparound_failsafe, wal_records, wal_fpi, wal_bytes) + LATERAL pg_stat_get_vacuum_tables(c.oid) s(relid, pages_scanned, pages_removed, tuples_deleted, tuples_frozen, recently_dead_tuples, missed_dead_pages, missed_dead_tuples, vm_new_frozen_pages, vm_new_visible_pages, vm_new_visible_frozen_pages, total_blks_read, total_blks_hit, total_blks_dirtied, total_blks_written, wraparound_failsafe, wal_records, wal_fpi, wal_bytes) WHERE (c.relkind = ANY (ARRAY['r'::"char", 't'::"char", 'm'::"char"])); pg_stat_wal| SELECT wal_records, wal_fpi, diff --git a/src/test/regress/expected/vacuum_stats.out b/src/test/regress/expected/vacuum_stats.out index c996699804..87f49cb76c 100644 --- a/src/test/regress/expected/vacuum_stats.out +++ b/src/test/regress/expected/vacuum_stats.out @@ -123,6 +123,21 @@ SELECT vm_new_visible_pages > 0 AS vm_new_visible_pages, (1 row) DROP TABLE vacstat_frz; +-- total buffer access counters. The vacuum always touches the table's pages +-- through the buffer cache (total_blks_hit > 0) and dirties some of them while +-- removing dead tuples (total_blks_dirtied > 0). total_blks_read and +-- total_blks_written depend on the buffer-cache and checkpoint state at run +-- time, so they are only checked for being non-negative. +SELECT total_blks_read >= 0 AS total_blks_read, + total_blks_hit > 0 AS total_blks_hit, + total_blks_dirtied > 0 AS total_blks_dirtied, + total_blks_written >= 0 AS total_blks_written + FROM pg_stat_vacuum_tables WHERE relname = 'vacstat_t'; + total_blks_read | total_blks_hit | total_blks_dirtied | total_blks_written +-----------------+----------------+--------------------+-------------------- + t | t | t | t +(1 row) + -- WAL metrics. A vacuum that removes tuples always emits WAL -- (wal_records > 0, wal_bytes > 0). wal_fpi depends on whether a checkpoint -- happened recently, so it is only checked for being non-negative here; the @@ -174,17 +189,23 @@ SELECT wraparound_failsafe = 0 AS wraparound_failsafe -- per-index view: the primary key index is processed by the same VACUUM. -- No btree leaf empties out (interleaved deletions), so pages_deleted = 0, --- while every index entry for a removed heap tuple is deleted. +-- while every index entry for a removed heap tuple is deleted. The index is +-- read through the buffer cache (total_blks_hit > 0); the read/written/dirtied +-- counters depend on run-time cache state. SELECT indexrelname, pages_deleted = 0 AS pages_deleted, tuples_deleted = 500 AS tuples_deleted, + total_blks_read >= 0 AS total_blks_read, + total_blks_hit > 0 AS total_blks_hit, + total_blks_dirtied >= 0 AS total_blks_dirtied, + total_blks_written >= 0 AS total_blks_written, wal_records > 0 AS wal_records, wal_fpi >= 0 AS wal_fpi, wal_bytes > 0 AS wal_bytes FROM pg_stat_vacuum_indexes WHERE relname = 'vacstat_t' ORDER BY indexrelname; - indexrelname | pages_deleted | tuples_deleted | wal_records | wal_fpi | wal_bytes -----------------+---------------+----------------+-------------+---------+----------- - vacstat_t_pkey | t | t | t | t | t + indexrelname | pages_deleted | tuples_deleted | total_blks_read | total_blks_hit | total_blks_dirtied | total_blks_written | wal_records | wal_fpi | wal_bytes +----------------+---------------+----------------+-----------------+----------------+--------------------+--------------------+-------------+---------+----------- + vacstat_t_pkey | t | t | t | t | t | t | t | t | t (1 row) -- index page-deletion path: deleting a contiguous key range empties whole @@ -219,16 +240,21 @@ SELECT indexrelname, DROP TABLE vacstat_idxdel; -- per-database aggregate view: no vacuum errors occurred in this database, and --- the vacuums in this database emit WAL (wal_records > 0). +-- the vacuums in this database touched pages through the buffer cache +-- (db_blks_hit > 0) and emit WAL (wal_records > 0). SELECT errors = 0 AS errors, + db_blks_read >= 0 AS db_blks_read, + db_blks_hit > 0 AS db_blks_hit, + total_blks_dirtied >= 0 AS total_blks_dirtied, + total_blks_written >= 0 AS total_blks_written, wraparound_failsafe = 0 AS wraparound_failsafe, wal_records > 0 AS wal_records, wal_fpi >= 0 AS wal_fpi, wal_bytes > 0 AS wal_bytes FROM pg_stat_vacuum_database WHERE dbname = current_database(); - errors | wraparound_failsafe | wal_records | wal_fpi | wal_bytes ---------+---------------------+-------------+---------+----------- - t | t | t | t | t + errors | db_blks_read | db_blks_hit | total_blks_dirtied | total_blks_written | wraparound_failsafe | wal_records | wal_fpi | wal_bytes +--------+--------------+-------------+--------------------+--------------------+---------------------+-------------+---------+----------- + t | t | t | t | t | t | t | t | t (1 row) -- parallel index vacuum: index statistics must be captured for indexes diff --git a/src/test/regress/sql/vacuum_stats.sql b/src/test/regress/sql/vacuum_stats.sql index f106b7c37b..6e364d183c 100644 --- a/src/test/regress/sql/vacuum_stats.sql +++ b/src/test/regress/sql/vacuum_stats.sql @@ -81,6 +81,17 @@ SELECT vm_new_visible_pages > 0 AS vm_new_visible_pages, FROM pg_stat_vacuum_tables WHERE relname = 'vacstat_frz'; DROP TABLE vacstat_frz; +-- total buffer access counters. The vacuum always touches the table's pages +-- through the buffer cache (total_blks_hit > 0) and dirties some of them while +-- removing dead tuples (total_blks_dirtied > 0). total_blks_read and +-- total_blks_written depend on the buffer-cache and checkpoint state at run +-- time, so they are only checked for being non-negative. +SELECT total_blks_read >= 0 AS total_blks_read, + total_blks_hit > 0 AS total_blks_hit, + total_blks_dirtied > 0 AS total_blks_dirtied, + total_blks_written >= 0 AS total_blks_written + FROM pg_stat_vacuum_tables WHERE relname = 'vacstat_t'; + -- WAL metrics. A vacuum that removes tuples always emits WAL -- (wal_records > 0, wal_bytes > 0). wal_fpi depends on whether a checkpoint -- happened recently, so it is only checked for being non-negative here; the @@ -115,10 +126,16 @@ SELECT wraparound_failsafe = 0 AS wraparound_failsafe -- per-index view: the primary key index is processed by the same VACUUM. -- No btree leaf empties out (interleaved deletions), so pages_deleted = 0, --- while every index entry for a removed heap tuple is deleted. +-- while every index entry for a removed heap tuple is deleted. The index is +-- read through the buffer cache (total_blks_hit > 0); the read/written/dirtied +-- counters depend on run-time cache state. SELECT indexrelname, pages_deleted = 0 AS pages_deleted, tuples_deleted = 500 AS tuples_deleted, + total_blks_read >= 0 AS total_blks_read, + total_blks_hit > 0 AS total_blks_hit, + total_blks_dirtied >= 0 AS total_blks_dirtied, + total_blks_written >= 0 AS total_blks_written, wal_records > 0 AS wal_records, wal_fpi >= 0 AS wal_fpi, wal_bytes > 0 AS wal_bytes @@ -142,8 +159,13 @@ SELECT indexrelname, DROP TABLE vacstat_idxdel; -- per-database aggregate view: no vacuum errors occurred in this database, and --- the vacuums in this database emit WAL (wal_records > 0). +-- the vacuums in this database touched pages through the buffer cache +-- (db_blks_hit > 0) and emit WAL (wal_records > 0). SELECT errors = 0 AS errors, + db_blks_read >= 0 AS db_blks_read, + db_blks_hit > 0 AS db_blks_hit, + total_blks_dirtied >= 0 AS total_blks_dirtied, + total_blks_written >= 0 AS total_blks_written, wraparound_failsafe = 0 AS wraparound_failsafe, wal_records > 0 AS wal_records, wal_fpi >= 0 AS wal_fpi, -- 2.39.5 (Apple Git-154)