*** a/src/backend/commands/vacuumlazy.c --- b/src/backend/commands/vacuumlazy.c *************** *** 106,111 **** typedef struct LVRelStats --- 106,112 ---- double scanned_tuples; /* counts only tuples on scanned pages */ double old_rel_tuples; /* previous value of pg_class.reltuples */ double new_rel_tuples; /* new estimated total # of tuples */ + double new_dead_tuples; /* new estimated dead tuples */ BlockNumber pages_removed; double tuples_deleted; BlockNumber nonempty_pages; /* actually, last nonempty page + 1 */ *************** *** 288,294 **** lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt, /* report results to the stats collector, too */ pgstat_report_vacuum(RelationGetRelid(onerel), onerel->rd_rel->relisshared, ! new_rel_tuples); /* and log the action if appropriate */ if (IsAutoVacuumWorkerProcess() && Log_autovacuum_min_duration >= 0) --- 289,296 ---- /* report results to the stats collector, too */ pgstat_report_vacuum(RelationGetRelid(onerel), onerel->rd_rel->relisshared, ! new_rel_tuples, ! vacrelstats->new_dead_tuples); /* and log the action if appropriate */ if (IsAutoVacuumWorkerProcess() && Log_autovacuum_min_duration >= 0) *************** *** 422,427 **** lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats, --- 424,430 ---- vacrelstats->rel_pages = nblocks; vacrelstats->scanned_pages = 0; vacrelstats->nonempty_pages = 0; + vacrelstats->new_dead_tuples = 0; vacrelstats->latestRemovedXid = InvalidTransactionId; lazy_space_alloc(vacrelstats, nblocks); *************** *** 993,998 **** lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats, --- 996,1004 ---- vacrelstats->scanned_tuples = num_tuples; vacrelstats->tuples_deleted = tups_vacuumed; + /* Dead tuples which are yet to remove from relation */ + vacrelstats->new_dead_tuples = nkeep; + /* now we can compute the new value for pg_class.reltuples */ vacrelstats->new_rel_tuples = vac_estimate_reltuples(onerel, false, nblocks, *** a/src/backend/postmaster/pgstat.c --- b/src/backend/postmaster/pgstat.c *************** *** 1317,1323 **** pgstat_report_autovac(Oid dboid) * --------- */ void ! pgstat_report_vacuum(Oid tableoid, bool shared, PgStat_Counter tuples) { PgStat_MsgVacuum msg; --- 1317,1324 ---- * --------- */ void ! pgstat_report_vacuum(Oid tableoid, bool shared, PgStat_Counter tuples, ! PgStat_Counter dead_tuples) { PgStat_MsgVacuum msg; *************** *** 1330,1335 **** pgstat_report_vacuum(Oid tableoid, bool shared, PgStat_Counter tuples) --- 1331,1337 ---- msg.m_autovacuum = IsAutoVacuumWorkerProcess(); msg.m_vacuumtime = GetCurrentTimestamp(); msg.m_tuples = tuples; + msg.m_dead_tuples = dead_tuples; pgstat_send(&msg, sizeof(msg)); } *************** *** 4800,4807 **** pgstat_recv_vacuum(PgStat_MsgVacuum *msg, int len) tabentry = pgstat_get_tab_entry(dbentry, msg->m_tableoid, true); tabentry->n_live_tuples = msg->m_tuples; ! /* Resetting dead_tuples to 0 is an approximation ... */ ! tabentry->n_dead_tuples = 0; if (msg->m_autovacuum) { --- 4802,4808 ---- tabentry = pgstat_get_tab_entry(dbentry, msg->m_tableoid, true); tabentry->n_live_tuples = msg->m_tuples; ! tabentry->n_dead_tuples = msg->m_dead_tuples; if (msg->m_autovacuum) { *** a/src/include/pgstat.h --- b/src/include/pgstat.h *************** *** 332,337 **** typedef struct PgStat_MsgVacuum --- 332,338 ---- bool m_autovacuum; TimestampTz m_vacuumtime; PgStat_Counter m_tuples; + PgStat_Counter m_dead_tuples; } PgStat_MsgVacuum; *************** *** 773,779 **** extern void pgstat_reset_single_counter(Oid objectid, PgStat_Single_Reset_Type t extern void pgstat_report_autovac(Oid dboid); extern void pgstat_report_vacuum(Oid tableoid, bool shared, ! PgStat_Counter tuples); extern void pgstat_report_analyze(Relation rel, PgStat_Counter livetuples, PgStat_Counter deadtuples); --- 774,780 ---- extern void pgstat_report_autovac(Oid dboid); extern void pgstat_report_vacuum(Oid tableoid, bool shared, ! PgStat_Counter tuples, PgStat_Counter dead_tuples); extern void pgstat_report_analyze(Relation rel, PgStat_Counter livetuples, PgStat_Counter deadtuples);