]> granicus.if.org Git - postgresql/commitdiff
Count heap tuples in non-SnapshotAny path in IndexBuildHeapRangeScan().
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 8 May 2018 04:20:19 +0000 (00:20 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 8 May 2018 04:20:19 +0000 (00:20 -0400)
Brown-paper-bag bug in commit 7c91a0364: when we rearranged the placement
of "reltuples += 1" statements, we missed including one in this code path.

The net effect of that was that CREATE INDEX CONCURRENTLY would set the
table's pg_class.reltuples to zero, as would index builds done during
bootstrap mode.  (It seems like parallel index builds ought to fail
similarly, but they don't, perhaps because reltuples is computed in some
other way.  You certainly couldn't figure that out from the abysmally
underdocumented parallelism code in this area.)

I was led to this by wondering why initdb seemed to have slowed down as
a result of 7c91a0364, as is evident in the buildfarm's timing history.
The reason is that every system catalog with indexes had pg_class.reltuples
= 0 after bootstrap, causing the planner to make some terrible choices for
queries in the post-bootstrap steps.  On my workstation, this fix causes
the runtime of "initdb -N" to drop from ~2.0 sec to ~1.4 sec, which is
almost though not quite back to where it was in v10.  That's not much of
a deal for production use perhaps, but it makes a noticeable difference
for buildfarm and "make check-world" runs, which do a lot of initdbs.

src/backend/catalog/index.c

index 6c40b29b3ff7369f492ac28688e0b844baf73bcb..8b276bc430f16d691192b6f83abb80e7fc5b4723 100644 (file)
@@ -2850,6 +2850,7 @@ IndexBuildHeapRangeScan(Relation heapRelation,
                {
                        /* heap_getnext did the time qual check */
                        tupleIsAlive = true;
+                       reltuples += 1;
                }
 
                MemoryContextReset(econtext->ecxt_per_tuple_memory);