I've come across a number of times where the statistics on materialized
views become stale producing bad plans. It turns out that autovacuum only
touches a materialized view when it is first created and ignores it on a
refresh. When you have a materialized view like yesterdays_sales the data
in the materialized view turns over every day.
Attached is a patch to trigger autovacuum based on a matview refresh along
with a system view pg_stat_all_matviews to show information more meaningful
for materialized views.
-- Jim
diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml
index fad5cb0..ec27e2c 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -436,6 +436,21 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser
</row>
<row>
+ <entry><structname>pg_stat_all_matviews</><indexterm><primary>pg_stat_all_matviews</primary></indexterm></entry>
+ <entry>
+ One row for each materialized view in the current database, showing statistics
+ about accesses to that specific materialized view.
+ See <xref linkend="pg-stat-all-matviews-view"> for details.
+ </entry>
+ </row>
+
+ <row>
+ <entry><structname>pg_stat_user_matviews</><indexterm><primary>pg_stat_user_matviews</primary></indexterm></entry>
+ <entry>Same as <structname>pg_stat_all_matviews</>, except that only
+ user materialized views are shown.</entry>
+ </row>
+
+ <row>
<entry><structname>pg_statio_all_tables</><indexterm><primary>pg_statio_all_tables</primary></indexterm></entry>
<entry>
One row for each table in the current database, showing statistics
@@ -2277,6 +2292,97 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i
</para>
</note>
+ <table id="pg-stat-all-matviews-view" xreflabel="pg_stat_all_matviews">
+ <title><structname>pg_stat_all_matviews</structname> View</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Column</entry>
+ <entry>Type</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry><structfield>relid</></entry>
+ <entry><type>oid</></entry>
+ <entry>OID of this materialize view</entry>
+ </row>
+ <row>
+ <entry><structfield>schemaname</></entry>
+ <entry><type>name</></entry>
+ <entry>Name of the schema that this materialized view is in</entry>
+ </row>
+ <row>
+ <entry><structfield>relname</></entry>
+ <entry><type>name</></entry>
+ <entry>Name of this materialized view</entry>
+ </row>
+ <row>
+ <entry><structfield>seq_scan</></entry>
+ <entry><type>bigint</></entry>
+ <entry>Number of sequential scans initiated on this materialized view</entry>
+ </row>
+ <row>
+ <entry><structfield>seq_tup_read</></entry>
+ <entry><type>bigint</></entry>
+ <entry>Number of live rows fetched by sequential scans</entry>
+ </row>
+ <row>
+ <entry><structfield>idx_scan</></entry>
+ <entry><type>bigint</></entry>
+ <entry>Number of index scans initiated on this materialized ciew</entry>
+ </row>
+ <row>
+ <entry><structfield>idx_tup_fetch</></entry>
+ <entry><type>bigint</></entry>
+ <entry>Number of live rows fetched by index scans</entry>
+ </row>
+ <row>
+ <entry><structfield>last_refresh</></entry>
+ <entry><type>timestamp with time zone</></entry>
+ <entry>Last time at which this materialized view was refreshed</entry>
+ </row>
+ <row>
+ <entry><structfield>refresh_count</></entry>
+ <entry><type>bigint</></entry>
+ <entry>Number of times this materialized view has been refreshed</entry>
+ </row>
+ <row>
+ <entry><structfield>last_analyze</></entry>
+ <entry><type>timestamp with time zone</></entry>
+ <entry>Last time at which this materialized view was manually analyzed</entry>
+ </row>
+ <row>
+ <entry><structfield>last_autoanalyze</></entry>
+ <entry><type>timestamp with time zone</></entry>
+ <entry>Last time at which this materialized ciew was analyzed by the
+ autovacuum daemon</entry>
+ </row>
+ <row>
+ <entry><structfield>analyze_count</></entry>
+ <entry><type>bigint</></entry>
+ <entry>Number of times this materialized view has been manually analyzed</entry>
+ </row>
+ <row>
+ <entry><structfield>autoanalyze_count</></entry>
+ <entry><type>bigint</></entry>
+ <entry>Number of times this materialized view has been analyzed by the
+ autovacuum daemon</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The <structname>pg_stat_all_matviews</structname> view will contain
+ one row for each materialized view in the current database, showing
+ statistics about accesses to that specific materialized view. The
+ <structname>pg_stat_user_matviews</structname> contain the same
+ information, but filtered to only show user materialized views.
+ </para>
+
<table id="pg-statio-all-tables-view" xreflabel="pg_statio_all_tables">
<title><structname>pg_statio_all_tables</structname> View</title>
<tgroup cols="3">
diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c
index 816483e..8d60d48 100644
--- a/src/backend/access/common/reloptions.c
+++ b/src/backend/access/common/reloptions.c
@@ -164,6 +164,15 @@ static relopt_int intRelOpts[] =
},
-1, 0, INT_MAX
},
+ {
+ {
+ "autovacuum_analyze_refresh_threshold",
+ "Minimum number of materialized view refreshes prior to analyze",
+ RELOPT_KIND_HEAP,
+ ShareUpdateExclusiveLock
+ },
+ -1, 0, INT_MAX
+ },
{
{
"autovacuum_vacuum_cost_delay",
@@ -1283,6 +1292,8 @@ default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
offsetof(StdRdOptions, autovacuum) +offsetof(AutoVacOpts, vacuum_threshold)},
{"autovacuum_analyze_threshold", RELOPT_TYPE_INT,
offsetof(StdRdOptions, autovacuum) +offsetof(AutoVacOpts, analyze_threshold)},
+ {"autovacuum_analyze_refresh_threshold", RELOPT_TYPE_INT,
+ offsetof(StdRdOptions, autovacuum) +offsetof(AutoVacOpts, analyze_ref_threshold)},
{"autovacuum_vacuum_cost_delay", RELOPT_TYPE_INT,
offsetof(StdRdOptions, autovacuum) +offsetof(AutoVacOpts, vacuum_cost_delay)},
{"autovacuum_vacuum_cost_limit", RELOPT_TYPE_INT,
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 38be9cf..07b9f1c 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -535,6 +535,28 @@ CREATE VIEW pg_stat_xact_all_tables AS
WHERE C.relkind IN ('r', 't', 'm')
GROUP BY C.oid, N.nspname, C.relname;
+CREATE VIEW pg_stat_all_matviews AS
+ SELECT
+ C.oid AS relid,
+ N.nspname AS schemaname,
+ C.relname AS relname,
+ pg_stat_get_numscans(C.oid) AS seq_scan,
+ pg_stat_get_tuples_returned(C.oid) AS seq_tup_read,
+ sum(pg_stat_get_numscans(I.indexrelid))::bigint AS idx_scan,
+ sum(pg_stat_get_tuples_fetched(I.indexrelid))::bigint +
+ pg_stat_get_tuples_fetched(C.oid) AS idx_tup_fetch,
+ pg_stat_get_last_refresh_time(C.oid) as last_refresh,
+ pg_stat_get_refresh_count(C.oid) AS refresh_count,
+ pg_stat_get_last_analyze_time(C.oid) as last_analyze,
+ pg_stat_get_last_autoanalyze_time(C.oid) as last_autoanalyze,
+ pg_stat_get_analyze_count(C.oid) AS analyze_count,
+ pg_stat_get_autoanalyze_count(C.oid) AS autoanalyze_count
+ FROM pg_class C LEFT JOIN
+ pg_index I ON C.oid = I.indrelid
+ LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
+ WHERE C.relkind = 'm'
+ GROUP BY C.oid, N.nspname, C.relname;
+
CREATE VIEW pg_stat_sys_tables AS
SELECT * FROM pg_stat_all_tables
WHERE schemaname IN ('pg_catalog', 'information_schema') OR
@@ -555,6 +577,11 @@ CREATE VIEW pg_stat_xact_user_tables AS
WHERE schemaname NOT IN ('pg_catalog', 'information_schema') AND
schemaname !~ '^pg_toast';
+CREATE VIEW pg_stat_user_matviews AS
+ SELECT * FROM pg_stat_all_matviews
+ WHERE schemaname NOT IN ('pg_catalog', 'information_schema') AND
+ schemaname !~ '^pg_toast';
+
CREATE VIEW pg_statio_all_tables AS
SELECT
C.oid AS relid,
diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c
index a18c917..b4ad098 100644
--- a/src/backend/commands/matview.c
+++ b/src/backend/commands/matview.c
@@ -320,6 +320,9 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString,
SetUserIdAndSecContext(relowner,
save_sec_context | SECURITY_RESTRICTED_OPERATION);
+ /* report the refresh to the stats collector */
+ pgstat_report_refresh(matviewOid);
+
/* Generate the data, if wanted. */
if (!stmt->skipData)
refresh_matview_datafill(dest, dataQuery, queryString);
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index 0c5ffa0..42f7a1d 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -115,6 +115,7 @@ int autovacuum_naptime;
int autovacuum_vac_thresh;
double autovacuum_vac_scale;
int autovacuum_anl_thresh;
+int autovacuum_anl_ref_thresh;
double autovacuum_anl_scale;
int autovacuum_freeze_max_age;
int autovacuum_multixact_freeze_max_age;
@@ -2757,7 +2758,8 @@ relation_needs_vacanalyze(Oid relid,
/* constants from reloptions or GUC variables */
int vac_base_thresh,
- anl_base_thresh;
+ anl_base_thresh,
+ anl_ref_thresh;
float4 vac_scale_factor,
anl_scale_factor;
@@ -2768,6 +2770,7 @@ relation_needs_vacanalyze(Oid relid,
/* number of vacuum (resp. analyze) tuples at this time */
float4 vactuples,
anltuples;
+ int anlrefresh;
/* freeze parameters */
int freeze_max_age;
@@ -2801,6 +2804,10 @@ relation_needs_vacanalyze(Oid relid,
? relopts->analyze_threshold
: autovacuum_anl_thresh;
+ anl_ref_thresh = (relopts && relopts->analyze_ref_threshold >= 0)
+ ? relopts->analyze_ref_threshold
+ : autovacuum_anl_ref_thresh;
+
freeze_max_age = (relopts && relopts->freeze_max_age >= 0)
? Min(relopts->freeze_max_age, autovacuum_freeze_max_age)
: autovacuum_freeze_max_age;
@@ -2848,6 +2855,7 @@ relation_needs_vacanalyze(Oid relid,
reltuples = classForm->reltuples;
vactuples = tabentry->n_dead_tuples;
anltuples = tabentry->changes_since_analyze;
+ anlrefresh = tabentry->refreshes_since_analyze;
vacthresh = (float4) vac_base_thresh + vac_scale_factor * reltuples;
anlthresh = (float4) anl_base_thresh + anl_scale_factor * reltuples;
@@ -2861,9 +2869,13 @@ relation_needs_vacanalyze(Oid relid,
NameStr(classForm->relname),
vactuples, vacthresh, anltuples, anlthresh);
- /* Determine if this table needs vacuum or analyze. */
+ /* Determine if this table or materialzed view needs vacuum or analyze. */
*dovacuum = force_vacuum || (vactuples > vacthresh);
*doanalyze = (anltuples > anlthresh);
+
+ /* Check if a materialized view was refreshed and needs to be analyzed */
+ if (!*doanalyze && classForm->relkind == RELKIND_MATVIEW)
+ *doanalyze = (anlrefresh >= anl_ref_thresh);
}
else
{
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index ada374c..2f86409 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -294,6 +294,7 @@ static void pgstat_recv_resetsinglecounter(PgStat_MsgResetsinglecounter *msg, in
static void pgstat_recv_autovac(PgStat_MsgAutovacStart *msg, int len);
static void pgstat_recv_vacuum(PgStat_MsgVacuum *msg, int len);
static void pgstat_recv_analyze(PgStat_MsgAnalyze *msg, int len);
+static void pgstat_recv_refresh(PgStat_MsgRefresh *msg, int len);
static void pgstat_recv_archiver(PgStat_MsgArchiver *msg, int len);
static void pgstat_recv_bgwriter(PgStat_MsgBgWriter *msg, int len);
static void pgstat_recv_funcstat(PgStat_MsgFuncstat *msg, int len);
@@ -1400,6 +1401,28 @@ pgstat_report_analyze(Relation rel,
pgstat_send(&msg, sizeof(msg));
}
+/* ---------
+ * pgstat_report_refresh() -
+ *
+ * Tell the collector about the materialed view we just refreshed.
+ * ---------
+ */
+void
+pgstat_report_refresh(Oid tableoid)
+{
+ PgStat_MsgRefresh msg;
+
+ if (pgStatSock == PGINVALID_SOCKET || !pgstat_track_counts)
+ return;
+
+ pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_REFRESH);
+ msg.m_databaseid = MyDatabaseId;
+ msg.m_tableoid = tableoid;
+ msg.m_refreshtime = GetCurrentTimestamp();
+ pgstat_send(&msg, sizeof(msg));
+}
+
+
/* --------
* pgstat_report_recovery_conflict() -
*
@@ -3878,6 +3901,10 @@ PgstatCollectorMain(int argc, char *argv[])
pgstat_recv_analyze((PgStat_MsgAnalyze *) &msg, len);
break;
+ case PGSTAT_MTYPE_REFRESH:
+ pgstat_recv_refresh((PgStat_MsgRefresh *) &msg, len);
+ break;
+
case PGSTAT_MTYPE_ARCHIVER:
pgstat_recv_archiver((PgStat_MsgArchiver *) &msg, len);
break;
@@ -4101,6 +4128,9 @@ pgstat_get_tab_entry(PgStat_StatDBEntry *dbentry, Oid tableoid, bool create)
result->analyze_count = 0;
result->autovac_analyze_timestamp = 0;
result->autovac_analyze_count = 0;
+ result->refresh_timestamp = 0;
+ result->refresh_count = 0;
+ result->refreshes_since_analyze = 0;
}
return result;
@@ -5211,6 +5241,9 @@ pgstat_recv_tabstat(PgStat_MsgTabstat *msg, int len)
tabentry->analyze_count = 0;
tabentry->autovac_analyze_timestamp = 0;
tabentry->autovac_analyze_count = 0;
+ tabentry->refresh_timestamp = 0;
+ tabentry->refresh_count = 0;
+ tabentry->refreshes_since_analyze = 0;
}
else
{
@@ -5507,8 +5540,11 @@ pgstat_recv_analyze(PgStat_MsgAnalyze *msg, int len)
* have no good way to estimate how many of those there were.
*/
if (msg->m_resetcounter)
+ {
tabentry->changes_since_analyze = 0;
-
+ tabentry->refreshes_since_analyze = 0;
+ }
+
if (msg->m_autovacuum)
{
tabentry->autovac_analyze_timestamp = msg->m_analyzetime;
@@ -5521,6 +5557,29 @@ pgstat_recv_analyze(PgStat_MsgAnalyze *msg, int len)
}
}
+/* ----------
+ * pgstat_recv_refresh() -
+ *
+ * Process a REFRESH message.
+ * ----------
+ */
+static void
+pgstat_recv_refresh(PgStat_MsgRefresh *msg, int len)
+{
+ PgStat_StatDBEntry *dbentry;
+ PgStat_StatTabEntry *tabentry;
+
+ /*
+ * Store the data in the mview's hashtable entry.
+ */
+ dbentry = pgstat_get_db_entry(msg->m_databaseid, true);
+
+ tabentry = pgstat_get_tab_entry(dbentry, msg->m_tableoid, true);
+
+ tabentry->refresh_timestamp = msg->m_refreshtime;
+ tabentry->refresh_count++;
+ tabentry->refreshes_since_analyze++;
+}
/* ----------
* pgstat_recv_archiver() -
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index a987d0d..13f77ad 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -296,6 +296,24 @@ pg_stat_get_last_autoanalyze_time(PG_FUNCTION_ARGS)
}
Datum
+pg_stat_get_last_refresh_time(PG_FUNCTION_ARGS)
+{
+ Oid relid = PG_GETARG_OID(0);
+ TimestampTz result;
+ PgStat_StatTabEntry *tabentry;
+
+ if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
+ result = 0;
+ else
+ result = tabentry->refresh_timestamp;
+
+ if (result == 0)
+ PG_RETURN_NULL();
+ else
+ PG_RETURN_TIMESTAMPTZ(result);
+}
+
+Datum
pg_stat_get_vacuum_count(PG_FUNCTION_ARGS)
{
Oid relid = PG_GETARG_OID(0);
@@ -356,6 +374,21 @@ pg_stat_get_autoanalyze_count(PG_FUNCTION_ARGS)
}
Datum
+pg_stat_get_refresh_count(PG_FUNCTION_ARGS)
+{
+ Oid relid = PG_GETARG_OID(0);
+ int64 result;
+ PgStat_StatTabEntry *tabentry;
+
+ if ((tabentry = pgstat_fetch_stat_tabentry(relid)) == NULL)
+ result = 0;
+ else
+ result = (int64) (tabentry->refresh_count);
+
+ PG_RETURN_INT64(result);
+}
+
+Datum
pg_stat_get_function_calls(PG_FUNCTION_ARGS)
{
Oid funcid = PG_GETARG_OID(0);
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 5d8fb2e..4ec36c0 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -2632,6 +2632,15 @@ static struct config_int ConfigureNamesInt[] =
50, 0, INT_MAX,
NULL, NULL, NULL
},
+ {
+ {"autovacuum_analyze_refresh_threshold", PGC_SIGHUP, AUTOVACUUM,
+ gettext_noop("Minimum number of materialized view refreshes prior to analyze."),
+ NULL
+ },
+ &autovacuum_anl_ref_thresh,
+ 1, 0, INT_MAX,
+ NULL, NULL, NULL
+ },
{
/* see varsup.c for why this is PGC_POSTMASTER not PGC_SIGHUP */
{"autovacuum_freeze_max_age", PGC_POSTMASTER, AUTOVACUUM,
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index bb7053a..1ed669a 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -2766,6 +2766,10 @@ DATA(insert OID = 3056 ( pg_stat_get_analyze_count PGNSP PGUID 12 1 0 0 0 f f f
DESCR("statistics: number of manual analyzes for a table");
DATA(insert OID = 3057 ( pg_stat_get_autoanalyze_count PGNSP PGUID 12 1 0 0 0 f f f f t f s r 1 0 20 "26" _null_ _null_ _null_ _null_ _null_ pg_stat_get_autoanalyze_count _null_ _null_ _null_ ));
DESCR("statistics: number of auto analyzes for a table");
+DATA(insert OID = 3353 ( pg_stat_get_last_refresh_time PGNSP PGUID 12 1 0 0 0 f f f f t f s r 1 0 1184 "26" _null_ _null_ _null_ _null_ _null_ pg_stat_get_last_refresh_time _null_ _null_ _null_ ));
+DESCR("statistics: last refresh time for a materialized view");
+DATA(insert OID = 3354 ( pg_stat_get_refresh_count PGNSP PGUID 12 1 0 0 0 f f f f t f s r 1 0 20 "26" _null_ _null_ _null_ _null_ _null_ pg_stat_get_refresh_count _null_ _null_ _null_ ));
+DESCR("statistics: number of manual vacuums for a table");
DATA(insert OID = 1936 ( pg_stat_get_backend_idset PGNSP PGUID 12 1 100 0 0 f f f f t t s r 0 0 23 "" _null_ _null_ _null_ _null_ _null_ pg_stat_get_backend_idset _null_ _null_ _null_ ));
DESCR("statistics: currently active backend IDs");
DATA(insert OID = 2022 ( pg_stat_get_activity PGNSP PGUID 12 1 100 0 0 f f f f f t s r 1 0 2249 "23" "{23,26,23,26,25,25,25,25,25,1184,1184,1184,1184,869,25,23,28,28,16,25,25,23,16,25}" "{i,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}" "{pid,datid,pid,usesysid,application_name,state,query,wait_event_type,wait_event,xact_start,query_start,backend_start,state_change,client_addr,client_hostname,client_port,backend_xid,backend_xmin,ssl,sslversion,sslcipher,sslbits,sslcompression,sslclientdn}" _null_ _null_ pg_stat_get_activity _null_ _null_ _null_ ));
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 8b710ec..4b87e38 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -58,6 +58,7 @@ typedef enum StatMsgType
PGSTAT_MTYPE_AUTOVAC_START,
PGSTAT_MTYPE_VACUUM,
PGSTAT_MTYPE_ANALYZE,
+ PGSTAT_MTYPE_REFRESH,
PGSTAT_MTYPE_ARCHIVER,
PGSTAT_MTYPE_BGWRITER,
PGSTAT_MTYPE_FUNCSTAT,
@@ -391,6 +392,19 @@ typedef struct PgStat_MsgAnalyze
/* ----------
+ * PgStat_MsgRefresh Sent by the backend after REFRESH
+ * ----------
+ */
+typedef struct PgStat_MsgRefresh
+{
+ PgStat_MsgHdr m_hdr;
+ Oid m_databaseid;
+ Oid m_tableoid;
+ TimestampTz m_refreshtime;
+} PgStat_MsgRefresh;
+
+
+/* ----------
* PgStat_MsgArchiver Sent by the archiver to update statistics.
* ----------
*/
@@ -549,6 +563,7 @@ typedef union PgStat_Msg
PgStat_MsgAutovacStart msg_autovacuum;
PgStat_MsgVacuum msg_vacuum;
PgStat_MsgAnalyze msg_analyze;
+ PgStat_MsgRefresh msg_refresh;
PgStat_MsgArchiver msg_archiver;
PgStat_MsgBgWriter msg_bgwriter;
PgStat_MsgFuncstat msg_funcstat;
@@ -641,6 +656,9 @@ typedef struct PgStat_StatTabEntry
PgStat_Counter analyze_count;
TimestampTz autovac_analyze_timestamp; /* autovacuum initiated */
PgStat_Counter autovac_analyze_count;
+ TimestampTz refresh_timestamp;
+ PgStat_Counter refresh_count;
+ PgStat_Counter refreshes_since_analyze;
} PgStat_StatTabEntry;
diff --git a/src/include/postmaster/autovacuum.h b/src/include/postmaster/autovacuum.h
index 99d7f09..e910c76 100644
--- a/src/include/postmaster/autovacuum.h
+++ b/src/include/postmaster/autovacuum.h
@@ -23,6 +23,7 @@ extern int autovacuum_naptime;
extern int autovacuum_vac_thresh;
extern double autovacuum_vac_scale;
extern int autovacuum_anl_thresh;
+extern int autovacuum_anl_ref_thresh;
extern double autovacuum_anl_scale;
extern int autovacuum_freeze_max_age;
extern int autovacuum_multixact_freeze_max_age;
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index a617a7c..0555aae 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -256,6 +256,7 @@ typedef struct AutoVacOpts
bool enabled;
int vacuum_threshold;
int analyze_threshold;
+ int analyze_ref_threshold;
int vacuum_cost_delay;
int vacuum_cost_limit;
int freeze_min_age;
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index 9f876ae..d4517ab 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -1549,6 +1549,7 @@ PgStat_MsgFuncstat
PgStat_MsgHdr
PgStat_MsgInquiry
PgStat_MsgRecoveryConflict
+PgStat_MsgRefresh
PgStat_MsgResetcounter
PgStat_MsgResetsharedcounter
PgStat_MsgResetsinglecounter
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers