Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Don't reset changes_since_analyze after a selective-columns ANALYZE.
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 6 Jun 2016 21:44:17 +0000 (17:44 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 6 Jun 2016 21:44:17 +0000 (17:44 -0400)
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>

src/backend/commands/analyze.c
src/backend/postmaster/pgstat.c
src/include/pgstat.h

index 2282f8b052a17bca5450333a8f4c0208e53c2916..39131957685e95b366bd218502bc2874e2a50b55 100644 (file)
@@ -617,10 +617,13 @@ do_analyze_rel(Relation onerel, VacuumStmt *vacstmt,
    /*
     * Report ANALYZE to the stats collector, too.  However, if doing
     * 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)
-       pgstat_report_analyze(onerel, totalrows, totaldeadrows);
+       pgstat_report_analyze(onerel, totalrows, totaldeadrows,
+                             (vacstmt->va_cols == NIL));
 
    /* If this isn't part of VACUUM ANALYZE, let index AMs do cleanup */
    if (!(vacstmt->options & VACOPT_VACUUM))
index 64511eb00ad0006039b4088975af0e2d63ef5bfa..b2f226cfd9e577938e205676c4911e7cdbbb6860 100644 (file)
@@ -1346,11 +1346,15 @@ pgstat_report_vacuum(Oid tableoid, bool shared,
  * pgstat_report_analyze() -
  *
  * 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
 pgstat_report_analyze(Relation rel,
-                     PgStat_Counter livetuples, PgStat_Counter deadtuples)
+                     PgStat_Counter livetuples, PgStat_Counter deadtuples,
+                     bool resetcounter)
 {
    PgStat_MsgAnalyze msg;
 
@@ -1387,6 +1391,7 @@ pgstat_report_analyze(Relation rel,
    msg.m_databaseid = rel->rd_rel->relisshared ? InvalidOid : MyDatabaseId;
    msg.m_tableoid = RelationGetRelid(rel);
    msg.m_autovacuum = IsAutoVacuumWorkerProcess();
+   msg.m_resetcounter = resetcounter;
    msg.m_analyzetime = GetCurrentTimestamp();
    msg.m_live_tuples = livetuples;
    msg.m_dead_tuples = deadtuples;
@@ -4964,10 +4969,12 @@ pgstat_recv_analyze(PgStat_MsgAnalyze *msg, int len)
    tabentry->n_dead_tuples = msg->m_dead_tuples;
 
    /*
-    * We reset changes_since_analyze to zero, forgetting any changes that
-    * occurred while the ANALYZE was in progress.
+    * If commanded, reset changes_since_analyze to zero.  This forgets any
+    * 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)
    {
index 79bf196845f2f2f9b01b8eaa33102abfe67bfea4..205cba3762da41aee9526deae1993e880b6e1f88 100644 (file)
@@ -376,6 +376,7 @@ typedef struct PgStat_MsgAnalyze
    Oid         m_databaseid;
    Oid         m_tableoid;
    bool        m_autovacuum;
+   bool        m_resetcounter;
    TimestampTz m_analyzetime;
    PgStat_Counter m_live_tuples;
    PgStat_Counter m_dead_tuples;
@@ -862,7 +863,8 @@ extern void pgstat_report_autovac(Oid dboid);
 extern void pgstat_report_vacuum(Oid tableoid, bool shared,
                     PgStat_Counter livetuples, PgStat_Counter deadtuples);
 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_deadlock(void);