• Tom Lane's avatar
    When updating reltuples after ANALYZE, just extrapolate from our sample. · d04900de
    Tom Lane authored
    The existing logic for updating pg_class.reltuples trusted the sampling
    results only for the pages ANALYZE actually visited, preferring to
    believe the previous tuple density estimate for all the unvisited pages.
    While there's some rationale for doing that for VACUUM (first that
    VACUUM is likely to visit a very nonrandom subset of pages, and second
    that we know for sure that the unvisited pages did not change), there's
    no such rationale for ANALYZE: by assumption, it's looked at an unbiased
    random sample of the table's pages.  Furthermore, in a very large table
    ANALYZE will have examined only a tiny fraction of the table's pages,
    meaning it cannot slew the overall density estimate very far at all.
    In a table that is physically growing, this causes reltuples to increase
    nearly proportionally to the change in relpages, regardless of what is
    actually happening in the table.  This has been observed to cause reltuples
    to become so much larger than reality that it effectively shuts off
    autovacuum, whose threshold for doing anything is a fraction of reltuples.
    (Getting to the point where that would happen seems to require some
    additional, not well understood, conditions.  But it's undeniable that if
    reltuples is seriously off in a large table, ANALYZE alone will not fix it
    in any reasonable number of iterations, especially not if the table is
    continuing to grow.)
    
    Hence, restrict the use of vac_estimate_reltuples() to VACUUM alone,
    and in ANALYZE, just extrapolate from the sample pages on the assumption
    that they provide an accurate model of the whole table.  If, by very bad
    luck, they don't, at least another ANALYZE will fix it; in the old logic
    a single bad estimate could cause problems indefinitely.
    
    In HEAD, let's remove vac_estimate_reltuples' is_analyze argument
    altogether; it was never used for anything and now it's totally pointless.
    But keep it in the back branches, in case any third-party code is calling
    this function.
    
    Per bug #15005.  Back-patch to all supported branches.
    
    David Gould, reviewed by Alexander Kuzmenkov, cosmetic changes by me
    
    Discussion: https://postgr.es/m/20180117164916.3fdcf2e9@engels
    d04900de
pgstatapprox.c 8.01 KB