Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Update relation's stats in pg_class during vacuum full.
authorTeodor Sigaev <teodor@sigaev.ru>
Wed, 27 Dec 2017 15:25:37 +0000 (18:25 +0300)
committerTeodor Sigaev <teodor@sigaev.ru>
Wed, 27 Dec 2017 15:25:37 +0000 (18:25 +0300)
Hash index depends on estimation of numbers of tuples and pages of relations,
incorrect value could be a reason of significantly growing of index. Vacuum
full recreates heap and reindex all indexes before renewal stats. The patch
fixes that, so indexes will see correct values.

Backpatch to v10 only because earlier versions haven't usable hash index and
growing of hash index is a single user-visible symptom.

Author: Amit Kapila
Reviewed-by: Ashutosh Sharma, me
Discussion: https://www.postgresql.org/message-id/flat/20171115232922.5tomkxnw3iq6jsg7@inml.weebeastie.net

src/backend/commands/cluster.c

index 48f1e6e2addfc4d965b1b5e2eb5b1ecd828db454..1c5669afa8eaa1cb6e92eec91b4ac64925e3577c 100644 (file)
@@ -738,6 +738,9 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex, bool verbose,
    Relation    NewHeap,
                OldHeap,
                OldIndex;
+   Relation    relRelation;
+   HeapTuple   reltup;
+   Form_pg_class relform;
    TupleDesc   oldTupDesc;
    TupleDesc   newTupDesc;
    int         natts;
@@ -756,6 +759,7 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex, bool verbose,
    double      num_tuples = 0,
                tups_vacuumed = 0,
                tups_recently_dead = 0;
+   BlockNumber num_pages;
    int         elevel = verbose ? INFO : DEBUG2;
    PGRUsage    ru0;
 
@@ -1079,6 +1083,8 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex, bool verbose,
    /* Reset rd_toastoid just to be tidy --- it shouldn't be looked at again */
    NewHeap->rd_toastoid = InvalidOid;
 
+   num_pages = RelationGetNumberOfBlocks(NewHeap);
+
    /* Log what we did */
    ereport(elevel,
            (errmsg("\"%s\": found %.0f removable, %.0f nonremovable row versions in %u pages",
@@ -1098,6 +1104,30 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex, bool verbose,
        index_close(OldIndex, NoLock);
    heap_close(OldHeap, NoLock);
    heap_close(NewHeap, NoLock);
+
+   /* Update pg_class to reflect the correct values of pages and tuples. */
+   relRelation = heap_open(RelationRelationId, RowExclusiveLock);
+
+   reltup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(OIDNewHeap));
+   if (!HeapTupleIsValid(reltup))
+       elog(ERROR, "cache lookup failed for relation %u", OIDNewHeap);
+   relform = (Form_pg_class) GETSTRUCT(reltup);
+
+   relform->relpages = num_pages;
+   relform->reltuples = num_tuples;
+
+   /* Don't update the stats for pg_class.  See swap_relation_files. */
+   if (OIDOldHeap != RelationRelationId)
+       CatalogTupleUpdate(relRelation, &reltup->t_self, reltup);
+   else
+       CacheInvalidateRelcacheByTuple(reltup);
+
+   /* Clean up. */
+   heap_freetuple(reltup);
+   heap_close(relRelation, RowExclusiveLock);
+
+   /* Make the update visible */
+   CommandCounterIncrement();
 }
 
 /*