On Sat, Apr 04, 2026 at 12:48:28PM -0500, Sami Imseih wrote: >> If we did report booleans, I would probably argue for just reporting >> dovacuum and doanalyze and calling out the criteria for why they may be >> false even when it looks like the table needs processing. > > Yes, we only require a needs_analyze and needs_vacuum. The latter > can be set to true due to thresholds or wraparound. But, I don't think we > should rely on the dovacuum or doanalyze, instead we can just have a flag > in AutoVacuumScores->needs and track what is needed. This will separate > the autovacuum processing from the reporting.
Sorry for going in circles about this, but I'm not seeing why we wouldn't just return the booleans that relation_needs_vacanalyze() already returns. I think the question people will have is "what will autovacuum process and in what order?", and if we aren't giving them the exact same information that autovacuum is using to make its decisions, then I'm not sure what is the point. It's true that someone might disable autovacuum for a table and that it would otherwise be processed, but so be it. Concretely, like the attached 0003. IMHO this feels much more natural than giving folks booleans that usually represents dovacuum/doanalyze but that don't in certain cases. -- nathan
>From 5964ff180193c0a976beef38609d4fcab38383a5 Mon Sep 17 00:00:00 2001 From: Nathan Bossart <[email protected]> Date: Thu, 2 Apr 2026 14:17:11 -0500 Subject: [PATCH v12 1/3] refactor autovacuum subroutine in preparation for system view --- src/backend/postmaster/autovacuum.c | 73 ++++++----------------------- 1 file changed, 15 insertions(+), 58 deletions(-) diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index 8400e6722cc..1be1ba8a25f 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -370,13 +370,8 @@ static void FreeWorkerInfo(int code, Datum arg); static autovac_table *table_recheck_autovac(Oid relid, HTAB *table_toast_map, TupleDesc pg_class_desc, int effective_multixact_freeze_max_age); -static void recheck_relation_needs_vacanalyze(Oid relid, AutoVacOpts *avopts, - Form_pg_class classForm, - int effective_multixact_freeze_max_age, - bool *dovacuum, bool *doanalyze, bool *wraparound); static void relation_needs_vacanalyze(Oid relid, AutoVacOpts *relopts, Form_pg_class classForm, - PgStat_StatTabEntry *tabentry, int effective_multixact_freeze_max_age, int elevel, bool *dovacuum, bool *doanalyze, bool *wraparound, @@ -2029,7 +2024,6 @@ do_autovacuum(void) while ((tuple = heap_getnext(relScan, ForwardScanDirection)) != NULL) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); - PgStat_StatTabEntry *tabentry; AutoVacOpts *relopts; Oid relid; bool dovacuum; @@ -2070,11 +2064,9 @@ do_autovacuum(void) /* Fetch reloptions and the pgstat entry for this table */ relopts = extract_autovac_opts(tuple, pg_class_desc); - tabentry = pgstat_fetch_stat_tabentry_ext(classForm->relisshared, - relid); /* Check if it needs vacuum or analyze */ - relation_needs_vacanalyze(relid, relopts, classForm, tabentry, + relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, DEBUG3, &dovacuum, &doanalyze, &wraparound, @@ -2121,8 +2113,6 @@ do_autovacuum(void) /* Release stuff to avoid per-relation leakage */ if (relopts) pfree(relopts); - if (tabentry) - pfree(tabentry); } table_endscan(relScan); @@ -2137,7 +2127,6 @@ do_autovacuum(void) while ((tuple = heap_getnext(relScan, ForwardScanDirection)) != NULL) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); - PgStat_StatTabEntry *tabentry; Oid relid; AutoVacOpts *relopts; bool free_relopts = false; @@ -2171,11 +2160,7 @@ do_autovacuum(void) relopts = &hentry->ar_reloptions; } - /* Fetch the pgstat entry for this table */ - tabentry = pgstat_fetch_stat_tabentry_ext(classForm->relisshared, - relid); - - relation_needs_vacanalyze(relid, relopts, classForm, tabentry, + relation_needs_vacanalyze(relid, relopts, classForm, effective_multixact_freeze_max_age, DEBUG3, &dovacuum, &doanalyze, &wraparound, @@ -2194,8 +2179,6 @@ do_autovacuum(void) /* Release stuff to avoid leakage */ if (free_relopts) pfree(relopts); - if (tabentry) - pfree(tabentry); } table_endscan(relScan); @@ -2834,6 +2817,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, bool wraparound; AutoVacOpts *avopts; bool free_avopts = false; + AutoVacuumScores scores; /* fetch the relation's relcache entry */ classTup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relid)); @@ -2859,9 +2843,11 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, avopts = &hentry->ar_reloptions; } - recheck_relation_needs_vacanalyze(relid, avopts, classForm, - effective_multixact_freeze_max_age, - &dovacuum, &doanalyze, &wraparound); + relation_needs_vacanalyze(relid, avopts, classForm, + effective_multixact_freeze_max_age, + DEBUG3, + &dovacuum, &doanalyze, &wraparound, + &scores); /* OK, it needs something done */ if (doanalyze || dovacuum) @@ -2970,41 +2956,6 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, return tab; } -/* - * recheck_relation_needs_vacanalyze - * - * Subroutine for table_recheck_autovac. - * - * Fetch the pgstat of a relation and recheck whether a relation - * needs to be vacuumed or analyzed. - */ -static void -recheck_relation_needs_vacanalyze(Oid relid, - AutoVacOpts *avopts, - Form_pg_class classForm, - int effective_multixact_freeze_max_age, - bool *dovacuum, - bool *doanalyze, - bool *wraparound) -{ - PgStat_StatTabEntry *tabentry; - AutoVacuumScores scores; - - /* fetch the pgstat table entry */ - tabentry = pgstat_fetch_stat_tabentry_ext(classForm->relisshared, - relid); - - relation_needs_vacanalyze(relid, avopts, classForm, tabentry, - effective_multixact_freeze_max_age, - DEBUG3, - dovacuum, doanalyze, wraparound, - &scores); - - /* Release tabentry to avoid leakage */ - if (tabentry) - pfree(tabentry); -} - /* * relation_needs_vacanalyze * @@ -3089,7 +3040,6 @@ static void relation_needs_vacanalyze(Oid relid, AutoVacOpts *relopts, Form_pg_class classForm, - PgStat_StatTabEntry *tabentry, int effective_multixact_freeze_max_age, int elevel, /* output params below */ @@ -3098,6 +3048,7 @@ relation_needs_vacanalyze(Oid relid, bool *wraparound, AutoVacuumScores *scores) { + PgStat_StatTabEntry *tabentry; bool force_vacuum; bool av_enabled; @@ -3265,6 +3216,8 @@ relation_needs_vacanalyze(Oid relid, * vacuuming only, so don't vacuum (or analyze) anything that's not being * forced. */ + tabentry = pgstat_fetch_stat_tabentry_ext(classForm->relisshared, + relid); if (!tabentry) return; @@ -3353,6 +3306,10 @@ relation_needs_vacanalyze(Oid relid, vactuples, vacthresh, scores->vac, anltuples, anlthresh, scores->anl, scores->xid, scores->mxid); + + /* Release tabentry to avoid leakage */ + if (tabentry) + pfree(tabentry); } /* -- 2.50.1 (Apple Git-155)
>From 7cc2c0212da9f7836a6bd4aa20303ea563f6e2a6 Mon Sep 17 00:00:00 2001 From: Nathan Bossart <[email protected]> Date: Thu, 2 Apr 2026 15:47:19 -0500 Subject: [PATCH v12 2/3] add pg_stat_autovacuum_scores system view --- doc/src/sgml/maintenance.sgml | 6 ++ doc/src/sgml/monitoring.sgml | 143 +++++++++++++++++++++++++++ src/backend/catalog/system_views.sql | 15 +++ src/backend/postmaster/autovacuum.c | 70 +++++++++++++ src/include/catalog/pg_proc.dat | 7 ++ src/test/regress/expected/rules.out | 12 +++ 6 files changed, 253 insertions(+) diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 0d2a28207ed..906aca2c228 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -1164,6 +1164,12 @@ analyze threshold = analyze base threshold + analyze scale factor * number of tu <literal>2.0</literal> effectively doubles the <emphasis>analyze</emphasis> component score. </para> + + <para> + The <link linkend="monitoring-pg-stat-autovacuum-scores-view"> + <structname>pg_stat_autovacuum_scores</structname></link> + view shows the current scores of all tables in the current database. + </para> </sect3> </sect2> </sect1> diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index 312374da5e0..b8b2967aa36 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -596,6 +596,16 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser user tables are shown.</entry> </row> + <row> + <entry><structname>pg_stat_autovacuum_scores</structname><indexterm><primary>pg_stat_autovacuum_scores</primary></indexterm></entry> + <entry> + One row for each table in the current database, showing the current + autovacuum scores for that specific table. See + <link linkend="monitoring-pg-stat-autovacuum-scores-view"> + <structname>pg_stat_autovacuum_scores</structname></link> for details. + </entry> + </row> + <row> <entry><structname>pg_stat_all_indexes</structname><indexterm><primary>pg_stat_all_indexes</primary></indexterm></entry> <entry> @@ -4502,6 +4512,139 @@ description | Waiting for a newly initialized WAL file to reach durable storage </sect2> + <sect2 id="monitoring-pg-stat-autovacuum-scores-view"> + <title><structname>pg_stat_autovacuum_scores</structname></title> + + <indexterm> + <primary>pg_stat_autovacuum_scores</primary> + </indexterm> + + <para> + The <structname>pg_stat_autovacuum_scores</structname> view will contain one + row for each table in the current database (including TOAST tables), showing + the current autovacuum scores for that specific table. Tables deemed + eligible for processing are prioritized based on their + <structfield>score</structfield>, with higher scores indicating higher + priority. See <xref linkend="autovacuum-priority"/> for more information. + </para> + + <table id="pg-stat-autovacuum-scores-view" xreflabel="pg_stat_autovacuum_scores"> + <title><structname>pg_stat_autovacuum_scores</structname> View</title> + <tgroup cols="1"> + <thead> + <row> + <entry role="catalog_table_entry"><para role="column_definition"> + Column Type + </para> + <para> + Description + </para></entry> + </row> + </thead> + + <tbody> + <row> + <entry role="catalog_table_entry"><para role="column_definition"> + <structfield>relid</structfield> <type>oid</type> + </para> + <para> + Oid of the table. + </para></entry> + </row> + + <row> + <entry role="catalog_table_entry"><para role="column_definition"> + <structfield>schemaname</structfield> <type>name</type> + </para> + <para> + Name of the schema that the table is in. + </para></entry> + </row> + + <row> + <entry role="catalog_table_entry"><para role="column_definition"> + <structfield>relname</structfield> <type>name</type> + </para> + <para> + Name of the table. + </para></entry> + </row> + + <row> + <entry role="catalog_table_entry"><para role="column_definition"> + <structfield>score</structfield> <type>double precision</type> + </para> + <para> + Maximum value of all component scores. This is the value that + autovacuum uses to sort the list of tables to process. When the + "weight" parameters are set to their default values of + <literal>1.0</literal>, scores greater than or equal to + <literal>1.0</literal> indicate the table will be processed (unless + autovacuum is disabled and neither <literal>xid_score</literal> nor + <literal>mxid_score</literal> are greater than or equal to + <literal>1.0</literal>). + </para></entry> + </row> + + <row> + <entry role="catalog_table_entry"><para role="column_definition"> + <structfield>xid_score</structfield> <type>double precision</type> + </para> + <para> + Transaction ID age component score. Scores greater than or equal to + <xref linkend="guc-autovacuum-freeze-score-weight"/> indicate the table + will be vacuumed. + </para></entry> + </row> + + <row> + <entry role="catalog_table_entry"><para role="column_definition"> + <structfield>mxid_score</structfield> <type>double precision</type> + </para> + <para> + Multixact ID age component score. Scores greater than or equal to + <xref linkend="guc-autovacuum-multixact-freeze-score-weight"/> indicate + the table will be vacuumed. + </para></entry> + </row> + + <row> + <entry role="catalog_table_entry"><para role="column_definition"> + <structfield>vacuum_score</structfield> <type>double precision</type> + </para> + <para> + Vacuum component score. Scores greater than or equal to + <xref linkend="guc-autovacuum-vacuum-score-weight"/> indicate the table + will be vacuumed (unless autovacuum is disabled). + </para></entry> + </row> + + <row> + <entry role="catalog_table_entry"><para role="column_definition"> + <structfield>vacuum_insert_score</structfield> <type>double precision</type> + </para> + <para> + Vacuum insert component score. Scores greater than or equal to + <xref linkend="guc-autovacuum-vacuum-insert-score-weight"/> indicate the + table will be vacuumed (unless autovacuum is disabled). + </para></entry> + </row> + + <row> + <entry role="catalog_table_entry"><para role="column_definition"> + <structfield>analyze_score</structfield> <type>double precision</type> + </para> + <para> + Analyze component score. Scores greater than or equal to + <xref linkend="guc-autovacuum-analyze-score-weight"/> indicate the table + will be analyzed (unless autovacuum is disabled). + </para></entry> + </row> + </tbody> + </tgroup> + </table> + </sect2> + <sect2 id="monitoring-pg-stat-all-indexes-view"> <title><structname>pg_stat_all_indexes</structname></title> diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index eba25aa3e4d..5c2f2977965 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -795,6 +795,21 @@ CREATE VIEW pg_stat_xact_user_tables AS WHERE schemaname NOT IN ('pg_catalog', 'information_schema') AND schemaname !~ '^pg_toast'; +CREATE VIEW pg_stat_autovacuum_scores AS + SELECT + s.oid AS relid, + n.nspname AS schemaname, + c.relname AS relname, + s.score, + s.xid_score, + s.mxid_score, + s.vacuum_score, + s.vacuum_insert_score, + s.analyze_score + FROM pg_stat_get_autovacuum_scores() s + JOIN pg_class c on c.oid = s.oid + LEFT JOIN pg_namespace n ON n.oid = c.relnamespace; + CREATE VIEW pg_statio_all_tables AS SELECT C.oid AS relid, diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index 1be1ba8a25f..c6c601dd3ad 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -80,6 +80,7 @@ #include "catalog/pg_namespace.h" #include "commands/vacuum.h" #include "common/int.h" +#include "funcapi.h" #include "lib/ilist.h" #include "libpq/pqsignal.h" #include "miscadmin.h" @@ -111,6 +112,7 @@ #include "utils/syscache.h" #include "utils/timeout.h" #include "utils/timestamp.h" +#include "utils/tuplestore.h" #include "utils/wait_event.h" @@ -3623,3 +3625,71 @@ check_av_worker_gucs(void) errdetail("The server will only start up to \"autovacuum_worker_slots\" (%d) autovacuum workers at a given time.", autovacuum_worker_slots))); } + +/* + * pg_stat_get_autovacuum_scores + * + * Returns current autovacuum scores for all relevant tables in the current + * database. + */ +Datum +pg_stat_get_autovacuum_scores(PG_FUNCTION_ARGS) +{ + int effective_multixact_freeze_max_age; + Relation rel; + TableScanDesc scan; + HeapTuple tup; + ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; + + InitMaterializedSRF(fcinfo, 0); + + /* some prerequisite initialization */ + effective_multixact_freeze_max_age = MultiXactMemberFreezeThreshold(); + recentXid = ReadNextTransactionId(); + recentMulti = ReadNextMultiXactId(); + + /* scan pg_class */ + rel = table_open(RelationRelationId, AccessShareLock); + scan = table_beginscan_catalog(rel, 0, NULL); + while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL) + { + Form_pg_class form = (Form_pg_class) GETSTRUCT(tup); + AutoVacOpts *avopts; + bool dovacuum; + bool doanalyze; + bool wraparound; + AutoVacuumScores scores; + Datum vals[7]; + bool nulls[7] = {false}; + + /* skip ineligible entries */ + if (form->relkind != RELKIND_RELATION && + form->relkind != RELKIND_MATVIEW && + form->relkind != RELKIND_TOASTVALUE) + continue; + if (form->relpersistence == RELPERSISTENCE_TEMP) + continue; + + avopts = extract_autovac_opts(tup, RelationGetDescr(rel)); + relation_needs_vacanalyze(form->oid, avopts, form, + effective_multixact_freeze_max_age, 0, + &dovacuum, &doanalyze, &wraparound, + &scores); + if (avopts) + pfree(avopts); + + vals[0] = ObjectIdGetDatum(form->oid); + vals[1] = Float8GetDatum(scores.max); + vals[2] = Float8GetDatum(scores.xid); + vals[3] = Float8GetDatum(scores.mxid); + vals[4] = Float8GetDatum(scores.vac); + vals[5] = Float8GetDatum(scores.vac_ins); + vals[6] = Float8GetDatum(scores.anl); + + tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, vals, nulls); + } + table_endscan(scan); + table_close(rel, AccessShareLock); + + return (Datum) 0; +} diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index bd177aebfcb..0de3bb52eb2 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -5667,6 +5667,13 @@ proname => 'pg_stat_get_total_autoanalyze_time', provolatile => 's', proparallel => 'r', prorettype => 'float8', proargtypes => 'oid', prosrc => 'pg_stat_get_total_autoanalyze_time' }, +{ oid => '8409', descr => 'autovacuum scores', + proname => 'pg_stat_get_autovacuum_scores', prorows => '100', proretset => 't', + provolatile => 'v', proparallel => 'u', prorettype => 'record', proargtypes => '', + proallargtypes => '{oid,float8,float8,float8,float8,float8,float8}', + proargmodes => '{o,o,o,o,o,o,o}', + proargnames => '{oid,score,xid_score,mxid_score,vacuum_score,vacuum_insert_score,analyze_score}', + prosrc => 'pg_stat_get_autovacuum_scores' }, { oid => '1936', descr => 'statistics: currently active backend IDs', proname => 'pg_stat_get_backend_idset', prorows => '100', proretset => 't', provolatile => 's', proparallel => 'r', prorettype => 'int4', diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index 81a73c426d2..b167e8d3cab 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -1860,6 +1860,18 @@ pg_stat_archiver| SELECT archived_count, last_failed_time, stats_reset FROM pg_stat_get_archiver() s(archived_count, last_archived_wal, last_archived_time, failed_count, last_failed_wal, last_failed_time, stats_reset); +pg_stat_autovacuum_scores| SELECT s.oid AS relid, + n.nspname AS schemaname, + c.relname, + s.score, + s.xid_score, + s.mxid_score, + s.vacuum_score, + s.vacuum_insert_score, + s.analyze_score + FROM ((pg_stat_get_autovacuum_scores() s(oid, score, xid_score, mxid_score, vacuum_score, vacuum_insert_score, analyze_score) + JOIN pg_class c ON ((c.oid = s.oid))) + LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))); pg_stat_bgwriter| SELECT pg_stat_get_bgwriter_buf_written_clean() AS buffers_clean, pg_stat_get_bgwriter_maxwritten_clean() AS maxwritten_clean, pg_stat_get_buf_alloc() AS buffers_alloc, -- 2.50.1 (Apple Git-155)
>From c1da752cc6f649d1ee4694091e12481232b569ca Mon Sep 17 00:00:00 2001 From: Nathan Bossart <[email protected]> Date: Sat, 4 Apr 2026 14:08:43 -0500 Subject: [PATCH v12 3/3] add booleans to view --- doc/src/sgml/monitoring.sgml | 43 ++++++++++++++++++++++------ src/backend/catalog/system_views.sql | 5 +++- src/backend/postmaster/autovacuum.c | 7 +++-- src/include/catalog/pg_proc.dat | 6 ++-- src/test/regress/expected/rules.out | 7 +++-- 5 files changed, 51 insertions(+), 17 deletions(-) diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index b8b2967aa36..3888292bec3 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -4576,13 +4576,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage </para> <para> Maximum value of all component scores. This is the value that - autovacuum uses to sort the list of tables to process. When the - "weight" parameters are set to their default values of - <literal>1.0</literal>, scores greater than or equal to - <literal>1.0</literal> indicate the table will be processed (unless - autovacuum is disabled and neither <literal>xid_score</literal> nor - <literal>mxid_score</literal> are greater than or equal to - <literal>1.0</literal>). + autovacuum uses to sort the list of tables to process. </para></entry> </row> @@ -4593,7 +4587,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage <para> Transaction ID age component score. Scores greater than or equal to <xref linkend="guc-autovacuum-freeze-score-weight"/> indicate the table - will be vacuumed. + will be vacuumed for transaction ID wraparound prevention. </para></entry> </row> @@ -4604,7 +4598,7 @@ description | Waiting for a newly initialized WAL file to reach durable storage <para> Multixact ID age component score. Scores greater than or equal to <xref linkend="guc-autovacuum-multixact-freeze-score-weight"/> indicate - the table will be vacuumed. + the table will be vacuumed for multixact ID wraparound prevention. </para></entry> </row> @@ -4640,6 +4634,37 @@ description | Waiting for a newly initialized WAL file to reach durable storage will be analyzed (unless autovacuum is disabled). </para></entry> </row> + + <row> + <entry role="catalog_table_entry"><para role="column_definition"> + <structfield>will_vacuum</structfield> <type>bool</type> + </para> + <para> + Whether the table will be vacuumed. Note that even if the component + scores indicate that the table needs to be vacuumed, this may be + <literal>false</literal> if autovacuum is disabled. + </para></entry> + </row> + + <row> + <entry role="catalog_table_entry"><para role="column_definition"> + <structfield>will_analyze</structfield> <type>bool</type> + </para> + <para> + Whether the table will be analyzed. Note that even if the component + scores indicate that the table needs to be analyzed, this may be + <literal>false</literal> if autovacuum is disabled. + </para></entry> + </row> + + <row> + <entry role="catalog_table_entry"><para role="column_definition"> + <structfield>for_wraparound</structfield> <type>bool</type> + </para> + <para> + Whether the table will be vacuumed for wraparound prevention. + </para></entry> + </row> </tbody> </tgroup> </table> diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index 5c2f2977965..83cc3edcbeb 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -805,7 +805,10 @@ CREATE VIEW pg_stat_autovacuum_scores AS s.mxid_score, s.vacuum_score, s.vacuum_insert_score, - s.analyze_score + s.analyze_score, + s.will_vacuum, + s.will_analyze, + s.for_wraparound FROM pg_stat_get_autovacuum_scores() s JOIN pg_class c on c.oid = s.oid LEFT JOIN pg_namespace n ON n.oid = c.relnamespace; diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index c6c601dd3ad..26faa9870ba 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -3659,8 +3659,8 @@ pg_stat_get_autovacuum_scores(PG_FUNCTION_ARGS) bool doanalyze; bool wraparound; AutoVacuumScores scores; - Datum vals[7]; - bool nulls[7] = {false}; + Datum vals[10]; + bool nulls[10] = {false}; /* skip ineligible entries */ if (form->relkind != RELKIND_RELATION && @@ -3685,6 +3685,9 @@ pg_stat_get_autovacuum_scores(PG_FUNCTION_ARGS) vals[4] = Float8GetDatum(scores.vac); vals[5] = Float8GetDatum(scores.vac_ins); vals[6] = Float8GetDatum(scores.anl); + vals[7] = BoolGetDatum(dovacuum); + vals[8] = BoolGetDatum(doanalyze); + vals[9] = BoolGetDatum(wraparound); tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, vals, nulls); } diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 0de3bb52eb2..d79b4465b10 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -5670,9 +5670,9 @@ { oid => '8409', descr => 'autovacuum scores', proname => 'pg_stat_get_autovacuum_scores', prorows => '100', proretset => 't', provolatile => 'v', proparallel => 'u', prorettype => 'record', proargtypes => '', - proallargtypes => '{oid,float8,float8,float8,float8,float8,float8}', - proargmodes => '{o,o,o,o,o,o,o}', - proargnames => '{oid,score,xid_score,mxid_score,vacuum_score,vacuum_insert_score,analyze_score}', + proallargtypes => '{oid,float8,float8,float8,float8,float8,float8,bool,bool,bool}', + proargmodes => '{o,o,o,o,o,o,o,o,o,o}', + proargnames => '{oid,score,xid_score,mxid_score,vacuum_score,vacuum_insert_score,analyze_score,will_vacuum,will_analyze,for_wraparound}', prosrc => 'pg_stat_get_autovacuum_scores' }, { oid => '1936', descr => 'statistics: currently active backend IDs', proname => 'pg_stat_get_backend_idset', prorows => '100', proretset => 't', diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index b167e8d3cab..d978aedbd07 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -1868,8 +1868,11 @@ pg_stat_autovacuum_scores| SELECT s.oid AS relid, s.mxid_score, s.vacuum_score, s.vacuum_insert_score, - s.analyze_score - FROM ((pg_stat_get_autovacuum_scores() s(oid, score, xid_score, mxid_score, vacuum_score, vacuum_insert_score, analyze_score) + s.analyze_score, + s.will_vacuum, + s.will_analyze, + s.for_wraparound + FROM ((pg_stat_get_autovacuum_scores() s(oid, score, xid_score, mxid_score, vacuum_score, vacuum_insert_score, analyze_score, will_vacuum, will_analyze, for_wraparound) JOIN pg_class c ON ((c.oid = s.oid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))); pg_stat_bgwriter| SELECT pg_stat_get_bgwriter_buf_written_clean() AS buffers_clean, -- 2.50.1 (Apple Git-155)
