Don't reset changes_since_analyze after a selective-columns ANALYZE.

If we ANALYZE only selected columns of a table, we should not postpone
auto-analyze because of that; other columns may well still need stats
updates.  As committed, the counter is left alone if a column list is
given, whether or not it includes all analyzable columns of the table.
Per complaint from Tomasz Ostrowski.

It's been like this a long time, so back-patch to all supported branches.

Report: <ef99c1bd-ff60-5f32-2733-c7b504eb960c@ato.waw.pl>
This commit is contained in:
Tom Lane 2016-06-06 17:44:17 -04:00
parent a7aa61ffe7
commit 5acc58c5e5
3 changed files with 19 additions and 7 deletions

View File

@ -605,10 +605,13 @@ do_analyze_rel(Relation onerel, int options, VacuumParams *params,
/* /*
* Report ANALYZE to the stats collector, too. However, if doing * Report ANALYZE to the stats collector, too. However, if doing
* inherited stats we shouldn't report, because the stats collector only * inherited stats we shouldn't report, because the stats collector only
* tracks per-table stats. * tracks per-table stats. Reset the changes_since_analyze counter only
* if we analyzed all columns; otherwise, there is still work for
* auto-analyze to do.
*/ */
if (!inh) if (!inh)
pgstat_report_analyze(onerel, totalrows, totaldeadrows); pgstat_report_analyze(onerel, totalrows, totaldeadrows,
(va_cols == NIL));
/* If this isn't part of VACUUM ANALYZE, let index AMs do cleanup */ /* If this isn't part of VACUUM ANALYZE, let index AMs do cleanup */
if (!(options & VACOPT_VACUUM)) if (!(options & VACOPT_VACUUM))

View File

@ -1346,11 +1346,15 @@ pgstat_report_vacuum(Oid tableoid, bool shared,
* pgstat_report_analyze() - * pgstat_report_analyze() -
* *
* Tell the collector about the table we just analyzed. * Tell the collector about the table we just analyzed.
*
* Caller must provide new live- and dead-tuples estimates, as well as a
* flag indicating whether to reset the changes_since_analyze counter.
* -------- * --------
*/ */
void void
pgstat_report_analyze(Relation rel, pgstat_report_analyze(Relation rel,
PgStat_Counter livetuples, PgStat_Counter deadtuples) PgStat_Counter livetuples, PgStat_Counter deadtuples,
bool resetcounter)
{ {
PgStat_MsgAnalyze msg; PgStat_MsgAnalyze msg;
@ -1387,6 +1391,7 @@ pgstat_report_analyze(Relation rel,
msg.m_databaseid = rel->rd_rel->relisshared ? InvalidOid : MyDatabaseId; msg.m_databaseid = rel->rd_rel->relisshared ? InvalidOid : MyDatabaseId;
msg.m_tableoid = RelationGetRelid(rel); msg.m_tableoid = RelationGetRelid(rel);
msg.m_autovacuum = IsAutoVacuumWorkerProcess(); msg.m_autovacuum = IsAutoVacuumWorkerProcess();
msg.m_resetcounter = resetcounter;
msg.m_analyzetime = GetCurrentTimestamp(); msg.m_analyzetime = GetCurrentTimestamp();
msg.m_live_tuples = livetuples; msg.m_live_tuples = livetuples;
msg.m_dead_tuples = deadtuples; msg.m_dead_tuples = deadtuples;
@ -5110,10 +5115,12 @@ pgstat_recv_analyze(PgStat_MsgAnalyze *msg, int len)
tabentry->n_dead_tuples = msg->m_dead_tuples; tabentry->n_dead_tuples = msg->m_dead_tuples;
/* /*
* We reset changes_since_analyze to zero, forgetting any changes that * If commanded, reset changes_since_analyze to zero. This forgets any
* occurred while the ANALYZE was in progress. * changes that were committed while the ANALYZE was in progress, but we
* have no good way to estimate how many of those there were.
*/ */
tabentry->changes_since_analyze = 0; if (msg->m_resetcounter)
tabentry->changes_since_analyze = 0;
if (msg->m_autovacuum) if (msg->m_autovacuum)
{ {

View File

@ -382,6 +382,7 @@ typedef struct PgStat_MsgAnalyze
Oid m_databaseid; Oid m_databaseid;
Oid m_tableoid; Oid m_tableoid;
bool m_autovacuum; bool m_autovacuum;
bool m_resetcounter;
TimestampTz m_analyzetime; TimestampTz m_analyzetime;
PgStat_Counter m_live_tuples; PgStat_Counter m_live_tuples;
PgStat_Counter m_dead_tuples; PgStat_Counter m_dead_tuples;
@ -932,7 +933,8 @@ extern void pgstat_report_autovac(Oid dboid);
extern void pgstat_report_vacuum(Oid tableoid, bool shared, extern void pgstat_report_vacuum(Oid tableoid, bool shared,
PgStat_Counter livetuples, PgStat_Counter deadtuples); PgStat_Counter livetuples, PgStat_Counter deadtuples);
extern void pgstat_report_analyze(Relation rel, extern void pgstat_report_analyze(Relation rel,
PgStat_Counter livetuples, PgStat_Counter deadtuples); PgStat_Counter livetuples, PgStat_Counter deadtuples,
bool resetcounter);
extern void pgstat_report_recovery_conflict(int reason); extern void pgstat_report_recovery_conflict(int reason);
extern void pgstat_report_deadlock(void); extern void pgstat_report_deadlock(void);