mirror of
https://github.com/postgres/postgres.git
synced 2026-05-16 03:19:53 -04:00
Add pg_stat_autovacuum_scores system view.
This view contains one row for each table in the current database, showing the current autovacuum scores for that specific table. It also shows whether autovacuum would vacuum or analyze the table. Bumps catversion. Author: Sami Imseih <samimseih@gmail.com> Reviewed-by: Satyanarayana Narlapuram <satyanarlapuram@gmail.com> Reviewed-by: Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com> Reviewed-by: Robert Treat <rob@xzilla.net> Discussion: https://postgr.es/m/CAA5RZ0s4xjMrB-VAnLccC7kY8d0-4806-Lsac-czJsdA1LXtAw%40mail.gmail.com
This commit is contained in:
parent
b3a37ffbc5
commit
87f61f0c82
7 changed files with 299 additions and 1 deletions
|
|
@ -1168,6 +1168,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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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,175 @@ 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. Autovacuum
|
||||
prioritizes tables deemed eligible for processing based on their
|
||||
<structfield>score</structfield>, with higher scores indicating higher
|
||||
priority. See <xref linkend="autovacuum-priority"/> for more information.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
While this view generates its results the same way that autovacuum workers
|
||||
do, it does so using the current source information, which might differ from
|
||||
the source information that an autovacuum worker sees when it gathers its
|
||||
list of tables to process. Therefore, this view is not a completely
|
||||
reliable indicator of which tables autovacuum will process and what order it
|
||||
will process them.
|
||||
</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 would use to sort the list of tables to process.
|
||||
</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 that
|
||||
autovacuum would vacuum the table for transaction ID wraparound
|
||||
prevention.
|
||||
</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
|
||||
that autovacuum would vacuum the table for multixact ID wraparound
|
||||
prevention.
|
||||
</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 that
|
||||
autovacuum would vacuum the table (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
|
||||
that autovacuum would vacuum the table (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 that
|
||||
autovacuum would analyze the table (unless autovacuum is disabled).
|
||||
</para></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry role="catalog_table_entry"><para role="column_definition">
|
||||
<structfield>do_vacuum</structfield> <type>bool</type>
|
||||
</para>
|
||||
<para>
|
||||
Whether autovacuum would vacuum the table. Note that even if the
|
||||
component scores indicate that autovacuum would vacuum the table, this
|
||||
may be <literal>false</literal> if autovacuum is disabled.
|
||||
</para></entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry role="catalog_table_entry"><para role="column_definition">
|
||||
<structfield>do_analyze</structfield> <type>bool</type>
|
||||
</para>
|
||||
<para>
|
||||
Whether autovacuum would analyze the table. Note that even if the
|
||||
component scores indicate that autovacuum would analyze the table, 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 autovacuum would vacuum the table for wraparound prevention.
|
||||
</para></entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="monitoring-pg-stat-all-indexes-view">
|
||||
<title><structname>pg_stat_all_indexes</structname></title>
|
||||
|
||||
|
|
|
|||
|
|
@ -795,6 +795,24 @@ 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,
|
||||
s.do_vacuum,
|
||||
s.do_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;
|
||||
|
||||
CREATE VIEW pg_statio_all_tables AS
|
||||
SELECT
|
||||
C.oid AS relid,
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
@ -112,6 +113,7 @@
|
|||
#include "utils/syscache.h"
|
||||
#include "utils/timeout.h"
|
||||
#include "utils/timestamp.h"
|
||||
#include "utils/tuplestore.h"
|
||||
#include "utils/wait_event.h"
|
||||
|
||||
|
||||
|
|
@ -3627,3 +3629,74 @@ 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[10];
|
||||
bool nulls[10] = {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);
|
||||
vals[7] = BoolGetDatum(dovacuum);
|
||||
vals[8] = BoolGetDatum(doanalyze);
|
||||
vals[9] = BoolGetDatum(wraparound);
|
||||
|
||||
tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, vals, nulls);
|
||||
}
|
||||
table_endscan(scan);
|
||||
table_close(rel, AccessShareLock);
|
||||
|
||||
return (Datum) 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,6 +57,6 @@
|
|||
*/
|
||||
|
||||
/* yyyymmddN */
|
||||
#define CATALOG_VERSION_NO 202604051
|
||||
#define CATALOG_VERSION_NO 202604061
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -5673,6 +5673,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 => 's', proparallel => 'r', prorettype => 'record', proargtypes => '',
|
||||
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,do_vacuum,do_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',
|
||||
provolatile => 's', proparallel => 'r', prorettype => 'int4',
|
||||
|
|
|
|||
|
|
@ -1860,6 +1860,21 @@ 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,
|
||||
s.do_vacuum,
|
||||
s.do_analyze,
|
||||
s.for_wraparound
|
||||
FROM ((pg_stat_get_autovacuum_scores() s(oid, score, xid_score, mxid_score, vacuum_score, vacuum_insert_score, analyze_score, do_vacuum, do_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,
|
||||
pg_stat_get_bgwriter_maxwritten_clean() AS maxwritten_clean,
|
||||
pg_stat_get_buf_alloc() AS buffers_alloc,
|
||||
|
|
|
|||
Loading…
Reference in a new issue