diff options
Diffstat (limited to 'contrib/pgstattuple/pgstatapprox.c')
-rw-r--r-- | contrib/pgstattuple/pgstatapprox.c | 36 |
1 files changed, 21 insertions, 15 deletions
diff --git a/contrib/pgstattuple/pgstatapprox.c b/contrib/pgstattuple/pgstatapprox.c index 474c3bd517..ef33cacec6 100644 --- a/contrib/pgstattuple/pgstatapprox.c +++ b/contrib/pgstattuple/pgstatapprox.c @@ -68,7 +68,6 @@ statapprox_heap(Relation rel, output_type *stat) Buffer vmbuffer = InvalidBuffer; BufferAccessStrategy bstrategy; TransactionId OldestXmin; - uint64 misc_count = 0; OldestXmin = GetOldestXmin(rel, PROCARRAY_FLAGS_VACUUM); bstrategy = GetAccessStrategy(BAS_BULKREAD); @@ -114,14 +113,15 @@ statapprox_heap(Relation rel, output_type *stat) else stat->free_space += BLCKSZ - SizeOfPageHeaderData; + /* We may count the page as scanned even if it's new/empty */ + scanned++; + if (PageIsNew(page) || PageIsEmpty(page)) { UnlockReleaseBuffer(buf); continue; } - scanned++; - /* * Look at each tuple on the page and decide whether it's live or * dead, then count it and its size. Unlike lazy_scan_heap, we can @@ -153,25 +153,23 @@ statapprox_heap(Relation rel, output_type *stat) tuple.t_tableOid = RelationGetRelid(rel); /* - * We count live and dead tuples, but we also need to add up - * others in order to feed vac_estimate_reltuples. + * We follow VACUUM's lead in counting INSERT_IN_PROGRESS tuples + * as "dead" while DELETE_IN_PROGRESS tuples are "live". We don't + * bother distinguishing tuples inserted/deleted by our own + * transaction. */ switch (HeapTupleSatisfiesVacuum(&tuple, OldestXmin, buf)) { - case HEAPTUPLE_RECENTLY_DEAD: - misc_count++; - /* Fall through */ - case HEAPTUPLE_DEAD: - stat->dead_tuple_len += tuple.t_len; - stat->dead_tuple_count++; - break; case HEAPTUPLE_LIVE: + case HEAPTUPLE_DELETE_IN_PROGRESS: stat->tuple_len += tuple.t_len; stat->tuple_count++; break; + case HEAPTUPLE_DEAD: + case HEAPTUPLE_RECENTLY_DEAD: case HEAPTUPLE_INSERT_IN_PROGRESS: - case HEAPTUPLE_DELETE_IN_PROGRESS: - misc_count++; + stat->dead_tuple_len += tuple.t_len; + stat->dead_tuple_count++; break; default: elog(ERROR, "unexpected HeapTupleSatisfiesVacuum result"); @@ -184,8 +182,16 @@ statapprox_heap(Relation rel, output_type *stat) stat->table_len = (uint64) nblocks * BLCKSZ; + /* + * We don't know how many tuples are in the pages we didn't scan, so + * extrapolate the live-tuple count to the whole table in the same way + * that VACUUM does. (Like VACUUM, we're not taking a random sample, so + * just extrapolating linearly seems unsafe.) There should be no dead + * tuples in all-visible pages, so no correction is needed for that, and + * we already accounted for the space in those pages, too. + */ stat->tuple_count = vac_estimate_reltuples(rel, nblocks, scanned, - stat->tuple_count + misc_count); + stat->tuple_count); /* * Calculate percentages if the relation has one or more pages. |