v24-0004-Vacuum-statistics-have-been-separated-from-regular.patch
text/x-patch
Filename: v24-0004-Vacuum-statistics-have-been-separated-from-regular.patch
Type: text/x-patch
Part: 3
Message:
Re: Vacuum statistics
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v24-0004
Subject: Vacuum statistics have been separated from regular relation and database statistics to reduce memory usage. Dedicated PGSTAT_KIND_VACUUM_RELATION and PGSTAT_KIND_VACUUM_DB entries were added to the stats collector to efficiently allocate memory for vacuum-specific metrics, which require significantly more space per relation.
| File | + | − |
|---|---|---|
| src/backend/access/heap/vacuumlazy.c | 102 | 94 |
| src/backend/catalog/heap.c | 1 | 0 |
| src/backend/catalog/index.c | 1 | 0 |
| src/backend/catalog/system_views.sql | 91 | 87 |
| src/backend/commands/dbcommands.c | 1 | 0 |
| src/backend/commands/vacuumparallel.c | 5 | 9 |
| src/backend/utils/activity/Makefile | 1 | 0 |
| src/backend/utils/activity/pgstat.c | 28 | 0 |
| src/backend/utils/activity/pgstat_database.c | 9 | 1 |
| src/backend/utils/activity/pgstat_relation.c | 7 | 104 |
| src/backend/utils/activity/pgstat_vacuum.c | 215 | 0 |
| src/backend/utils/adt/pgstatfuncs.c | 73 | 212 |
| src/include/commands/vacuum.h | 1 | 1 |
| src/include/pgstat.h | 112 | 88 |
| src/include/utils/pgstat_internal.h | 15 | 0 |
| src/include/utils/pgstat_kind.h | 3 | 1 |
| src/test/regress/expected/rules.out | 75 | 71 |
| src/test/regress/expected/vacuum_index_statistics.out | 41 | 41 |
| src/test/regress/sql/vacuum_index_statistics.sql | 24 | 24 |
From c7acebdd3a7b21b615c087aef9c6acd30e49c4a4 Mon Sep 17 00:00:00 2001
From: Alena Rybakina <a.rybakina@postgrespro.ru>
Date: Mon, 1 Sep 2025 21:44:59 +0300
Subject: [PATCH 4/5] Vacuum statistics have been separated from regular
relation and database statistics to reduce memory usage. Dedicated
PGSTAT_KIND_VACUUM_RELATION and PGSTAT_KIND_VACUUM_DB entries were added to
the stats collector to efficiently allocate memory for vacuum-specific
metrics, which require significantly more space per relation.
---
src/backend/access/heap/vacuumlazy.c | 196 ++++++------
src/backend/catalog/heap.c | 1 +
src/backend/catalog/index.c | 1 +
src/backend/catalog/system_views.sql | 178 +++++------
src/backend/commands/dbcommands.c | 1 +
src/backend/commands/vacuumparallel.c | 14 +-
src/backend/utils/activity/Makefile | 1 +
src/backend/utils/activity/pgstat.c | 28 ++
src/backend/utils/activity/pgstat_database.c | 10 +-
src/backend/utils/activity/pgstat_relation.c | 111 +------
src/backend/utils/activity/pgstat_vacuum.c | 215 +++++++++++++
src/backend/utils/adt/pgstatfuncs.c | 285 +++++-------------
src/include/commands/vacuum.h | 2 +-
src/include/pgstat.h | 200 ++++++------
src/include/utils/pgstat_internal.h | 15 +
src/include/utils/pgstat_kind.h | 4 +-
src/test/regress/expected/rules.out | 146 ++++-----
.../expected/vacuum_index_statistics.out | 82 ++---
.../regress/sql/vacuum_index_statistics.sql | 48 +--
19 files changed, 805 insertions(+), 733 deletions(-)
create mode 100644 src/backend/utils/activity/pgstat_vacuum.c
diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 3c3e23cd943..606a03827c7 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -412,7 +412,7 @@ typedef struct LVRelState
int32 wraparound_failsafe_count; /* number of emergency vacuums to prevent anti-wraparound shutdown */
- ExtVacReport extVacReportIdx;
+ PgStat_VacuumRelationCounts extVacReportIdx;
} LVRelState;
@@ -524,7 +524,7 @@ extvac_stats_start(Relation rel, LVExtStatCounters *counters)
*/
static void
extvac_stats_end(Relation rel, LVExtStatCounters *counters,
- ExtVacReport *report)
+ PgStat_CommonCounts *report)
{
WalUsage walusage;
BufferUsage bufusage;
@@ -585,6 +585,8 @@ extvac_stats_start_idx(Relation rel, IndexBulkDeleteResult *stats,
if(!pgstat_track_vacuum_statistics)
return;
+ memset(&counters->common, 0, sizeof(LVExtStatCounters));
+
/* Set initial values for common heap and index statistics*/
extvac_stats_start(rel, &counters->common);
counters->pages_deleted = counters->tuples_removed = 0;
@@ -602,11 +604,13 @@ extvac_stats_start_idx(Relation rel, IndexBulkDeleteResult *stats,
void
extvac_stats_end_idx(Relation rel, IndexBulkDeleteResult *stats,
- LVExtStatCountersIdx *counters, ExtVacReport *report)
+ LVExtStatCountersIdx *counters, PgStat_VacuumRelationCounts *report)
{
- memset(report, 0, sizeof(ExtVacReport));
+ if(!pgstat_track_vacuum_statistics)
+ return;
+
+ extvac_stats_end(rel, &counters->common, &report->common);
- extvac_stats_end(rel, &counters->common, report);
report->type = PGSTAT_EXTVAC_INDEX;
if (stats != NULL)
@@ -617,7 +621,7 @@ extvac_stats_end_idx(Relation rel, IndexBulkDeleteResult *stats,
*/
/* Fill index-specific extended stats fields */
- report->tuples_deleted =
+ report->common.tuples_deleted =
stats->tuples_removed - counters->tuples_removed;
report->index.pages_deleted =
stats->pages_deleted - counters->pages_deleted;
@@ -640,7 +644,7 @@ extvac_stats_end_idx(Relation rel, IndexBulkDeleteResult *stats,
* procudure.
*/
static void
-accumulate_heap_vacuum_statistics(LVRelState *vacrel, ExtVacReport *extVacStats)
+accumulate_heap_vacuum_statistics(LVRelState *vacrel, PgStat_VacuumRelationCounts *extVacStats)
{
if (!pgstat_track_vacuum_statistics)
return;
@@ -652,49 +656,49 @@ accumulate_heap_vacuum_statistics(LVRelState *vacrel, ExtVacReport *extVacStats)
extVacStats->table.vm_new_frozen_pages = vacrel->vm_new_frozen_pages;
extVacStats->table.vm_new_visible_pages = vacrel->vm_new_visible_pages;
extVacStats->table.vm_new_visible_frozen_pages = vacrel->vm_new_visible_frozen_pages;
- extVacStats->tuples_deleted = vacrel->tuples_deleted;
+ extVacStats->common.tuples_deleted = vacrel->tuples_deleted;
extVacStats->table.tuples_frozen = vacrel->tuples_frozen;
extVacStats->table.recently_dead_tuples = vacrel->recently_dead_tuples;
extVacStats->table.recently_dead_tuples = vacrel->recently_dead_tuples;
extVacStats->table.missed_dead_tuples = vacrel->missed_dead_tuples;
extVacStats->table.missed_dead_pages = vacrel->missed_dead_pages;
extVacStats->table.index_vacuum_count = vacrel->num_index_scans;
- extVacStats->wraparound_failsafe_count = vacrel->wraparound_failsafe_count;
+ extVacStats->common.wraparound_failsafe_count = vacrel->wraparound_failsafe_count;
- extVacStats->blk_read_time -= vacrel->extVacReportIdx.blk_read_time;
- extVacStats->blk_write_time -= vacrel->extVacReportIdx.blk_write_time;
- extVacStats->total_blks_dirtied -= vacrel->extVacReportIdx.total_blks_dirtied;
- extVacStats->total_blks_hit -= vacrel->extVacReportIdx.total_blks_hit;
- extVacStats->total_blks_read -= vacrel->extVacReportIdx.total_blks_read;
- extVacStats->total_blks_written -= vacrel->extVacReportIdx.total_blks_written;
- extVacStats->wal_bytes -= vacrel->extVacReportIdx.wal_bytes;
- extVacStats->wal_fpi -= vacrel->extVacReportIdx.wal_fpi;
- extVacStats->wal_records -= vacrel->extVacReportIdx.wal_records;
+ extVacStats->common.blk_read_time -= vacrel->extVacReportIdx.common.blk_read_time;
+ extVacStats->common.blk_write_time -= vacrel->extVacReportIdx.common.blk_write_time;
+ 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;
- extVacStats->total_time -= vacrel->extVacReportIdx.total_time;
- extVacStats->delay_time -= vacrel->extVacReportIdx.delay_time;
+ extVacStats->common.total_time -= vacrel->extVacReportIdx.common.total_time;
+ extVacStats->common.delay_time -= vacrel->extVacReportIdx.common.delay_time;
}
static void
-accumulate_idxs_vacuum_statistics(LVRelState *vacrel, ExtVacReport *extVacIdxStats)
+accumulate_idxs_vacuum_statistics(LVRelState *vacrel, PgStat_VacuumRelationCounts *extVacIdxStats)
{
if (!pgstat_track_vacuum_statistics)
return;
/* Fill heap-specific extended stats fields */
- vacrel->extVacReportIdx.blk_read_time += extVacIdxStats->blk_read_time;
- vacrel->extVacReportIdx.blk_write_time += extVacIdxStats->blk_write_time;
- vacrel->extVacReportIdx.total_blks_dirtied += extVacIdxStats->total_blks_dirtied;
- vacrel->extVacReportIdx.total_blks_hit += extVacIdxStats->total_blks_hit;
- vacrel->extVacReportIdx.total_blks_read += extVacIdxStats->total_blks_read;
- vacrel->extVacReportIdx.total_blks_written += extVacIdxStats->total_blks_written;
- vacrel->extVacReportIdx.wal_bytes += extVacIdxStats->wal_bytes;
- vacrel->extVacReportIdx.wal_fpi += extVacIdxStats->wal_fpi;
- vacrel->extVacReportIdx.wal_records += extVacIdxStats->wal_records;
- vacrel->extVacReportIdx.delay_time += extVacIdxStats->delay_time;
-
- vacrel->extVacReportIdx.total_time += extVacIdxStats->total_time;
+ 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.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;
+ vacrel->extVacReportIdx.common.delay_time += extVacIdxStats->common.delay_time;
+
+ vacrel->extVacReportIdx.common.total_time += extVacIdxStats->common.total_time;
}
@@ -855,12 +859,10 @@ heap_vacuum_rel(Relation rel, const VacuumParams params,
ErrorContextCallback errcallback;
char **indnames = NULL;
LVExtStatCounters extVacCounters;
- ExtVacReport extVacReport;
- ExtVacReport allzero;
+ PgStat_VacuumRelationCounts extVacReport;
/* Initialize vacuum statistics */
- memset(&extVacReport, 0, sizeof(ExtVacReport));
- extVacReport = allzero;
+ memset(&extVacReport, 0, sizeof(PgStat_VacuumRelationCounts));
verbose = (params.options & VACOPT_VERBOSE) != 0;
instrument = (verbose || (AmAutoVacuumWorkerProcess() &&
@@ -906,7 +908,8 @@ heap_vacuum_rel(Relation rel, const VacuumParams params,
errcallback.previous = error_context_stack;
error_context_stack = &errcallback;
- memset(&vacrel->extVacReportIdx, 0, sizeof(ExtVacReport));
+ memset(&vacrel->extVacReportIdx, 0, sizeof(PgStat_VacuumRelationCounts));
+ memset(&extVacReport.common, 0, sizeof(PgStat_CommonCounts));
/* Set up high level stuff about rel and its indexes */
vacrel->rel = rel;
@@ -1158,7 +1161,7 @@ heap_vacuum_rel(Relation rel, const VacuumParams params,
&frozenxid_updated, &minmulti_updated, false);
/* Make generic extended vacuum stats report */
- extvac_stats_end(rel, &extVacCounters, &extVacReport);
+ extvac_stats_end(rel, &extVacCounters, &extVacReport.common);
/*
* Report results to the cumulative stats system, too.
@@ -1170,33 +1173,20 @@ heap_vacuum_rel(Relation rel, const VacuumParams params,
* soon in cases where the failsafe prevented significant amounts of heap
* vacuuming.
*/
- if(pgstat_track_vacuum_statistics)
- {
- /* Make generic extended vacuum stats report and
- * fill heap-specific extended stats fields.
- */
- extvac_stats_end(vacrel->rel, &extVacCounters, &extVacReport);
- accumulate_heap_vacuum_statistics(vacrel, &extVacReport);
- pgstat_report_vacuum(RelationGetRelid(rel),
- rel->rd_rel->relisshared,
- Max(vacrel->new_live_tuples, 0),
- vacrel->recently_dead_tuples +
- vacrel->missed_dead_tuples,
- starttime,
- &extVacReport);
+ /* Make generic extended vacuum stats report and
+ * fill heap-specific extended stats fields.
+ */
+ accumulate_heap_vacuum_statistics(vacrel, &extVacReport);
- }
- else
- {
- pgstat_report_vacuum(RelationGetRelid(rel),
+ pgstat_report_vacuum_extstats(vacrel->reloid, rel->rd_rel->relisshared, &extVacReport);
+
+ pgstat_report_vacuum(RelationGetRelid(rel),
rel->rd_rel->relisshared,
Max(vacrel->new_live_tuples, 0),
vacrel->recently_dead_tuples +
vacrel->missed_dead_tuples,
- starttime,
- NULL);
- }
+ starttime);
pgstat_progress_end_command();
@@ -2890,9 +2880,9 @@ lazy_vacuum_all_indexes(LVRelState *vacrel)
else
{
LVExtStatCounters counters;
- ExtVacReport extVacReport;
+ PgStat_VacuumRelationCounts extVacReport;
- memset(&extVacReport, 0, sizeof(ExtVacReport));
+ memset(&extVacReport.common, 0, sizeof(PgStat_CommonCounts));
extvac_stats_start(vacrel->rel, &counters);
@@ -2900,7 +2890,7 @@ lazy_vacuum_all_indexes(LVRelState *vacrel)
parallel_vacuum_bulkdel_all_indexes(vacrel->pvs, old_live_tuples,
vacrel->num_index_scans);
- extvac_stats_end(vacrel->rel, &counters, &extVacReport);
+ extvac_stats_end(vacrel->rel, &counters, &extVacReport.common);
accumulate_idxs_vacuum_statistics(vacrel, &extVacReport);
/*
@@ -3313,9 +3303,9 @@ lazy_cleanup_all_indexes(LVRelState *vacrel)
else
{
LVExtStatCounters counters;
- ExtVacReport extVacReport;
+ PgStat_VacuumRelationCounts extVacReport;
- memset(&extVacReport, 0, sizeof(ExtVacReport));
+ memset(&extVacReport.common, 0, sizeof(PgStat_CommonCounts));
extvac_stats_start(vacrel->rel, &counters);
@@ -3324,7 +3314,7 @@ lazy_cleanup_all_indexes(LVRelState *vacrel)
vacrel->num_index_scans,
estimated_count);
- extvac_stats_end(vacrel->rel, &counters, &extVacReport);
+ extvac_stats_end(vacrel->rel, &counters, &extVacReport.common);
accumulate_idxs_vacuum_statistics(vacrel, &extVacReport);
}
@@ -3352,7 +3342,10 @@ lazy_vacuum_one_index(Relation indrel, IndexBulkDeleteResult *istat,
IndexVacuumInfo ivinfo;
LVSavedErrInfo saved_err_info;
LVExtStatCountersIdx extVacCounters;
- ExtVacReport extVacReport;
+ PgStat_VacuumRelationCounts extVacReport;
+
+ memset(&extVacReport, 0, sizeof(PgStat_VacuumRelationCounts));
+ memset(&extVacReport.common, 0, sizeof(PgStat_CommonCounts));
/* Set initial statistics values to gather vacuum statistics for the index */
extvac_stats_start_idx(indrel, istat, &extVacCounters);
@@ -3383,18 +3376,13 @@ lazy_vacuum_one_index(Relation indrel, IndexBulkDeleteResult *istat,
istat = vac_bulkdel_one_index(&ivinfo, istat, vacrel->dead_items,
vacrel->dead_items_info);
- if(pgstat_track_vacuum_statistics)
- {
- /* Make extended vacuum stats report for index */
- extvac_stats_end_idx(indrel, istat, &extVacCounters, &extVacReport);
+ /* Make extended vacuum stats report for index */
+ extvac_stats_end_idx(indrel, istat, &extVacCounters, &extVacReport);
- if (!ParallelVacuumIsActive(vacrel))
- accumulate_idxs_vacuum_statistics(vacrel, &extVacReport);
+ if (!ParallelVacuumIsActive(vacrel))
+ accumulate_idxs_vacuum_statistics(vacrel, &extVacReport);
- pgstat_report_vacuum(RelationGetRelid(indrel),
- indrel->rd_rel->relisshared,
- 0, 0, 0, &extVacReport);
- }
+ pgstat_report_vacuum_extstats(vacrel->indoid, indrel->rd_rel->relisshared, &extVacReport);
/* Revert to the previous phase information for error traceback */
restore_vacuum_error_info(vacrel, &saved_err_info);
@@ -3421,7 +3409,10 @@ lazy_cleanup_one_index(Relation indrel, IndexBulkDeleteResult *istat,
IndexVacuumInfo ivinfo;
LVSavedErrInfo saved_err_info;
LVExtStatCountersIdx extVacCounters;
- ExtVacReport extVacReport;
+ PgStat_VacuumRelationCounts extVacReport;
+
+ memset(&extVacReport, 0, sizeof(PgStat_VacuumRelationCounts));
+ memset(&extVacReport.common, 0, sizeof(PgStat_CommonCounts));
/* Set initial statistics values to gather vacuum statistics for the index */
extvac_stats_start_idx(indrel, istat, &extVacCounters);
@@ -3451,17 +3442,13 @@ lazy_cleanup_one_index(Relation indrel, IndexBulkDeleteResult *istat,
istat = vac_cleanup_one_index(&ivinfo, istat);
- if(pgstat_track_vacuum_statistics)
- {
- /* Make extended vacuum stats report for index */
- extvac_stats_end_idx(indrel, istat, &extVacCounters, &extVacReport);
- if (!ParallelVacuumIsActive(vacrel))
- accumulate_idxs_vacuum_statistics(vacrel, &extVacReport);
-
- pgstat_report_vacuum(RelationGetRelid(indrel),
- indrel->rd_rel->relisshared,
- 0, 0, 0, &extVacReport);
- }
+ /* Make extended vacuum stats report for index */
+ extvac_stats_end_idx(indrel, istat, &extVacCounters, &extVacReport);
+
+ if (!ParallelVacuumIsActive(vacrel))
+ accumulate_idxs_vacuum_statistics(vacrel, &extVacReport);
+
+ pgstat_report_vacuum_extstats(vacrel->indoid, indrel->rd_rel->relisshared, &extVacReport);
/* Revert to the previous phase information for error traceback */
restore_vacuum_error_info(vacrel, &saved_err_info);
@@ -4061,6 +4048,27 @@ update_relstats_all_indexes(LVRelState *vacrel)
}
}
+/* ---------
+ * pgstat_report_vacuum_error() -
+ *
+ * Tell the collector about an (auto)vacuum interruption.
+ * ---------
+ */
+static void
+pgstat_report_vacuum_error()
+{
+ PgStat_VacuumDBCounts *vacuum_dbentry;
+
+ if(!pgstat_track_vacuum_statistics)
+ return;
+
+ vacuum_dbentry = pgstat_fetch_stat_vacuum_dbentry(MyDatabaseId);
+
+ if(vacuum_dbentry == NULL)
+ return;
+ vacuum_dbentry->errors++;
+}
+
/*
* Error context callback for errors occurring during vacuum. The error
* context messages for index phases should match the messages set in parallel
@@ -4076,7 +4084,7 @@ vacuum_error_callback(void *arg)
{
case VACUUM_ERRCB_PHASE_SCAN_HEAP:
if(geterrelevel() == ERROR)
- pgstat_report_vacuum_error(errinfo->reloid, PGSTAT_EXTVAC_TABLE);
+ pgstat_report_vacuum_error();
if (BlockNumberIsValid(errinfo->blkno))
{
@@ -4094,7 +4102,7 @@ vacuum_error_callback(void *arg)
case VACUUM_ERRCB_PHASE_VACUUM_HEAP:
if(geterrelevel() == ERROR)
- pgstat_report_vacuum_error(errinfo->reloid, PGSTAT_EXTVAC_TABLE);
+ pgstat_report_vacuum_error();
if (BlockNumberIsValid(errinfo->blkno))
{
@@ -4112,7 +4120,7 @@ vacuum_error_callback(void *arg)
case VACUUM_ERRCB_PHASE_VACUUM_INDEX:
if(geterrelevel() == ERROR)
- pgstat_report_vacuum_error(errinfo->indoid, PGSTAT_EXTVAC_INDEX);
+ pgstat_report_vacuum_error();
errcontext("while vacuuming index \"%s\" of relation \"%s.%s\"",
errinfo->indname, errinfo->relnamespace, errinfo->relname);
@@ -4120,7 +4128,7 @@ vacuum_error_callback(void *arg)
case VACUUM_ERRCB_PHASE_INDEX_CLEANUP:
if(geterrelevel() == ERROR)
- pgstat_report_vacuum_error(errinfo->indoid, PGSTAT_EXTVAC_INDEX);
+ pgstat_report_vacuum_error();
errcontext("while cleaning up index \"%s\" of relation \"%s.%s\"",
errinfo->indname, errinfo->relnamespace, errinfo->relname);
@@ -4128,7 +4136,7 @@ vacuum_error_callback(void *arg)
case VACUUM_ERRCB_PHASE_TRUNCATE:
if(geterrelevel() == ERROR)
- pgstat_report_vacuum_error(errinfo->reloid, PGSTAT_EXTVAC_TABLE);
+ pgstat_report_vacuum_error();
if (BlockNumberIsValid(errinfo->blkno))
errcontext("while truncating relation \"%s.%s\" to %u blocks",
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index fd6537567ea..f82f11490ff 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -1883,6 +1883,7 @@ heap_drop_with_catalog(Oid relid)
/* ensure that stats are dropped if transaction commits */
pgstat_drop_relation(rel);
+ pgstat_vacuum_relation_delete_pending_cb(RelationGetRelid(rel));
/*
* Close relcache entry, but *keep* AccessExclusiveLock on the relation
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index c4029a4f3d3..3bccc1097fb 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -2327,6 +2327,7 @@ index_drop(Oid indexId, bool concurrent, bool concurrent_lock_mode)
/* ensure that stats are dropped if transaction commits */
pgstat_drop_relation(userIndexRelation);
+ pgstat_vacuum_relation_delete_pending_cb(RelationGetRelid(userIndexRelation));
/*
* Close and flush the index's relcache entry, to ensure relcache doesn't
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index e5370211d74..b3f60ea546d 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -1430,100 +1430,104 @@ GRANT EXECUTE ON FUNCTION pg_get_aios() TO pg_read_all_stats;
--
CREATE VIEW pg_stat_vacuum_tables AS
-SELECT
- ns.nspname AS schemaname,
- rel.relname AS relname,
- stats.relid as relid,
-
- stats.total_blks_read AS total_blks_read,
- stats.total_blks_hit AS total_blks_hit,
- stats.total_blks_dirtied AS total_blks_dirtied,
- stats.total_blks_written AS total_blks_written,
-
- stats.rel_blks_read AS rel_blks_read,
- stats.rel_blks_hit AS rel_blks_hit,
-
- stats.pages_scanned AS pages_scanned,
- stats.pages_removed AS pages_removed,
- stats.vm_new_frozen_pages AS vm_new_frozen_pages,
- stats.vm_new_visible_pages AS vm_new_visible_pages,
- stats.vm_new_visible_frozen_pages AS vm_new_visible_frozen_pages,
- stats.missed_dead_pages AS missed_dead_pages,
- stats.tuples_deleted AS tuples_deleted,
- stats.tuples_frozen AS tuples_frozen,
- stats.recently_dead_tuples AS recently_dead_tuples,
- stats.missed_dead_tuples AS missed_dead_tuples,
-
- stats.wraparound_failsafe AS wraparound_failsafe,
- stats.index_vacuum_count AS index_vacuum_count,
- stats.wal_records AS wal_records,
- stats.wal_fpi AS wal_fpi,
- stats.wal_bytes AS wal_bytes,
-
- stats.blk_read_time AS blk_read_time,
- stats.blk_write_time AS blk_write_time,
-
- stats.delay_time AS delay_time,
- stats.total_time AS total_time
-
-FROM pg_class rel
- JOIN pg_namespace ns ON ns.oid = rel.relnamespace,
- LATERAL pg_stat_get_vacuum_tables(rel.oid) stats
-WHERE rel.relkind = 'r';
+ SELECT
+ N.nspname AS schemaname,
+ C.relname AS relname,
+ S.relid as relid,
+
+ 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.rel_blks_read AS rel_blks_read,
+ S.rel_blks_hit AS rel_blks_hit,
+
+ S.pages_scanned AS pages_scanned,
+ S.pages_removed AS pages_removed,
+ 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.missed_dead_pages AS missed_dead_pages,
+ S.tuples_deleted AS tuples_deleted,
+ S.tuples_frozen AS tuples_frozen,
+ S.recently_dead_tuples AS recently_dead_tuples,
+ S.missed_dead_tuples AS missed_dead_tuples,
+
+ S.wraparound_failsafe AS wraparound_failsafe,
+ S.index_vacuum_count AS index_vacuum_count,
+ S.wal_records AS wal_records,
+ S.wal_fpi AS wal_fpi,
+ S.wal_bytes AS wal_bytes,
+
+ S.blk_read_time AS blk_read_time,
+ S.blk_write_time AS blk_write_time,
+
+ S.delay_time AS delay_time,
+ S.total_time AS total_time
+
+ FROM pg_class C JOIN
+ pg_namespace N ON N.oid = C.relnamespace,
+ LATERAL pg_stat_get_vacuum_tables(C.oid) S
+ WHERE C.relkind IN ('r', 't', 'm');
CREATE VIEW pg_stat_vacuum_indexes AS
-SELECT
- rel.oid as relid,
- ns.nspname AS schemaname,
- rel.relname AS relname,
+ SELECT
+ C.oid AS relid,
+ I.oid AS indexrelid,
+ N.nspname AS schemaname,
+ C.relname AS relname,
+ I.relname AS indexrelname,
- total_blks_read AS total_blks_read,
- total_blks_hit AS total_blks_hit,
- total_blks_dirtied AS total_blks_dirtied,
- total_blks_written AS total_blks_written,
+ 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,
- rel_blks_read AS rel_blks_read,
- rel_blks_hit AS rel_blks_hit,
+ S.rel_blks_read AS rel_blks_read,
+ S.rel_blks_hit AS rel_blks_hit,
- pages_deleted AS pages_deleted,
- tuples_deleted AS tuples_deleted,
+ S.pages_deleted AS pages_deleted,
+ S.tuples_deleted AS tuples_deleted,
- wal_records AS wal_records,
- wal_fpi AS wal_fpi,
- wal_bytes AS wal_bytes,
+ S.wal_records AS wal_records,
+ S.wal_fpi AS wal_fpi,
+ S.wal_bytes AS wal_bytes,
- blk_read_time AS blk_read_time,
- blk_write_time AS blk_write_time,
+ S.blk_read_time AS blk_read_time,
+ S.blk_write_time AS blk_write_time,
- delay_time AS delay_time,
- total_time AS total_time
-FROM
- pg_class rel
- JOIN pg_namespace ns ON ns.oid = rel.relnamespace,
- LATERAL pg_stat_get_vacuum_indexes(rel.oid) stats
-WHERE rel.relkind = 'i';
+ S.delay_time AS delay_time,
+ S.total_time AS total_time
+ FROM
+ pg_class C 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
+ WHERE C.relkind IN ('r', 't', 'm');
CREATE VIEW pg_stat_vacuum_database AS
-SELECT
- db.oid as dboid,
- db.datname AS dbname,
-
- stats.db_blks_read AS db_blks_read,
- stats.db_blks_hit AS db_blks_hit,
- stats.total_blks_dirtied AS total_blks_dirtied,
- stats.total_blks_written AS total_blks_written,
-
- stats.wal_records AS wal_records,
- stats.wal_fpi AS wal_fpi,
- stats.wal_bytes AS wal_bytes,
-
- stats.blk_read_time AS blk_read_time,
- stats.blk_write_time AS blk_write_time,
-
- stats.delay_time AS delay_time,
- stats.total_time AS total_time,
- stats.wraparound_failsafe AS wraparound_failsafe,
- stats.errors AS errors
-FROM
- pg_database db,
- LATERAL pg_stat_get_vacuum_database(db.oid) stats;
\ No newline at end of file
+ SELECT
+ D.oid as dboid,
+ D.datname AS dbname,
+
+ 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.wal_records AS wal_records,
+ S.wal_fpi AS wal_fpi,
+ S.wal_bytes AS wal_bytes,
+
+ S.blk_read_time AS blk_read_time,
+ S.blk_write_time AS blk_write_time,
+
+ S.delay_time AS delay_time,
+ S.total_time AS total_time,
+ S.wraparound_failsafe AS wraparound_failsafe,
+ S.errors AS errors
+ FROM
+ pg_database D,
+ LATERAL pg_stat_get_vacuum_database(D.oid) S;
\ No newline at end of file
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index 2793fd83771..25ede1d9824 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -1815,6 +1815,7 @@ dropdb(const char *dbname, bool missing_ok, bool force)
* Tell the cumulative stats system to forget it immediately, too.
*/
pgstat_drop_database(db_id);
+ pgstat_drop_vacuum_database(db_id);
/*
* Except for the deletion of the catalog row, subsequent actions are not
diff --git a/src/backend/commands/vacuumparallel.c b/src/backend/commands/vacuumparallel.c
index 65de45a4447..3c37d1f07ce 100644
--- a/src/backend/commands/vacuumparallel.c
+++ b/src/backend/commands/vacuumparallel.c
@@ -869,7 +869,7 @@ parallel_vacuum_process_one_index(ParallelVacuumState *pvs, Relation indrel,
IndexBulkDeleteResult *istat_res;
IndexVacuumInfo ivinfo;
LVExtStatCountersIdx extVacCounters;
- ExtVacReport extVacReport;
+ PgStat_VacuumRelationCounts extVacReport;
/*
* Update the pointer to the corresponding bulk-deletion result if someone
@@ -909,14 +909,10 @@ parallel_vacuum_process_one_index(ParallelVacuumState *pvs, Relation indrel,
RelationGetRelationName(indrel));
}
- if(pgstat_track_vacuum_statistics)
- {
- /* Make extended vacuum stats report for index */
- extvac_stats_end_idx(indrel, istat_res, &extVacCounters, &extVacReport);
- pgstat_report_vacuum(RelationGetRelid(indrel),
- indrel->rd_rel->relisshared,
- 0, 0, 0, &extVacReport);
- }
+ /* Make extended vacuum stats report for index */
+ extvac_stats_end_idx(indrel, istat_res, &extVacCounters, &extVacReport);
+ pgstat_report_vacuum_extstats(RelationGetRelid(indrel), indrel->rd_rel->relisshared,
+ &extVacReport);
/*
* Copy the index bulk-deletion result returned from ambulkdelete and
diff --git a/src/backend/utils/activity/Makefile b/src/backend/utils/activity/Makefile
index 9c2443e1ecd..183f7514d2d 100644
--- a/src/backend/utils/activity/Makefile
+++ b/src/backend/utils/activity/Makefile
@@ -27,6 +27,7 @@ OBJS = \
pgstat_function.o \
pgstat_io.o \
pgstat_relation.o \
+ pgstat_vacuum.o \
pgstat_replslot.o \
pgstat_shmem.o \
pgstat_slru.o \
diff --git a/src/backend/utils/activity/pgstat.c b/src/backend/utils/activity/pgstat.c
index 614daf60372..d03fc10666e 100644
--- a/src/backend/utils/activity/pgstat.c
+++ b/src/backend/utils/activity/pgstat.c
@@ -479,6 +479,34 @@ static const PgStat_KindInfo pgstat_kind_builtin_infos[PGSTAT_KIND_BUILTIN_SIZE]
.reset_all_cb = pgstat_wal_reset_all_cb,
.snapshot_cb = pgstat_wal_snapshot_cb,
},
+ [PGSTAT_KIND_VACUUM_DB] = {
+ .name = "vacuum statistics",
+
+ .fixed_amount = false,
+ .write_to_file = true,
+ /* so pg_stat_database entries can be seen in all databases */
+ .accessed_across_databases = true,
+
+ .shared_size = sizeof(PgStatShared_VacuumDB),
+ .shared_data_off = offsetof(PgStatShared_VacuumDB, stats),
+ .shared_data_len = sizeof(((PgStatShared_VacuumDB *) 0)->stats),
+ .pending_size = sizeof(PgStat_VacuumDBCounts),
+
+ .flush_pending_cb = pgstat_vacuum_db_flush_cb,
+ },
+ [PGSTAT_KIND_VACUUM_RELATION] = {
+ .name = "vacuum statistics",
+
+ .fixed_amount = false,
+ .write_to_file = true,
+
+ .shared_size = sizeof(PgStatShared_VacuumRelation),
+ .shared_data_off = offsetof(PgStatShared_VacuumRelation, stats),
+ .shared_data_len = sizeof(((PgStatShared_VacuumRelation *) 0)->stats),
+ .pending_size = sizeof(PgStat_RelationVacuumPending),
+
+ .flush_pending_cb = pgstat_vacuum_relation_flush_cb
+ },
};
/*
diff --git a/src/backend/utils/activity/pgstat_database.c b/src/backend/utils/activity/pgstat_database.c
index 65207d30378..80e6c7c229a 100644
--- a/src/backend/utils/activity/pgstat_database.c
+++ b/src/backend/utils/activity/pgstat_database.c
@@ -46,6 +46,15 @@ pgstat_drop_database(Oid databaseid)
pgstat_drop_transactional(PGSTAT_KIND_DATABASE, databaseid, InvalidOid);
}
+/*
+ * Remove entry for the database being dropped.
+ */
+void
+pgstat_drop_vacuum_database(Oid databaseid)
+{
+ pgstat_drop_transactional(PGSTAT_KIND_VACUUM_DB, databaseid, InvalidOid);
+}
+
/*
* Called from autovacuum.c to report startup of an autovacuum process.
* We are called before InitPostgres is done, so can't rely on MyDatabaseId;
@@ -485,7 +494,6 @@ pgstat_database_flush_cb(PgStat_EntryRef *entry_ref, bool nowait)
pgstat_unlock_entry(entry_ref);
memset(pendingent, 0, sizeof(*pendingent));
- memset(&(pendingent)->vacuum_ext, 0, sizeof(ExtVacReport));
return true;
}
diff --git a/src/backend/utils/activity/pgstat_relation.c b/src/backend/utils/activity/pgstat_relation.c
index bf7ab345be0..817372f9cec 100644
--- a/src/backend/utils/activity/pgstat_relation.c
+++ b/src/backend/utils/activity/pgstat_relation.c
@@ -47,8 +47,6 @@ static void add_tabstat_xact_level(PgStat_TableStatus *pgstat_info, int nest_lev
static void ensure_tabstat_xact_level(PgStat_TableStatus *pgstat_info);
static void save_truncdrop_counters(PgStat_TableXactStatus *trans, bool is_drop);
static void restore_truncdrop_counters(PgStat_TableXactStatus *trans);
-static void pgstat_accumulate_extvac_stats(ExtVacReport *dst, ExtVacReport *src,
- bool accumulate_reltype_specific_info);
/*
@@ -205,50 +203,17 @@ pgstat_drop_relation(Relation rel)
}
}
-/* ---------
- * pgstat_report_vacuum_error() -
- *
- * Tell the collector about an (auto)vacuum interruption.
- * ---------
- */
-void
-pgstat_report_vacuum_error(Oid tableoid, ExtVacReportType m_type)
-{
- PgStat_EntryRef *entry_ref;
- PgStatShared_Relation *shtabentry;
- PgStat_StatTabEntry *tabentry;
- Oid dboid = MyDatabaseId;
- PgStat_StatDBEntry *dbentry; /* pending database entry */
-
- if (!pgstat_track_counts)
- return;
-
- entry_ref = pgstat_get_entry_ref_locked(PGSTAT_KIND_RELATION,
- dboid, tableoid, false);
-
- shtabentry = (PgStatShared_Relation *) entry_ref->shared_stats;
- tabentry = &shtabentry->stats;
-
- tabentry->vacuum_ext.type = m_type;
- pgstat_unlock_entry(entry_ref);
-
- dbentry = pgstat_prep_database_pending(dboid);
- dbentry->vacuum_ext.errors++;
- dbentry->vacuum_ext.type = m_type;
-}
-
/*
* Report that the table was just vacuumed and flush IO statistics.
*/
void
pgstat_report_vacuum(Oid tableoid, bool shared,
PgStat_Counter livetuples, PgStat_Counter deadtuples,
- TimestampTz starttime, ExtVacReport *params)
+ TimestampTz starttime)
{
PgStat_EntryRef *entry_ref;
PgStatShared_Relation *shtabentry;
PgStat_StatTabEntry *tabentry;
- PgStatShared_Database *dbentry;
Oid dboid = (shared ? InvalidOid : MyDatabaseId);
TimestampTz ts;
PgStat_Counter elapsedtime;
@@ -270,8 +235,6 @@ pgstat_report_vacuum(Oid tableoid, bool shared,
tabentry->live_tuples = livetuples;
tabentry->dead_tuples = deadtuples;
- pgstat_accumulate_extvac_stats(&tabentry->vacuum_ext, params, true);
-
/*
* It is quite possible that a non-aggressive VACUUM ended up skipping
* various pages, however, we'll zero the insert counter here regardless.
@@ -307,16 +270,6 @@ pgstat_report_vacuum(Oid tableoid, bool shared,
*/
pgstat_flush_io(false);
(void) pgstat_flush_backend(false, PGSTAT_BACKEND_FLUSH_IO);
-
- if (dboid != InvalidOid)
- {
- entry_ref = pgstat_get_entry_ref_locked(PGSTAT_KIND_DATABASE,
- dboid, InvalidOid, false);
- dbentry = (PgStatShared_Database *) entry_ref->shared_stats;
-
- pgstat_accumulate_extvac_stats(&dbentry->stats.vacuum_ext, params, false);
- pgstat_unlock_entry(entry_ref);
- }
}
/*
@@ -951,6 +904,12 @@ pgstat_relation_flush_cb(PgStat_EntryRef *entry_ref, bool nowait)
return true;
}
+void
+pgstat_vacuum_relation_delete_pending_cb(Oid relid)
+{
+ pgstat_drop_transactional(PGSTAT_KIND_VACUUM_RELATION, relid, InvalidOid);
+}
+
void
pgstat_relation_delete_pending_cb(PgStat_EntryRef *entry_ref)
{
@@ -1053,60 +1012,4 @@ restore_truncdrop_counters(PgStat_TableXactStatus *trans)
trans->tuples_updated = trans->updated_pre_truncdrop;
trans->tuples_deleted = trans->deleted_pre_truncdrop;
}
-}
-
-static void
-pgstat_accumulate_extvac_stats(ExtVacReport *dst, ExtVacReport *src,
- bool accumulate_reltype_specific_info)
-{
- if(!pgstat_track_vacuum_statistics)
- return;
-
- 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->wal_bytes += src->wal_bytes;
- dst->wal_fpi += src->wal_fpi;
- dst->wal_records += src->wal_records;
- dst->blk_read_time += src->blk_read_time;
- dst->blk_write_time += src->blk_write_time;
- dst->delay_time += src->delay_time;
- dst->total_time += src->total_time;
- dst->wraparound_failsafe_count += src->wraparound_failsafe_count;
- dst->errors += src->errors;
-
- if (!accumulate_reltype_specific_info)
- return;
-
- if (dst->type == PGSTAT_EXTVAC_INVALID)
- dst->type = src->type;
-
- Assert(src->type == PGSTAT_EXTVAC_INVALID || src->type == dst->type);
-
- if (dst->type == src->type)
- {
- dst->blks_fetched += src->blks_fetched;
- dst->blks_hit += src->blks_hit;
-
- if (dst->type == PGSTAT_EXTVAC_TABLE)
- {
- dst->table.pages_scanned += src->table.pages_scanned;
- dst->table.pages_removed += src->table.pages_removed;
- dst->table.vm_new_frozen_pages += src->table.vm_new_frozen_pages;
- dst->table.vm_new_visible_pages += src->table.vm_new_visible_pages;
- dst->table.vm_new_visible_frozen_pages += src->table.vm_new_visible_frozen_pages;
- dst->tuples_deleted += src->tuples_deleted;
- dst->table.tuples_frozen += src->table.tuples_frozen;
- dst->table.recently_dead_tuples += src->table.recently_dead_tuples;
- dst->table.index_vacuum_count += src->table.index_vacuum_count;
- dst->table.missed_dead_pages += src->table.missed_dead_pages;
- dst->table.missed_dead_tuples += src->table.missed_dead_tuples;
- }
- else if (dst->type == PGSTAT_EXTVAC_INDEX)
- {
- dst->index.pages_deleted += src->index.pages_deleted;
- dst->tuples_deleted += src->tuples_deleted;
- }
- }
}
\ No newline at end of file
diff --git a/src/backend/utils/activity/pgstat_vacuum.c b/src/backend/utils/activity/pgstat_vacuum.c
new file mode 100644
index 00000000000..e11f19e46b2
--- /dev/null
+++ b/src/backend/utils/activity/pgstat_vacuum.c
@@ -0,0 +1,215 @@
+#include "postgres.h"
+
+#include "pgstat.h"
+#include "utils/pgstat_internal.h"
+#include "utils/memutils.h"
+
+/* ----------
+ * GUC parameters
+ * ----------
+ */
+bool pgstat_track_vacuum_statistics_for_relations = false;
+
+#define ACCUMULATE_FIELD(field) dst->field += src->field;
+
+#define ACCUMULATE_SUBFIELD(substruct, field) \
+ (dst->substruct.field += src->substruct.field)
+
+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(blks_fetched);
+ ACCUMULATE_FIELD(blks_hit);
+
+ ACCUMULATE_FIELD(wal_records);
+ ACCUMULATE_FIELD(wal_fpi);
+ ACCUMULATE_FIELD(wal_bytes);
+
+ ACCUMULATE_FIELD(blk_read_time);
+ ACCUMULATE_FIELD(blk_write_time);
+ ACCUMULATE_FIELD(delay_time);
+ ACCUMULATE_FIELD(total_time);
+
+ ACCUMULATE_FIELD(tuples_deleted);
+ ACCUMULATE_FIELD(wraparound_failsafe_count);
+}
+
+static void
+pgstat_accumulate_extvac_stats_relations(PgStat_VacuumRelationCounts *dst, PgStat_VacuumRelationCounts *src)
+{
+ if(!pgstat_track_vacuum_statistics)
+ return;
+
+ if (dst->type == PGSTAT_EXTVAC_INVALID)
+ dst->type = src->type;
+
+ Assert(src->type != PGSTAT_EXTVAC_INVALID && src->type != PGSTAT_EXTVAC_DB && src->type == dst->type);
+
+ pgstat_accumulate_common(&dst->common, &src->common);
+
+ ACCUMULATE_SUBFIELD(common, blks_fetched);
+ ACCUMULATE_SUBFIELD(common, blks_hit);
+
+ if (dst->type == PGSTAT_EXTVAC_TABLE)
+ {
+ ACCUMULATE_SUBFIELD(common, tuples_deleted);
+ ACCUMULATE_SUBFIELD(table, pages_scanned);
+ ACCUMULATE_SUBFIELD(table, pages_removed);
+ ACCUMULATE_SUBFIELD(table, vm_new_frozen_pages);
+ ACCUMULATE_SUBFIELD(table, vm_new_visible_pages);
+ ACCUMULATE_SUBFIELD(table, vm_new_visible_frozen_pages);
+ ACCUMULATE_SUBFIELD(table, tuples_frozen);
+ ACCUMULATE_SUBFIELD(table, recently_dead_tuples);
+ ACCUMULATE_SUBFIELD(table, index_vacuum_count);
+ ACCUMULATE_SUBFIELD(table, missed_dead_pages);
+ ACCUMULATE_SUBFIELD(table, missed_dead_tuples);
+ }
+ else if (dst->type == PGSTAT_EXTVAC_INDEX)
+ {
+ ACCUMULATE_SUBFIELD(common, tuples_deleted);
+ ACCUMULATE_SUBFIELD(index, pages_deleted);
+ }
+}
+
+static void
+pgstat_accumulate_extvac_stats_db(PgStat_VacuumDBCounts *dst, PgStat_VacuumDBCounts *src)
+{
+ if(!pgstat_track_vacuum_statistics)
+ return;
+
+ pgstat_accumulate_common(&dst->common, &src->common);
+ dst->errors += src->errors;
+}
+
+/*
+ * Report that the table was just vacuumed and flush statistics.
+ */
+void
+pgstat_report_vacuum_extstats(Oid tableoid, bool shared,
+ PgStat_VacuumRelationCounts *params)
+{
+ PgStat_EntryRef *entry_ref;
+ PgStatShared_VacuumRelation *shtabentry;
+ PgStatShared_VacuumDB *shdbentry;
+ Oid dboid = (shared ? InvalidOid : MyDatabaseId);
+
+ if(!pgstat_track_vacuum_statistics)
+ return;
+
+ entry_ref = pgstat_get_entry_ref_locked(PGSTAT_KIND_VACUUM_RELATION,
+ dboid, tableoid, false);
+ shtabentry = (PgStatShared_VacuumRelation *) entry_ref->shared_stats;
+ pgstat_accumulate_extvac_stats_relations(&shtabentry->stats, params);
+
+ pgstat_unlock_entry(entry_ref);
+
+
+ entry_ref = pgstat_get_entry_ref_locked(PGSTAT_KIND_VACUUM_DB,
+ dboid, InvalidOid, false);
+
+ shdbentry = (PgStatShared_VacuumDB *) entry_ref->shared_stats;
+
+ pgstat_accumulate_common(&shdbentry->stats.common, ¶ms->common);
+
+ pgstat_unlock_entry(entry_ref);
+}
+
+/*
+ * Flush out pending stats for the entry
+ *
+ * If nowait is true, this function returns false if lock could not
+ * immediately acquired, otherwise true is returned.
+ */
+bool
+pgstat_vacuum_relation_flush_cb(PgStat_EntryRef *entry_ref, bool nowait)
+{
+ PgStatShared_VacuumRelation *shtabstats;
+ PgStat_RelationVacuumPending *pendingent; /* table entry of shared stats */
+
+ pendingent = (PgStat_RelationVacuumPending *) entry_ref->pending;
+ shtabstats = (PgStatShared_VacuumRelation *) entry_ref->shared_stats;
+
+ /*
+ * Ignore entries that didn't accumulate any actual counts.
+ */
+ if (pg_memory_is_all_zeros(&pendingent,
+ sizeof(struct PgStat_RelationVacuumPending)))
+ return true;
+
+ if (!pgstat_lock_entry(entry_ref, nowait))
+ {
+ return false;
+ }
+
+ pgstat_accumulate_extvac_stats_relations(&(shtabstats->stats), &(pendingent->counts));
+
+ pgstat_unlock_entry(entry_ref);
+
+ return true;
+}
+
+/*
+ * Support function for the SQL-callable pgstat* functions. Returns
+ * the vacuum collected statistics for one relation or NULL.
+ */
+PgStat_VacuumRelationCounts *
+pgstat_fetch_stat_vacuum_tabentry(Oid relid, Oid dbid)
+{
+ return (PgStat_VacuumRelationCounts *)
+ pgstat_fetch_entry(PGSTAT_KIND_VACUUM_RELATION, dbid, relid);
+}
+
+PgStat_VacuumDBCounts *
+pgstat_fetch_stat_vacuum_dbentry(Oid dbid)
+{
+ return (PgStat_VacuumDBCounts *)
+ pgstat_fetch_entry(PGSTAT_KIND_VACUUM_DB, dbid, InvalidOid);
+}
+
+bool
+pgstat_vacuum_db_flush_cb(PgStat_EntryRef *entry_ref, bool nowait)
+{
+ PgStatShared_VacuumDB *sharedent;
+ PgStat_VacuumDBCounts *pendingent;
+
+ pendingent = (PgStat_VacuumDBCounts *) entry_ref->pending;
+ sharedent = (PgStatShared_VacuumDB *) entry_ref->shared_stats;
+
+ if (!pgstat_lock_entry(entry_ref, nowait))
+ return false;
+
+ /* The entry was successfully flushed, add the same to database stats */
+ pgstat_accumulate_extvac_stats_db(&(sharedent->stats), pendingent);
+
+ pgstat_unlock_entry(entry_ref);
+
+ return true;
+}
+
+/*
+ * Find or create a local PgStat_VacuumDBCounts entry for dboid.
+ */
+PgStat_VacuumDBCounts *
+pgstat_prep_vacuum_database_pending(Oid dboid)
+{
+ PgStat_EntryRef *entry_ref;
+
+ /*
+ * This should not report stats on database objects before having
+ * connected to a database.
+ */
+ Assert(!OidIsValid(dboid) || OidIsValid(MyDatabaseId));
+
+ entry_ref = pgstat_prep_pending_entry(PGSTAT_KIND_VACUUM_DB, dboid, InvalidOid,
+ NULL);
+
+ if(entry_ref == NULL)
+ return NULL;
+
+ return entry_ref->pending;
+}
\ No newline at end of file
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 1c39ada2c3e..b2df237c337 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -2267,7 +2267,6 @@ pg_stat_have_stats(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(pgstat_have_entry(kind, dboid, objid));
}
-
/*
* Get the vacuum statistics for the heap tables.
*/
@@ -2277,102 +2276,42 @@ pg_stat_get_vacuum_tables(PG_FUNCTION_ARGS)
#define PG_STAT_GET_VACUUM_TABLES_STATS_COLS 26
Oid relid = PG_GETARG_OID(0);
- PgStat_StatTabEntry *tabentry;
- ExtVacReport *extvacuum;
+ PgStat_VacuumRelationCounts *extvacuum;
+ PgStat_VacuumRelationCounts *pending;
TupleDesc tupdesc;
Datum values[PG_STAT_GET_VACUUM_TABLES_STATS_COLS] = {0};
bool nulls[PG_STAT_GET_VACUUM_TABLES_STATS_COLS] = {0};
char buf[256];
int i = 0;
- ExtVacReport allzero;
+ PgStat_VacuumRelationCounts allzero;
- /* Initialise attributes information in the tuple descriptor */
- tupdesc = CreateTemplateTupleDesc(PG_STAT_GET_VACUUM_TABLES_STATS_COLS);
+ /* Build a tuple descriptor for our result type */
+ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+ elog(ERROR, "return type must be a row type");
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "relid",
- INT4OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "total_blks_read",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "total_blks_hit",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "total_blks_dirtied",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "total_blks_written",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "rel_blks_read",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "rel_blks_hit",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "pages_scanned",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "pages_removed",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "vm_new_frozen_pages",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "vm_new_visible_pages",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "vm_new_visible_frozen_pages",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "missed_dead_pages",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "tuples_deleted",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "tuples_frozen",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "recently_dead_tuples",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "missed_dead_tuples",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "wraparound_failsafe_count",
- INT4OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "index_vacuum_count",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "wal_records",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "wal_fpi",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "wal_bytes",
- NUMERICOID, -1, 0);
-
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "blk_read_time",
- FLOAT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "blk_write_time",
- FLOAT8OID, -1, 0);
-
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "delay_time",
- FLOAT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "total_time",
- FLOAT8OID, -1, 0);
-
- Assert(i == PG_STAT_GET_VACUUM_TABLES_STATS_COLS);
-
- BlessTupleDesc(tupdesc);
+ pending = pgstat_fetch_stat_vacuum_tabentry(relid, MyDatabaseId);
- tabentry = pgstat_fetch_stat_tabentry(relid);
-
- if (tabentry == NULL)
+ if (pending == NULL)
{
/* If the subscription is not found, initialise its stats */
- memset(&allzero, 0, sizeof(ExtVacReport));
+ memset(&allzero, 0, sizeof(PgStat_VacuumRelationCounts));
extvacuum = &allzero;
}
else
- {
- extvacuum = &(tabentry->vacuum_ext);
- }
+ extvacuum = pending;
i = 0;
values[i++] = ObjectIdGetDatum(relid);
- values[i++] = Int64GetDatum(extvacuum->total_blks_read);
- values[i++] = Int64GetDatum(extvacuum->total_blks_hit);
- values[i++] = Int64GetDatum(extvacuum->total_blks_dirtied);
- values[i++] = Int64GetDatum(extvacuum->total_blks_written);
+ 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->blks_fetched -
- extvacuum->blks_hit);
- values[i++] = Int64GetDatum(extvacuum->blks_hit);
+ values[i++] = Int64GetDatum(extvacuum->common.blks_fetched -
+ extvacuum->common.blks_hit);
+ values[i++] = Int64GetDatum(extvacuum->common.blks_hit);
values[i++] = Int64GetDatum(extvacuum->table.pages_scanned);
values[i++] = Int64GetDatum(extvacuum->table.pages_removed);
@@ -2380,28 +2319,28 @@ pg_stat_get_vacuum_tables(PG_FUNCTION_ARGS)
values[i++] = Int64GetDatum(extvacuum->table.vm_new_visible_pages);
values[i++] = Int64GetDatum(extvacuum->table.vm_new_visible_frozen_pages);
values[i++] = Int64GetDatum(extvacuum->table.missed_dead_pages);
- values[i++] = Int64GetDatum(extvacuum->tuples_deleted);
+ values[i++] = Int64GetDatum(extvacuum->common.tuples_deleted);
values[i++] = Int64GetDatum(extvacuum->table.tuples_frozen);
values[i++] = Int64GetDatum(extvacuum->table.recently_dead_tuples);
values[i++] = Int64GetDatum(extvacuum->table.missed_dead_tuples);
- values[i++] = Int32GetDatum(extvacuum->wraparound_failsafe_count);
+ values[i++] = Int32GetDatum(extvacuum->common.wraparound_failsafe_count);
values[i++] = Int64GetDatum(extvacuum->table.index_vacuum_count);
- values[i++] = Int64GetDatum(extvacuum->wal_records);
- values[i++] = Int64GetDatum(extvacuum->wal_fpi);
+ values[i++] = Int64GetDatum(extvacuum->common.wal_records);
+ values[i++] = Int64GetDatum(extvacuum->common.wal_fpi);
/* Convert to numeric, like pg_stat_statements */
- snprintf(buf, sizeof buf, UINT64_FORMAT, extvacuum->wal_bytes);
+ snprintf(buf, sizeof buf, UINT64_FORMAT, extvacuum->common.wal_bytes);
values[i++] = DirectFunctionCall3(numeric_in,
CStringGetDatum(buf),
ObjectIdGetDatum(0),
Int32GetDatum(-1));
- values[i++] = Float8GetDatum(extvacuum->blk_read_time);
- values[i++] = Float8GetDatum(extvacuum->blk_write_time);
- values[i++] = Float8GetDatum(extvacuum->delay_time);
- values[i++] = Float8GetDatum(extvacuum->total_time);
+ values[i++] = Float8GetDatum(extvacuum->common.blk_read_time);
+ values[i++] = Float8GetDatum(extvacuum->common.blk_write_time);
+ values[i++] = Float8GetDatum(extvacuum->common.delay_time);
+ values[i++] = Float8GetDatum(extvacuum->common.total_time);
Assert(i == PG_STAT_GET_VACUUM_TABLES_STATS_COLS);
@@ -2418,100 +2357,60 @@ pg_stat_get_vacuum_indexes(PG_FUNCTION_ARGS)
#define PG_STAT_GET_VACUUM_INDEX_STATS_COLS 16
Oid relid = PG_GETARG_OID(0);
- PgStat_StatTabEntry *tabentry;
- ExtVacReport *extvacuum;
+ PgStat_VacuumRelationCounts *extvacuum;
+ PgStat_VacuumRelationCounts *pending;
TupleDesc tupdesc;
Datum values[PG_STAT_GET_VACUUM_INDEX_STATS_COLS] = {0};
bool nulls[PG_STAT_GET_VACUUM_INDEX_STATS_COLS] = {0};
char buf[256];
int i = 0;
- ExtVacReport allzero;
+ PgStat_VacuumRelationCounts allzero;
- /* Initialise attributes information in the tuple descriptor */
- tupdesc = CreateTemplateTupleDesc(PG_STAT_GET_VACUUM_INDEX_STATS_COLS);
+ /* Build a tuple descriptor for our result type */
+ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+ elog(ERROR, "return type must be a row type");
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "relid",
- INT4OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "total_ blks_read",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "total_blks_hit",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "total_blks_dirtied",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "total_blks_written",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "rel_blks_read",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "rel_blks_hit",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "pages_deleted",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "tuples_deleted",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "wal_records",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "wal_fpi",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "wal_bytes",
- NUMERICOID, -1, 0);
-
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "blk_read_time",
- FLOAT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "blk_write_time",
- FLOAT8OID, -1, 0);
+ pending = pgstat_fetch_stat_vacuum_tabentry(relid, MyDatabaseId);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "delay_time",
- FLOAT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "total_time",
- FLOAT8OID, -1, 0);
-
- Assert(i == PG_STAT_GET_VACUUM_INDEX_STATS_COLS);
-
- BlessTupleDesc(tupdesc);
-
- tabentry = pgstat_fetch_stat_tabentry(relid);
-
- if (tabentry == NULL)
+ if (pending == NULL)
{
/* If the subscription is not found, initialise its stats */
- memset(&allzero, 0, sizeof(ExtVacReport));
+ memset(&allzero, 0, sizeof(PgStat_VacuumRelationCounts));
extvacuum = &allzero;
}
else
- {
- extvacuum = &(tabentry->vacuum_ext);
- }
+ extvacuum = pending;
i = 0;
values[i++] = ObjectIdGetDatum(relid);
- values[i++] = Int64GetDatum(extvacuum->total_blks_read);
- values[i++] = Int64GetDatum(extvacuum->total_blks_hit);
- values[i++] = Int64GetDatum(extvacuum->total_blks_dirtied);
- values[i++] = Int64GetDatum(extvacuum->total_blks_written);
+ 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->blks_fetched -
- extvacuum->blks_hit);
- values[i++] = Int64GetDatum(extvacuum->blks_hit);
+ values[i++] = Int64GetDatum(extvacuum->common.blks_fetched -
+ extvacuum->common.blks_hit);
+ values[i++] = Int64GetDatum(extvacuum->common.blks_hit);
values[i++] = Int64GetDatum(extvacuum->index.pages_deleted);
- values[i++] = Int64GetDatum(extvacuum->tuples_deleted);
+ values[i++] = Int64GetDatum(extvacuum->common.tuples_deleted);
- values[i++] = Int64GetDatum(extvacuum->wal_records);
- values[i++] = Int64GetDatum(extvacuum->wal_fpi);
+ values[i++] = Int64GetDatum(extvacuum->common.wal_records);
+ values[i++] = Int64GetDatum(extvacuum->common.wal_fpi);
/* Convert to numeric, like pg_stat_statements */
- snprintf(buf, sizeof buf, UINT64_FORMAT, extvacuum->wal_bytes);
+ snprintf(buf, sizeof buf, UINT64_FORMAT, extvacuum->common.wal_bytes);
values[i++] = DirectFunctionCall3(numeric_in,
CStringGetDatum(buf),
ObjectIdGetDatum(0),
Int32GetDatum(-1));
- values[i++] = Float8GetDatum(extvacuum->blk_read_time);
- values[i++] = Float8GetDatum(extvacuum->blk_write_time);
- values[i++] = Float8GetDatum(extvacuum->delay_time);
- values[i++] = Float8GetDatum(extvacuum->total_time);
+ values[i++] = Float8GetDatum(extvacuum->common.blk_read_time);
+ values[i++] = Float8GetDatum(extvacuum->common.blk_write_time);
+ values[i++] = Float8GetDatum(extvacuum->common.delay_time);
+ values[i++] = Float8GetDatum(extvacuum->common.total_time);
Assert(i == PG_STAT_GET_VACUUM_INDEX_STATS_COLS);
@@ -2525,90 +2424,52 @@ pg_stat_get_vacuum_database(PG_FUNCTION_ARGS)
#define PG_STAT_GET_VACUUM_DATABASE_STATS_COLS 14
Oid dbid = PG_GETARG_OID(0);
- PgStat_StatDBEntry *dbentry;
- ExtVacReport *extvacuum;
+ PgStat_VacuumDBCounts *extvacuum;
+ PgStat_VacuumDBCounts *pending;
TupleDesc tupdesc;
Datum values[PG_STAT_GET_VACUUM_DATABASE_STATS_COLS] = {0};
bool nulls[PG_STAT_GET_VACUUM_DATABASE_STATS_COLS] = {0};
char buf[256];
int i = 0;
- ExtVacReport allzero;
-
- /* Initialise attributes information in the tuple descriptor */
- tupdesc = CreateTemplateTupleDesc(PG_STAT_GET_VACUUM_DATABASE_STATS_COLS);
-
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "dbid",
- INT4OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "total_ blks_read",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "total_blks_hit",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "total_blks_dirtied",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "total_blks_written",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "wal_records",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "wal_fpi",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "wal_bytes",
- NUMERICOID, -1, 0);
+ PgStat_VacuumDBCounts allzero;
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "blk_read_time",
- FLOAT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "blk_write_time",
- FLOAT8OID, -1, 0);
+ /* Build a tuple descriptor for our result type */
+ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+ elog(ERROR, "return type must be a row type");
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "delay_time",
- FLOAT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "total_time",
- FLOAT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "wraparound_failsafe_count",
- INT4OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) ++i, "errors",
- INT4OID, -1, 0);
+ pending = pgstat_fetch_stat_vacuum_dbentry(dbid);
- Assert(i == PG_STAT_GET_VACUUM_DATABASE_STATS_COLS);
-
- BlessTupleDesc(tupdesc);
-
- dbentry = pgstat_fetch_stat_dbentry(dbid);
-
- if (dbentry == NULL)
+ if (pending == NULL)
{
/* If the subscription is not found, initialise its stats */
- memset(&allzero, 0, sizeof(ExtVacReport));
+ memset(&allzero, 0, sizeof(PgStat_VacuumRelationCounts));
extvacuum = &allzero;
}
else
- {
- extvacuum = &(dbentry->vacuum_ext);
- }
-
- i = 0;
+ extvacuum = pending;
values[i++] = ObjectIdGetDatum(dbid);
- values[i++] = Int64GetDatum(extvacuum->total_blks_read);
- values[i++] = Int64GetDatum(extvacuum->total_blks_hit);
- values[i++] = Int64GetDatum(extvacuum->total_blks_dirtied);
- values[i++] = Int64GetDatum(extvacuum->total_blks_written);
+ 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->wal_records);
- values[i++] = Int64GetDatum(extvacuum->wal_fpi);
+ values[i++] = Int64GetDatum(extvacuum->common.wal_records);
+ values[i++] = Int64GetDatum(extvacuum->common.wal_fpi);
/* Convert to numeric, like pg_stat_statements */
- snprintf(buf, sizeof buf, UINT64_FORMAT, extvacuum->wal_bytes);
+ snprintf(buf, sizeof buf, UINT64_FORMAT, extvacuum->common.wal_bytes);
values[i++] = DirectFunctionCall3(numeric_in,
CStringGetDatum(buf),
ObjectIdGetDatum(0),
Int32GetDatum(-1));
- values[i++] = Float8GetDatum(extvacuum->blk_read_time);
- values[i++] = Float8GetDatum(extvacuum->blk_write_time);
- values[i++] = Float8GetDatum(extvacuum->delay_time);
- values[i++] = Float8GetDatum(extvacuum->total_time);
- values[i++] = Int32GetDatum(extvacuum->wraparound_failsafe_count);
+ values[i++] = Float8GetDatum(extvacuum->common.blk_read_time);
+ values[i++] = Float8GetDatum(extvacuum->common.blk_write_time);
+ values[i++] = Float8GetDatum(extvacuum->common.delay_time);
+ values[i++] = Float8GetDatum(extvacuum->common.total_time);
+ values[i++] = Int32GetDatum(extvacuum->common.wraparound_failsafe_count);
values[i++] = Int32GetDatum(extvacuum->errors);
Assert(i == PG_STAT_GET_VACUUM_DATABASE_STATS_COLS);
diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h
index dcc542750b8..bc9df1433c2 100644
--- a/src/include/commands/vacuum.h
+++ b/src/include/commands/vacuum.h
@@ -432,5 +432,5 @@ extern double anl_get_next_S(double t, int n, double *stateptr);
extern void extvac_stats_start_idx(Relation rel, IndexBulkDeleteResult *stats,
LVExtStatCountersIdx *counters);
extern void extvac_stats_end_idx(Relation rel, IndexBulkDeleteResult *stats,
- LVExtStatCountersIdx *counters, ExtVacReport *report);
+ LVExtStatCountersIdx *counters, PgStat_VacuumRelationCounts *report);
#endif /* VACUUM_H */
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 50876f5446f..3b9eb87221a 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -116,46 +116,100 @@ typedef enum ExtVacReportType
{
PGSTAT_EXTVAC_INVALID = 0,
PGSTAT_EXTVAC_TABLE = 1,
- PGSTAT_EXTVAC_INDEX = 2
+ PGSTAT_EXTVAC_INDEX = 2,
+ PGSTAT_EXTVAC_DB = 3,
} ExtVacReportType;
/* ----------
+ * PgStat_TableCounts The actual per-table counts kept by a backend
*
- * ExtVacReport
+ * This struct should contain only actual event counters, because we make use
+ * of pg_memory_is_all_zeros() to detect whether there are any stats updates
+ * to apply.
*
- * Additional statistics of vacuum processing over a relation.
- * pages_removed is the amount by which the physically shrank,
- * if any (ie the change in its total size on disk)
- * pages_deleted refer to free space within the index file
+ * It is a component of PgStat_TableStatus (within-backend state).
+ *
+ * Note: for a table, tuples_returned is the number of tuples successfully
+ * fetched by heap_getnext, while tuples_fetched is the number of tuples
+ * successfully fetched by heap_fetch under the control of bitmap indexscans.
+ * For an index, tuples_returned is the number of index entries returned by
+ * the index AM, while tuples_fetched is the number of tuples successfully
+ * fetched by heap_fetch under the control of simple indexscans for this index.
+ *
+ * tuples_inserted/updated/deleted/hot_updated/newpage_updated count attempted
+ * actions, regardless of whether the transaction committed. delta_live_tuples,
+ * delta_dead_tuples, and changed_tuples are set depending on commit or abort.
+ * Note that delta_live_tuples and delta_dead_tuples can be negative!
* ----------
*/
-typedef struct ExtVacReport
+typedef struct PgStat_TableCounts
{
- /* number of blocks missed, hit, dirtied and written during a vacuum of specific relation */
- int64 total_blks_read;
- int64 total_blks_hit;
- int64 total_blks_dirtied;
- int64 total_blks_written;
+ PgStat_Counter numscans;
- /* blocks missed and hit for just the heap during a vacuum of specific relation */
- int64 blks_fetched;
- int64 blks_hit;
+ PgStat_Counter tuples_returned;
+ PgStat_Counter tuples_fetched;
- /* Vacuum WAL usage stats */
- int64 wal_records; /* wal usage: number of WAL records */
- int64 wal_fpi; /* wal usage: number of WAL full page images produced */
- uint64 wal_bytes; /* wal usage: size of WAL records produced */
+ PgStat_Counter tuples_inserted;
+ PgStat_Counter tuples_updated;
+ PgStat_Counter tuples_deleted;
+ PgStat_Counter tuples_hot_updated;
+ PgStat_Counter tuples_newpage_updated;
+ bool truncdropped;
+
+ PgStat_Counter delta_live_tuples;
+ PgStat_Counter delta_dead_tuples;
+ PgStat_Counter changed_tuples;
+
+ PgStat_Counter blocks_fetched;
+ PgStat_Counter blocks_hit;
- /* Time stats. */
- double blk_read_time; /* time spent reading pages, in msec */
- double blk_write_time; /* time spent writing pages, in msec */
- double delay_time; /* how long vacuum slept in vacuum delay point, in msec */
- double total_time; /* total time of a vacuum operation, in msec */
+ PgStat_Counter rev_all_visible_pages;
+ PgStat_Counter rev_all_frozen_pages;
+} PgStat_TableCounts;
- int64 tuples_deleted; /* tuples deleted by vacuum */
+typedef struct PgStat_CommonCounts
+{
+ /* blocks */
+ int64 total_blks_read;
+ int64 total_blks_hit;
+ int64 total_blks_dirtied;
+ int64 total_blks_written;
+
+ /* heap blocks */
+ int64 blks_fetched;
+ int64 blks_hit;
+
+ /* WAL */
+ int64 wal_records;
+ int64 wal_fpi;
+ uint64 wal_bytes;
+
+ /* Time */
+ double blk_read_time;
+ double blk_write_time;
+ double delay_time;
+ double total_time;
+
+ /* tuples */
+ int64 tuples_deleted;
+
+ /* failsafe */
+ int32 wraparound_failsafe_count;
+} PgStat_CommonCounts;
- int32 errors;
- int32 wraparound_failsafe_count; /* the number of times to prevent wraparound problem */
+/* ----------
+ *
+ * PgStat_VacuumRelationCounts
+ *
+ * Additional statistics of vacuum processing over a relation.
+ * pages_removed is the amount by which the physically shrank,
+ * if any (ie the change in its total size on disk)
+ * pages_deleted refer to free space within the index file
+ * ----------
+ */
+typedef struct PgStat_VacuumRelationCounts
+{
+ PgStat_CommonCounts common;
ExtVacReportType type; /* heap, index, etc. */
@@ -174,16 +228,16 @@ typedef struct ExtVacReport
{
struct
{
+ int64 tuples_frozen; /* tuples frozen up by vacuum */
+ int64 recently_dead_tuples; /* deleted tuples that are still visible to some transaction */
+ int64 missed_dead_tuples; /* tuples not pruned by vacuum due to failure to get a cleanup lock */
int64 pages_scanned; /* heap pages examined (not skipped by VM) */
int64 pages_removed; /* heap pages removed by vacuum "truncation" */
int64 pages_frozen; /* pages marked in VM as frozen */
int64 pages_all_visible; /* pages marked in VM as all-visible */
- int64 tuples_frozen; /* tuples frozen up by vacuum */
- int64 recently_dead_tuples; /* deleted tuples that are still visible to some transaction */
int64 vm_new_frozen_pages; /* pages marked in VM as frozen */
int64 vm_new_visible_pages; /* pages marked in VM as all-visible */
int64 vm_new_visible_frozen_pages; /* pages marked in VM as all-visible and frozen */
- int64 missed_dead_tuples; /* tuples not pruned by vacuum due to failure to get a cleanup lock */
int64 missed_dead_pages; /* pages with missed dead tuples */
int64 index_vacuum_count; /* number of index vacuumings */
} table;
@@ -192,61 +246,21 @@ typedef struct ExtVacReport
int64 pages_deleted; /* number of pages deleted by vacuum */
} index;
} /* per_type_stats */;
-} ExtVacReport;
+} PgStat_VacuumRelationCounts;
-/* ----------
- * PgStat_TableCounts The actual per-table counts kept by a backend
- *
- * This struct should contain only actual event counters, because we make use
- * of pg_memory_is_all_zeros() to detect whether there are any stats updates
- * to apply.
- *
- * It is a component of PgStat_TableStatus (within-backend state).
- *
- * Note: for a table, tuples_returned is the number of tuples successfully
- * fetched by heap_getnext, while tuples_fetched is the number of tuples
- * successfully fetched by heap_fetch under the control of bitmap indexscans.
- * For an index, tuples_returned is the number of index entries returned by
- * the index AM, while tuples_fetched is the number of tuples successfully
- * fetched by heap_fetch under the control of simple indexscans for this index.
- *
- * tuples_inserted/updated/deleted/hot_updated/newpage_updated count attempted
- * actions, regardless of whether the transaction committed. delta_live_tuples,
- * delta_dead_tuples, and changed_tuples are set depending on commit or abort.
- * Note that delta_live_tuples and delta_dead_tuples can be negative!
- * ----------
- */
-typedef struct PgStat_TableCounts
+typedef struct PgStat_VacuumRelationStatus
{
- PgStat_Counter numscans;
-
- PgStat_Counter tuples_returned;
- PgStat_Counter tuples_fetched;
-
- PgStat_Counter tuples_inserted;
- PgStat_Counter tuples_updated;
- PgStat_Counter tuples_deleted;
- PgStat_Counter tuples_hot_updated;
- PgStat_Counter tuples_newpage_updated;
- bool truncdropped;
-
- PgStat_Counter delta_live_tuples;
- PgStat_Counter delta_dead_tuples;
- PgStat_Counter changed_tuples;
-
- PgStat_Counter blocks_fetched;
- PgStat_Counter blocks_hit;
-
- PgStat_Counter rev_all_visible_pages;
- PgStat_Counter rev_all_frozen_pages;
+ Oid id; /* table's OID */
+ bool shared; /* is it a shared catalog? */
+ PgStat_VacuumRelationCounts counts; /* event counts to be sent */
+} PgStat_VacuumRelationStatus;
- /*
- * Additional cumulative stat on vacuum operations.
- * Use an expensive structure as an abstraction for different types of
- * relations.
- */
- ExtVacReport vacuum_ext;
-} PgStat_TableCounts;
+typedef struct PgStat_VacuumDBCounts
+{
+ Oid dbjid;
+ PgStat_CommonCounts common;
+ int32 errors;
+} PgStat_VacuumDBCounts;
/* ----------
* PgStat_TableStatus Per-table status within a backend
@@ -272,6 +286,12 @@ typedef struct PgStat_TableStatus
Relation relation; /* rel that is using this entry */
} PgStat_TableStatus;
+typedef struct PgStat_RelationVacuumPending
+{
+ Oid id; /* table's OID */
+ PgStat_VacuumRelationCounts counts; /* event counts to be sent */
+} PgStat_RelationVacuumPending;
+
/* ----------
* PgStat_TableXactStatus Per-table, per-subtransaction status
* ----------
@@ -468,8 +488,6 @@ typedef struct PgStat_StatDBEntry
PgStat_Counter parallel_workers_launched;
TimestampTz stat_reset_timestamp;
-
- ExtVacReport vacuum_ext; /* extended vacuum statistics */
} PgStat_StatDBEntry;
typedef struct PgStat_StatFuncEntry
@@ -551,8 +569,6 @@ typedef struct PgStat_StatTabEntry
PgStat_Counter rev_all_visible_pages;
PgStat_Counter rev_all_frozen_pages;
-
- ExtVacReport vacuum_ext;
} PgStat_StatTabEntry;
/* ------
@@ -760,11 +776,10 @@ extern void pgstat_unlink_relation(Relation rel);
extern void pgstat_report_vacuum(Oid tableoid, bool shared,
PgStat_Counter livetuples, PgStat_Counter deadtuples,
- TimestampTz starttime, ExtVacReport *params);
+ TimestampTz starttime);
extern void pgstat_report_analyze(Relation rel,
PgStat_Counter livetuples, PgStat_Counter deadtuples,
bool resetcounter, TimestampTz starttime);
-extern void pgstat_report_vacuum_error(Oid tableoid, ExtVacReportType m_type);
/*
* If stats are enabled, but pending data hasn't been prepared yet, call
@@ -895,6 +910,15 @@ extern int pgstat_get_transactional_drops(bool isCommit, struct xl_xact_stats_it
extern void pgstat_execute_transactional_drops(int ndrops, struct xl_xact_stats_item *items, bool is_redo);
+extern void pgstat_drop_vacuum_database(Oid databaseid);
+extern void pgstat_vacuum_relation_delete_pending_cb(Oid relid);
+extern void
+pgstat_report_vacuum_extstats(Oid tableoid, bool shared,
+ PgStat_VacuumRelationCounts *params);
+extern PgStat_RelationVacuumPending * find_vacuum_relation_entry(Oid relid);
+extern PgStat_VacuumDBCounts *pgstat_prep_vacuum_database_pending(Oid dboid);
+extern PgStat_VacuumRelationCounts *pgstat_fetch_stat_vacuum_tabentry(Oid relid, Oid dbid);
+PgStat_VacuumDBCounts *pgstat_fetch_stat_vacuum_dbentry(Oid dbid);
/*
* Functions in pgstat_wal.c
*/
diff --git a/src/include/utils/pgstat_internal.h b/src/include/utils/pgstat_internal.h
index 6cf00008f63..5c5ab8e2ee4 100644
--- a/src/include/utils/pgstat_internal.h
+++ b/src/include/utils/pgstat_internal.h
@@ -432,6 +432,18 @@ typedef struct PgStatShared_Relation
PgStat_StatTabEntry stats;
} PgStatShared_Relation;
+typedef struct PgStatShared_VacuumDB
+{
+ PgStatShared_Common header;
+ PgStat_VacuumDBCounts stats;
+} PgStatShared_VacuumDB;
+
+typedef struct PgStatShared_VacuumRelation
+{
+ PgStatShared_Common header;
+ PgStat_VacuumRelationCounts stats;
+} PgStatShared_VacuumRelation;
+
typedef struct PgStatShared_Function
{
PgStatShared_Common header;
@@ -600,6 +612,9 @@ extern PgStat_EntryRef *pgstat_fetch_pending_entry(PgStat_Kind kind,
extern void *pgstat_fetch_entry(PgStat_Kind kind, Oid dboid, uint64 objid);
extern void pgstat_snapshot_fixed(PgStat_Kind kind);
+bool pgstat_vacuum_db_flush_cb(PgStat_EntryRef *entry_ref, bool nowait);
+extern bool pgstat_vacuum_relation_flush_cb(PgStat_EntryRef *entry_ref, bool nowait);
+
/*
* Functions in pgstat_archiver.c
diff --git a/src/include/utils/pgstat_kind.h b/src/include/utils/pgstat_kind.h
index eb5f0b3ae6d..52e884fbf8b 100644
--- a/src/include/utils/pgstat_kind.h
+++ b/src/include/utils/pgstat_kind.h
@@ -38,9 +38,11 @@
#define PGSTAT_KIND_IO 10
#define PGSTAT_KIND_SLRU 11
#define PGSTAT_KIND_WAL 12
+#define PGSTAT_KIND_VACUUM_DB 13
+#define PGSTAT_KIND_VACUUM_RELATION 14
#define PGSTAT_KIND_BUILTIN_MIN PGSTAT_KIND_DATABASE
-#define PGSTAT_KIND_BUILTIN_MAX PGSTAT_KIND_WAL
+#define PGSTAT_KIND_BUILTIN_MAX PGSTAT_KIND_VACUUM_RELATION
#define PGSTAT_KIND_BUILTIN_SIZE (PGSTAT_KIND_BUILTIN_MAX + 1)
/* Custom stats kinds */
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index 14f19e5bcbe..ef2d6545953 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -2293,77 +2293,81 @@ pg_stat_user_tables| SELECT relid,
rev_all_visible_pages
FROM pg_stat_all_tables
WHERE ((schemaname <> ALL (ARRAY['pg_catalog'::name, 'information_schema'::name])) AND (schemaname !~ '^pg_toast'::text));
-pg_stat_vacuum_database| SELECT db.oid AS dboid,
- db.datname AS dbname,
- stats.db_blks_read,
- stats.db_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.delay_time,
- stats.total_time,
- stats.wraparound_failsafe,
- stats.errors
- FROM pg_database db,
- LATERAL pg_stat_get_vacuum_database(db.oid) stats(dboid, db_blks_read, db_blks_hit, total_blks_dirtied, total_blks_written, wal_records, wal_fpi, wal_bytes, blk_read_time, blk_write_time, delay_time, total_time, wraparound_failsafe, errors);
-pg_stat_vacuum_indexes| SELECT rel.oid AS relid,
- ns.nspname AS schemaname,
- rel.relname,
- stats.total_blks_read,
- stats.total_blks_hit,
- stats.total_blks_dirtied,
- stats.total_blks_written,
- stats.rel_blks_read,
- stats.rel_blks_hit,
- stats.pages_deleted,
- stats.tuples_deleted,
- stats.wal_records,
- stats.wal_fpi,
- stats.wal_bytes,
- stats.blk_read_time,
- stats.blk_write_time,
- stats.delay_time,
- stats.total_time
- FROM (pg_class rel
- JOIN pg_namespace ns ON ((ns.oid = rel.relnamespace))),
- LATERAL pg_stat_get_vacuum_indexes(rel.oid) stats(relid, total_blks_read, total_blks_hit, total_blks_dirtied, total_blks_written, rel_blks_read, rel_blks_hit, pages_deleted, tuples_deleted, wal_records, wal_fpi, wal_bytes, blk_read_time, blk_write_time, delay_time, total_time)
- WHERE (rel.relkind = 'i'::"char");
-pg_stat_vacuum_tables| SELECT ns.nspname AS schemaname,
- rel.relname,
- stats.relid,
- stats.total_blks_read,
- stats.total_blks_hit,
- stats.total_blks_dirtied,
- stats.total_blks_written,
- stats.rel_blks_read,
- stats.rel_blks_hit,
- stats.pages_scanned,
- stats.pages_removed,
- stats.vm_new_frozen_pages,
- stats.vm_new_visible_pages,
- stats.vm_new_visible_frozen_pages,
- stats.missed_dead_pages,
- stats.tuples_deleted,
- stats.tuples_frozen,
- stats.recently_dead_tuples,
- stats.missed_dead_tuples,
- stats.wraparound_failsafe,
- stats.index_vacuum_count,
- stats.wal_records,
- stats.wal_fpi,
- stats.wal_bytes,
- stats.blk_read_time,
- stats.blk_write_time,
- stats.delay_time,
- stats.total_time
- FROM (pg_class rel
- JOIN pg_namespace ns ON ((ns.oid = rel.relnamespace))),
- LATERAL pg_stat_get_vacuum_tables(rel.oid) stats(relid, total_blks_read, total_blks_hit, total_blks_dirtied, total_blks_written, rel_blks_read, rel_blks_hit, pages_scanned, pages_removed, vm_new_frozen_pages, vm_new_visible_pages, vm_new_visible_frozen_pages, missed_dead_pages, tuples_deleted, tuples_frozen, recently_dead_tuples, missed_dead_tuples, wraparound_failsafe, index_vacuum_count, wal_records, wal_fpi, wal_bytes, blk_read_time, blk_write_time, delay_time, total_time)
- WHERE (rel.relkind = 'r'::"char");
+pg_stat_vacuum_database| SELECT d.oid AS dboid,
+ d.datname AS dbname,
+ s.db_blks_read,
+ s.db_blks_hit,
+ s.total_blks_dirtied,
+ s.total_blks_written,
+ s.wal_records,
+ s.wal_fpi,
+ s.wal_bytes,
+ s.blk_read_time,
+ s.blk_write_time,
+ s.delay_time,
+ s.total_time,
+ s.wraparound_failsafe,
+ s.errors
+ FROM pg_database d,
+ LATERAL pg_stat_get_vacuum_database(d.oid) s(dboid, db_blks_read, db_blks_hit, total_blks_dirtied, total_blks_written, wal_records, wal_fpi, wal_bytes, blk_read_time, blk_write_time, delay_time, total_time, wraparound_failsafe, errors);
+pg_stat_vacuum_indexes| SELECT c.oid AS relid,
+ i.oid AS indexrelid,
+ n.nspname AS schemaname,
+ c.relname,
+ i.relname AS indexrelname,
+ s.total_blks_read,
+ s.total_blks_hit,
+ s.total_blks_dirtied,
+ s.total_blks_written,
+ s.rel_blks_read,
+ s.rel_blks_hit,
+ s.pages_deleted,
+ s.tuples_deleted,
+ s.wal_records,
+ s.wal_fpi,
+ s.wal_bytes,
+ s.blk_read_time,
+ s.blk_write_time,
+ s.delay_time,
+ s.total_time
+ FROM (((pg_class c
+ 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, total_blks_read, total_blks_hit, total_blks_dirtied, total_blks_written, rel_blks_read, rel_blks_hit, pages_deleted, tuples_deleted, wal_records, wal_fpi, wal_bytes, blk_read_time, blk_write_time, delay_time, total_time)
+ WHERE (c.relkind = ANY (ARRAY['r'::"char", 't'::"char", 'm'::"char"]));
+pg_stat_vacuum_tables| SELECT n.nspname AS schemaname,
+ c.relname,
+ s.relid,
+ s.total_blks_read,
+ s.total_blks_hit,
+ s.total_blks_dirtied,
+ s.total_blks_written,
+ s.rel_blks_read,
+ s.rel_blks_hit,
+ s.pages_scanned,
+ s.pages_removed,
+ s.vm_new_frozen_pages,
+ s.vm_new_visible_pages,
+ s.vm_new_visible_frozen_pages,
+ s.missed_dead_pages,
+ s.tuples_deleted,
+ s.tuples_frozen,
+ s.recently_dead_tuples,
+ s.missed_dead_tuples,
+ s.wraparound_failsafe,
+ s.index_vacuum_count,
+ s.wal_records,
+ s.wal_fpi,
+ s.wal_bytes,
+ s.blk_read_time,
+ s.blk_write_time,
+ s.delay_time,
+ s.total_time
+ FROM (pg_class c
+ JOIN pg_namespace n ON ((n.oid = c.relnamespace))),
+ LATERAL pg_stat_get_vacuum_tables(c.oid) s(relid, total_blks_read, total_blks_hit, total_blks_dirtied, total_blks_written, rel_blks_read, rel_blks_hit, pages_scanned, pages_removed, vm_new_frozen_pages, vm_new_visible_pages, vm_new_visible_frozen_pages, missed_dead_pages, tuples_deleted, tuples_frozen, recently_dead_tuples, missed_dead_tuples, wraparound_failsafe, index_vacuum_count, wal_records, wal_fpi, wal_bytes, blk_read_time, blk_write_time, delay_time, total_time)
+ WHERE (c.relkind = ANY (ARRAY['r'::"char", 't'::"char", 'm'::"char"]));
pg_stat_wal| SELECT wal_records,
wal_fpi,
wal_bytes,
diff --git a/src/test/regress/expected/vacuum_index_statistics.out b/src/test/regress/expected/vacuum_index_statistics.out
index 9e5d33342c9..4654a536ad6 100644
--- a/src/test/regress/expected/vacuum_index_statistics.out
+++ b/src/test/regress/expected/vacuum_index_statistics.out
@@ -30,9 +30,9 @@ VACUUM (PARALLEL 0, BUFFER_USAGE_LIMIT 128) vestat;
-- Must be empty.
SELECT *
FROM pg_stat_vacuum_indexes vt
-WHERE vt.relname = 'vestat';
- relid | schemaname | relname | total_blks_read | total_blks_hit | total_blks_dirtied | total_blks_written | rel_blks_read | rel_blks_hit | pages_deleted | tuples_deleted | wal_records | wal_fpi | wal_bytes | blk_read_time | blk_write_time | delay_time | total_time
--------+------------+---------+-----------------+----------------+--------------------+--------------------+---------------+--------------+---------------+----------------+-------------+---------+-----------+---------------+----------------+------------+------------
+WHERE vt.indexrelname = 'vestat';
+ relid | indexrelid | schemaname | relname | indexrelname | total_blks_read | total_blks_hit | total_blks_dirtied | total_blks_written | rel_blks_read | rel_blks_hit | pages_deleted | tuples_deleted | wal_records | wal_fpi | wal_bytes | blk_read_time | blk_write_time | delay_time | total_time
+-------+------------+------------+---------+--------------+-----------------+----------------+--------------------+--------------------+---------------+--------------+---------------+----------------+-------------+---------+-----------+---------------+----------------+------------+------------
(0 rows)
RESET track_vacuum_statistics;
@@ -55,12 +55,12 @@ ANALYZE vestat;
SELECT oid AS ioid from pg_class where relname = 'vestat_pkey' \gset
DELETE FROM vestat WHERE x % 2 = 0;
-- Before the first vacuum execution extended stats view is empty.
-SELECT vt.relname,relpages,pages_deleted,tuples_deleted
+SELECT vt.indexrelname,relpages,pages_deleted,tuples_deleted
FROM pg_stat_vacuum_indexes vt, pg_class c
-WHERE vt.relname = 'vestat_pkey' AND vt.relid = c.oid;
- relname | relpages | pages_deleted | tuples_deleted
--------------+----------+---------------+----------------
- vestat_pkey | 30 | 0 | 0
+WHERE vt.indexrelname = 'vestat_pkey' AND vt.indexrelid = c.oid;
+ indexrelname | relpages | pages_deleted | tuples_deleted
+--------------+----------+---------------+----------------
+ vestat_pkey | 30 | 0 | 0
(1 row)
SELECT relpages AS irp
@@ -72,22 +72,22 @@ CHECKPOINT;
-- The table and index extended vacuum statistics should show us that
-- vacuum frozed pages and clean up pages, but pages_removed stayed the same
-- because of not full table have cleaned up
-SELECT vt.relname,relpages-:irp = 0 AS relpages,pages_deleted = 0 AS pages_deleted,tuples_deleted > 0 AS tuples_deleted
+SELECT vt.indexrelname,relpages-:irp = 0 AS relpages,pages_deleted = 0 AS pages_deleted,tuples_deleted > 0 AS tuples_deleted
FROM pg_stat_vacuum_indexes vt, pg_class c
-WHERE vt.relname = 'vestat_pkey' AND vt.relid = c.oid;
- relname | relpages | pages_deleted | tuples_deleted
--------------+----------+---------------+----------------
- vestat_pkey | t | t | t
+WHERE vt.indexrelname = 'vestat_pkey' AND vt.indexrelid = c.oid;
+ indexrelname | relpages | pages_deleted | tuples_deleted
+--------------+----------+---------------+----------------
+ vestat_pkey | t | t | t
(1 row)
-SELECT vt.relname,relpages AS irp,pages_deleted AS ipd,tuples_deleted AS itd
+SELECT vt.indexrelname,relpages AS irp,pages_deleted AS ipd,tuples_deleted AS itd
FROM pg_stat_vacuum_indexes vt, pg_class c
-WHERE vt.relname = 'vestat_pkey' AND vt.relid = c.oid \gset
+WHERE vt.indexrelname = 'vestat_pkey' AND vt.indexrelid = c.oid \gset
-- Store WAL advances into variables
-SELECT wal_records AS iwr,wal_bytes AS iwb,wal_fpi AS ifpi FROM pg_stat_vacuum_indexes WHERE relname = 'vestat_pkey' \gset
+SELECT wal_records AS iwr,wal_bytes AS iwb,wal_fpi AS ifpi FROM pg_stat_vacuum_indexes WHERE indexrelname = 'vestat_pkey' \gset
-- Look into WAL records deltas.
SELECT wal_records > 0 AS diWR, wal_bytes > 0 AS diWB
-FROM pg_stat_vacuum_indexes WHERE relname = 'vestat_pkey';
+FROM pg_stat_vacuum_indexes WHERE indexrelname = 'vestat_pkey';
diwr | diwb
------+------
t | t
@@ -98,20 +98,20 @@ VACUUM (PARALLEL 0, BUFFER_USAGE_LIMIT 128, INDEX_CLEANUP ON) vestat;
-- it is necessary to check the wal statistics
CHECKPOINT;
-- pages_removed must be increased
-SELECT vt.relname,relpages-:irp = 0 AS relpages,pages_deleted-:ipd > 0 AS pages_deleted,tuples_deleted-:itd > 0 AS tuples_deleted
+SELECT vt.indexrelname,relpages-:irp = 0 AS relpages,pages_deleted-:ipd > 0 AS pages_deleted,tuples_deleted-:itd > 0 AS tuples_deleted
FROM pg_stat_vacuum_indexes vt, pg_class c
-WHERE vt.relname = 'vestat_pkey' AND vt.relid = c.oid;
- relname | relpages | pages_deleted | tuples_deleted
--------------+----------+---------------+----------------
- vestat_pkey | t | t | t
+WHERE vt.indexrelname = 'vestat_pkey' AND vt.indexrelid = c.oid;
+ indexrelname | relpages | pages_deleted | tuples_deleted
+--------------+----------+---------------+----------------
+ vestat_pkey | t | t | t
(1 row)
-SELECT vt.relname,relpages AS irp,pages_deleted AS ipd,tuples_deleted AS itd
+SELECT vt.indexrelname,relpages AS irp,pages_deleted AS ipd,tuples_deleted AS itd
FROM pg_stat_vacuum_indexes vt, pg_class c
-WHERE vt.relname = 'vestat_pkey' AND vt.relid = c.oid \gset
+WHERE vt.indexrelname = 'vestat_pkey' AND vt.indexrelid = c.oid \gset
-- Store WAL advances into variables
SELECT wal_records-:iwr AS diwr, wal_bytes-:iwb AS diwb, wal_fpi-:ifpi AS difpi
-FROM pg_stat_vacuum_indexes WHERE relname = 'vestat_pkey' \gset
+FROM pg_stat_vacuum_indexes WHERE indexrelname = 'vestat_pkey' \gset
-- WAL advance should be detected.
SELECT :diwr > 0 AS diWR, :diwb > 0 AS diWB;
diwr | diwb
@@ -120,7 +120,7 @@ SELECT :diwr > 0 AS diWR, :diwb > 0 AS diWB;
(1 row)
-- Store WAL advances into variables
-SELECT wal_records AS iwr,wal_bytes AS iwb,wal_fpi AS ifpi FROM pg_stat_vacuum_indexes WHERE relname = 'vestat_pkey' \gset
+SELECT wal_records AS iwr,wal_bytes AS iwb,wal_fpi AS ifpi FROM pg_stat_vacuum_indexes WHERE indexrelname = 'vestat_pkey' \gset
INSERT INTO vestat SELECT x FROM generate_series(1,:sample_size) as x;
DELETE FROM vestat WHERE x % 2 = 0;
-- VACUUM FULL doesn't report to stat collector. So, no any advancements of statistics
@@ -130,7 +130,7 @@ VACUUM FULL vestat;
CHECKPOINT;
-- Store WAL advances into variables
SELECT wal_records-:iwr AS diwr2, wal_bytes-:iwb AS diwb2, wal_fpi-:ifpi AS difpi2
-FROM pg_stat_vacuum_indexes WHERE relname = 'vestat_pkey' \gset
+FROM pg_stat_vacuum_indexes WHERE indexrelname = 'vestat_pkey' \gset
-- WAL and other statistics advance should not be detected.
SELECT :diwr2=0 AS diWR, :difpi2=0 AS iFPI, :diwb2=0 AS diWB;
diwr | ifpi | diwb
@@ -138,19 +138,19 @@ SELECT :diwr2=0 AS diWR, :difpi2=0 AS iFPI, :diwb2=0 AS diWB;
t | t | t
(1 row)
-SELECT vt.relname,relpages-:irp < 0 AS relpages,pages_deleted-:ipd = 0 AS pages_deleted,tuples_deleted-:itd = 0 AS tuples_deleted
+SELECT vt.indexrelname,relpages-:irp < 0 AS relpages,pages_deleted-:ipd = 0 AS pages_deleted,tuples_deleted-:itd = 0 AS tuples_deleted
FROM pg_stat_vacuum_indexes vt, pg_class c
-WHERE vt.relname = 'vestat_pkey' AND vt.relid = c.oid;
- relname | relpages | pages_deleted | tuples_deleted
--------------+----------+---------------+----------------
- vestat_pkey | t | t | t
+WHERE vt.indexrelname = 'vestat_pkey' AND vt.indexrelid = c.oid;
+ indexrelname | relpages | pages_deleted | tuples_deleted
+--------------+----------+---------------+----------------
+ vestat_pkey | t | t | t
(1 row)
-SELECT vt.relname,relpages AS irp,pages_deleted AS ipd,tuples_deleted AS itd
+SELECT vt.indexrelname,relpages AS irp,pages_deleted AS ipd,tuples_deleted AS itd
FROM pg_stat_vacuum_indexes vt, pg_class c
-WHERE vt.relname = 'vestat_pkey' AND vt.relid = c.oid \gset
+WHERE vt.indexrelname = 'vestat_pkey' AND vt.indexrelid = c.oid \gset
-- Store WAL advances into variables
-SELECT wal_records AS iwr,wal_bytes AS iwb,wal_fpi AS ifpi FROM pg_stat_vacuum_indexes WHERE relname = 'vestat_pkey' \gset
+SELECT wal_records AS iwr,wal_bytes AS iwb,wal_fpi AS ifpi FROM pg_stat_vacuum_indexes WHERE indexrelname = 'vestat_pkey' \gset
DELETE FROM vestat;
TRUNCATE vestat;
VACUUM (PARALLEL 0, BUFFER_USAGE_LIMIT 128, INDEX_CLEANUP ON) vestat;
@@ -158,7 +158,7 @@ VACUUM (PARALLEL 0, BUFFER_USAGE_LIMIT 128, INDEX_CLEANUP ON) vestat;
CHECKPOINT;
-- Store WAL advances into variables after removing all tuples from the table
SELECT wal_records-:iwr AS diwr3, wal_bytes-:iwb AS diwb3, wal_fpi-:ifpi AS difpi3
-FROM pg_stat_vacuum_indexes WHERE relname = 'vestat_pkey' \gset
+FROM pg_stat_vacuum_indexes WHERE indexrelname = 'vestat_pkey' \gset
--There are nothing changed
SELECT :diwr3=0 AS diWR, :difpi3=0 AS iFPI, :diwb3=0 AS diWB;
diwr | ifpi | diwb
@@ -171,12 +171,12 @@ SELECT :diwr3=0 AS diWR, :difpi3=0 AS iFPI, :diwb3=0 AS diWB;
-- in vacuum extended statistics.
-- The pages_frozen, pages_scanned values shouldn't be changed
--
-SELECT vt.relname,relpages-:irp = 0 AS relpages,pages_deleted-:ipd = 0 AS pages_deleted,tuples_deleted-:itd = 0 AS tuples_deleted
+SELECT vt.indexrelname,relpages-:irp = 0 AS relpages,pages_deleted-:ipd = 0 AS pages_deleted,tuples_deleted-:itd = 0 AS tuples_deleted
FROM pg_stat_vacuum_indexes vt, pg_class c
-WHERE vt.relname = 'vestat_pkey' AND vt.relid = c.oid;
- relname | relpages | pages_deleted | tuples_deleted
--------------+----------+---------------+----------------
- vestat_pkey | f | t | t
+WHERE vt.indexrelname = 'vestat_pkey' AND vt.indexrelid = c.oid;
+ indexrelname | relpages | pages_deleted | tuples_deleted
+--------------+----------+---------------+----------------
+ vestat_pkey | f | t | t
(1 row)
DROP TABLE vestat;
diff --git a/src/test/regress/sql/vacuum_index_statistics.sql b/src/test/regress/sql/vacuum_index_statistics.sql
index 9b7e645187d..57e5420b9b6 100644
--- a/src/test/regress/sql/vacuum_index_statistics.sql
+++ b/src/test/regress/sql/vacuum_index_statistics.sql
@@ -27,7 +27,7 @@ VACUUM (PARALLEL 0, BUFFER_USAGE_LIMIT 128) vestat;
-- Must be empty.
SELECT *
FROM pg_stat_vacuum_indexes vt
-WHERE vt.relname = 'vestat';
+WHERE vt.indexrelname = 'vestat';
RESET track_vacuum_statistics;
DROP TABLE vestat CASCADE;
@@ -49,9 +49,9 @@ SELECT oid AS ioid from pg_class where relname = 'vestat_pkey' \gset
DELETE FROM vestat WHERE x % 2 = 0;
-- Before the first vacuum execution extended stats view is empty.
-SELECT vt.relname,relpages,pages_deleted,tuples_deleted
+SELECT vt.indexrelname,relpages,pages_deleted,tuples_deleted
FROM pg_stat_vacuum_indexes vt, pg_class c
-WHERE vt.relname = 'vestat_pkey' AND vt.relid = c.oid;
+WHERE vt.indexrelname = 'vestat_pkey' AND vt.indexrelid = c.oid;
SELECT relpages AS irp
FROM pg_class c
WHERE relname = 'vestat_pkey' \gset
@@ -63,19 +63,19 @@ CHECKPOINT;
-- The table and index extended vacuum statistics should show us that
-- vacuum frozed pages and clean up pages, but pages_removed stayed the same
-- because of not full table have cleaned up
-SELECT vt.relname,relpages-:irp = 0 AS relpages,pages_deleted = 0 AS pages_deleted,tuples_deleted > 0 AS tuples_deleted
+SELECT vt.indexrelname,relpages-:irp = 0 AS relpages,pages_deleted = 0 AS pages_deleted,tuples_deleted > 0 AS tuples_deleted
FROM pg_stat_vacuum_indexes vt, pg_class c
-WHERE vt.relname = 'vestat_pkey' AND vt.relid = c.oid;
-SELECT vt.relname,relpages AS irp,pages_deleted AS ipd,tuples_deleted AS itd
+WHERE vt.indexrelname = 'vestat_pkey' AND vt.indexrelid = c.oid;
+SELECT vt.indexrelname,relpages AS irp,pages_deleted AS ipd,tuples_deleted AS itd
FROM pg_stat_vacuum_indexes vt, pg_class c
-WHERE vt.relname = 'vestat_pkey' AND vt.relid = c.oid \gset
+WHERE vt.indexrelname = 'vestat_pkey' AND vt.indexrelid = c.oid \gset
-- Store WAL advances into variables
-SELECT wal_records AS iwr,wal_bytes AS iwb,wal_fpi AS ifpi FROM pg_stat_vacuum_indexes WHERE relname = 'vestat_pkey' \gset
+SELECT wal_records AS iwr,wal_bytes AS iwb,wal_fpi AS ifpi FROM pg_stat_vacuum_indexes WHERE indexrelname = 'vestat_pkey' \gset
-- Look into WAL records deltas.
SELECT wal_records > 0 AS diWR, wal_bytes > 0 AS diWB
-FROM pg_stat_vacuum_indexes WHERE relname = 'vestat_pkey';
+FROM pg_stat_vacuum_indexes WHERE indexrelname = 'vestat_pkey';
DELETE FROM vestat;;
VACUUM (PARALLEL 0, BUFFER_USAGE_LIMIT 128, INDEX_CLEANUP ON) vestat;
@@ -83,22 +83,22 @@ VACUUM (PARALLEL 0, BUFFER_USAGE_LIMIT 128, INDEX_CLEANUP ON) vestat;
CHECKPOINT;
-- pages_removed must be increased
-SELECT vt.relname,relpages-:irp = 0 AS relpages,pages_deleted-:ipd > 0 AS pages_deleted,tuples_deleted-:itd > 0 AS tuples_deleted
+SELECT vt.indexrelname,relpages-:irp = 0 AS relpages,pages_deleted-:ipd > 0 AS pages_deleted,tuples_deleted-:itd > 0 AS tuples_deleted
FROM pg_stat_vacuum_indexes vt, pg_class c
-WHERE vt.relname = 'vestat_pkey' AND vt.relid = c.oid;
-SELECT vt.relname,relpages AS irp,pages_deleted AS ipd,tuples_deleted AS itd
+WHERE vt.indexrelname = 'vestat_pkey' AND vt.indexrelid = c.oid;
+SELECT vt.indexrelname,relpages AS irp,pages_deleted AS ipd,tuples_deleted AS itd
FROM pg_stat_vacuum_indexes vt, pg_class c
-WHERE vt.relname = 'vestat_pkey' AND vt.relid = c.oid \gset
+WHERE vt.indexrelname = 'vestat_pkey' AND vt.indexrelid = c.oid \gset
-- Store WAL advances into variables
SELECT wal_records-:iwr AS diwr, wal_bytes-:iwb AS diwb, wal_fpi-:ifpi AS difpi
-FROM pg_stat_vacuum_indexes WHERE relname = 'vestat_pkey' \gset
+FROM pg_stat_vacuum_indexes WHERE indexrelname = 'vestat_pkey' \gset
-- WAL advance should be detected.
SELECT :diwr > 0 AS diWR, :diwb > 0 AS diWB;
-- Store WAL advances into variables
-SELECT wal_records AS iwr,wal_bytes AS iwb,wal_fpi AS ifpi FROM pg_stat_vacuum_indexes WHERE relname = 'vestat_pkey' \gset
+SELECT wal_records AS iwr,wal_bytes AS iwb,wal_fpi AS ifpi FROM pg_stat_vacuum_indexes WHERE indexrelname = 'vestat_pkey' \gset
INSERT INTO vestat SELECT x FROM generate_series(1,:sample_size) as x;
DELETE FROM vestat WHERE x % 2 = 0;
@@ -110,20 +110,20 @@ CHECKPOINT;
-- Store WAL advances into variables
SELECT wal_records-:iwr AS diwr2, wal_bytes-:iwb AS diwb2, wal_fpi-:ifpi AS difpi2
-FROM pg_stat_vacuum_indexes WHERE relname = 'vestat_pkey' \gset
+FROM pg_stat_vacuum_indexes WHERE indexrelname = 'vestat_pkey' \gset
-- WAL and other statistics advance should not be detected.
SELECT :diwr2=0 AS diWR, :difpi2=0 AS iFPI, :diwb2=0 AS diWB;
-SELECT vt.relname,relpages-:irp < 0 AS relpages,pages_deleted-:ipd = 0 AS pages_deleted,tuples_deleted-:itd = 0 AS tuples_deleted
+SELECT vt.indexrelname,relpages-:irp < 0 AS relpages,pages_deleted-:ipd = 0 AS pages_deleted,tuples_deleted-:itd = 0 AS tuples_deleted
FROM pg_stat_vacuum_indexes vt, pg_class c
-WHERE vt.relname = 'vestat_pkey' AND vt.relid = c.oid;
-SELECT vt.relname,relpages AS irp,pages_deleted AS ipd,tuples_deleted AS itd
+WHERE vt.indexrelname = 'vestat_pkey' AND vt.indexrelid = c.oid;
+SELECT vt.indexrelname,relpages AS irp,pages_deleted AS ipd,tuples_deleted AS itd
FROM pg_stat_vacuum_indexes vt, pg_class c
-WHERE vt.relname = 'vestat_pkey' AND vt.relid = c.oid \gset
+WHERE vt.indexrelname = 'vestat_pkey' AND vt.indexrelid = c.oid \gset
-- Store WAL advances into variables
-SELECT wal_records AS iwr,wal_bytes AS iwb,wal_fpi AS ifpi FROM pg_stat_vacuum_indexes WHERE relname = 'vestat_pkey' \gset
+SELECT wal_records AS iwr,wal_bytes AS iwb,wal_fpi AS ifpi FROM pg_stat_vacuum_indexes WHERE indexrelname = 'vestat_pkey' \gset
DELETE FROM vestat;
TRUNCATE vestat;
@@ -133,7 +133,7 @@ CHECKPOINT;
-- Store WAL advances into variables after removing all tuples from the table
SELECT wal_records-:iwr AS diwr3, wal_bytes-:iwb AS diwb3, wal_fpi-:ifpi AS difpi3
-FROM pg_stat_vacuum_indexes WHERE relname = 'vestat_pkey' \gset
+FROM pg_stat_vacuum_indexes WHERE indexrelname = 'vestat_pkey' \gset
--There are nothing changed
SELECT :diwr3=0 AS diWR, :difpi3=0 AS iFPI, :diwb3=0 AS diWB;
@@ -143,9 +143,9 @@ SELECT :diwr3=0 AS diWR, :difpi3=0 AS iFPI, :diwb3=0 AS diWB;
-- in vacuum extended statistics.
-- The pages_frozen, pages_scanned values shouldn't be changed
--
-SELECT vt.relname,relpages-:irp = 0 AS relpages,pages_deleted-:ipd = 0 AS pages_deleted,tuples_deleted-:itd = 0 AS tuples_deleted
+SELECT vt.indexrelname,relpages-:irp = 0 AS relpages,pages_deleted-:ipd = 0 AS pages_deleted,tuples_deleted-:itd = 0 AS tuples_deleted
FROM pg_stat_vacuum_indexes vt, pg_class c
-WHERE vt.relname = 'vestat_pkey' AND vt.relid = c.oid;
+WHERE vt.indexrelname = 'vestat_pkey' AND vt.indexrelid = c.oid;
DROP TABLE vestat;
RESET track_vacuum_statistics;
--
2.34.1